Working with PHP in GWT hosted mode

February 19th, 2008 - Written by in Using GWT

Normally, when developing your GWT applications in hosted mode, the internal tomcat server will be used to serve up your application. However, if want to talk to a server-side php script running on your own local web server, you will soon run into issues with the , since hosted mode runs on one port and the php script is running on another. In this tutorial, I will show you how I got around by running my GWT application and the php script on the same local web server. To demonstrate this, I will use the GWT FileUpload widget with a php backend.

Getting started

This tutorial assumes you already have a local web server running that can handle php. I am personally using Apache via MAMP on OS X. XAMPP is also another easy to setup alternative for Windows.

To start, I created a project called FileUploader and imported it into my IDE (Eclipse). The code for the FileUploader module is directly taken from the example code in the FileUpload widget javadoc.

The only modification I made was to the setAction method of the FormPanel object.

()

final FormPanel form = new FormPanel();
form.setAction(GWT.getModuleBaseURL() + "upload.php");

Now when the user hits submit on the form, it will call the php script called upload.php to handle the file upload.

Using -noserver

To tell hosted mode not to use the internal tomcat server, we will pass the -noserver argument to the GWTShell. But first we have to perform the following steps:

First, notice that the url of my application is: http://localhost/com.gwtsite.FileUploader/Fileuploader.html

So I created a folder called com.gwtsite.FileUploader in my web server’s web documents folder. Next, I compiled my application and copied the following files to this new folder:

  • FileUploader.html
  • gwt.js
  • hosted.html
  • history.html
  • com.gwtsite.FileUploader.nocache.js

Then for the program arguments, i set the -noserver parameter and since my web server is running on port 80 I also set the -port parameter to 80.

fileuploader parameters

Finishing up

The upload.php script for handling the upload was taken from the online php manual. I placed it in the same com.gwtsite.FileUploader folder on my web server. All it does is move the uploaded file from the temp location to the specified directory. Notice that uploadFormElement matches the name set on the GWT FileUpload widget.

()


$uploaddir = './';
$uploadfile = $uploaddir . basename($_FILES['uploadFormElement']['name']);
echo '
';
if (move_uploaded_file($_FILES['uploadFormElement']['tmp_name'], $uploadfile)) {
    echo "File is valid, and was successfully uploaded.\n";
} else {
    echo "Possible file upload attack!\n";
}
...
?>

Once this is all wired up, I can now start up hosted mode from within my IDE and successfully upload files from within my GWT application.

References

7 Comments Stumble it!

Weekly GWT Links for 2/16/08

February 16th, 2008 - Written by in News

Here were some of the more interesting GWT related items I read about during this past week.

goChongo
  • goChongo – This is a really neat, interactive site built using GWT. You can create contests as a Producer and/or participate in contests as a Performer. You can even earn money depending on how popular your submissions are.
  • – Evan Tice shares his experiences on the Google Web Toolkit blog about developing his GWT application, MapEcos.
  • – There’s an informative discussion on the GWT forums about using LGPL libraries with your GWT applications.
  • GWT: improving performance – Interesting article about speeding up the layout of GWT components.
  • Hibernate, Swing, Google Web Toolkit – Part Three – A three part series on integrating GWT with Spring and Hibernate. [Part 1][Part 2]

Don’t forget to keep up with the latest GWT news by .

No Comments Stumble it!

Dragging and dropping with gwt-dnd

February 14th, 2008 - Written by in Using GWT

Today, we are going to take a look at adding drag-and-drop to our GWT applications. I’ve seen quite a few solutions for adding drag-and-drop, including a few tutorials that show how roll your own solution. But why reinvent the wheel when there is a perfectly good drag and drop library like ? This library by Fred Sauer provides a whole host of cool features. I took some time to play with it this past week and I will show you how to get started using the library by creating a simple shopping cart example.

To install, download the latest gwt-dnd jar file, add it to your build path and add the following line to your GWT application module file.

<inherits name='com.allen_sauer.gwt.dnd.gwt-dnd'/>

In this demo, we’re going to allow users to drop books into a shopping cart. You can take a sneak peak of what I’m going to build here. The first domain object I will create is the Book class.

()

public class Book extends Composite implements SourcesMouseEvents {
  private String title;
  private String imgUrl;
  private BigDecimal price;
  private Image bookImage;
  private VerticalPanel mainPanel;
 
  public Book(String title, BigDecimal price, String imgUrl)  {
    this.title = title;
    this.price = price;
    this.imgUrl = imgUrl;
    this.mainPanel = new VerticalPanel();
    initWidget(mainPanel);
 
    bookImage = new Image(imgUrl);
    mainPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
    mainPanel.add(bookImage);
    mainPanel.add(new Label(title));
    mainPanel.add(new Label("$"+price));
    mainPanel.addStyleName("book");
 
    public void addMouseListener(MouseListener listener) {
      bookImage.addMouseListener(listener);
   }
   ...
  }

Book is a GWT composite widget that will display the book’s title, image, and price. Notice that it implements the SourcesMouseEvents interface. This is required to make the book draggable. In my implementation, I attach a MouseListener to the image field because the GWT Image widget already implements this interface and it will allow users to use the image as a drag handle to move the book around.

Dragging is handled by implementing the DragController interface. In this demo I am extending PickupDragController, which allows me to move the books around a specified boundary panel. By default, the dragged widget will disappear when dropped on the drop target. I don’t want this behavior so I’ll use a drag proxy instead. This means I can drag a copy of the book’s image and leave the original book widget alone. To achieve this, I set setBehaviorDragProxy() to true and override PickupDragController’s newDragProxy() method.

()

PickupDragController dragController = new PickupDragController(containingPanel, false) {
  protected Widget newDragProxy(DragContext context) {
    AbsolutePanel container = new AbsolutePanel();
    DOM.setStyleAttribute(container.getElement(), "overflow", "visible");
    for (Iterator iterator = context.selectedWidgets.iterator(); iterator.hasNext();) {
      Widget widget = (Widget) iterator.next();
      Book book = (Book)widget;
      container.add(new Image(book.getImageUrl()));
    }
    return container;
  }
};

Then I make Book widgets draggable by calling makeDraggable on the drag controller. Here, we pass to the method the book object (the draggable widget) and its image (the drag handle).

()

FlowPanel flowPanel = new FlowPanel();
flowPanel.addStyleName("flowPanel");
for (int i = 0; i < books.length; i++) {
  Book book = books[i];
  dragController.makeDraggable(book, book.getImage());
  flowPanel.add(book);
}

For the drop part of the demo, I created a object which serves as the drop target. Dropping is handled by a DropController object. The library comes with several implementations, and I chose to extend the SimpleDropController class.

()

public class CartDropController extends SimpleDropController {
  private ShoppingCart cart;
 
  public CartDropController(Widget dropTarget) {
    super(dropTarget);
    cart = (ShoppingCart)dropTarget;
  }
  public void onDrop(DragContext context) {
    super.onDrop(context);
    Book book = (Book)context.draggable;
    cart.add(book);
  }
  public void onEnter(DragContext context) {
    super.onEnter(context);
    cart.addStyleName("enterCart");
  }
  public void onLeave(DragContext context) {
    super.onLeave(context);
    cart.removeStyleName("enterCart");
  }

This controller accepts a GWT widget (the drop target) in its constructor and I had to implement the behavior for the following events: onDrop, onEnter, onLeave, and onPreviewDrop. The implementations of onEnter, and onLeave are simple. Here, I just add and remove a css class which can be used to give a visual indicator when the the book gets dragged over the cart. The onDrop method is used to add the dragged book object to the shopping cart and updating its display. I don’t use onPreviewDrop here, but it can be used to cancel a drop if some requirement isn’t met by throwing a VetoDragException.

Finally, to tie it all together, we need to register the drag controller with the drop controller like so:

()

ShoppingCart cart = new ShoppingCart();
CartDropController dropController = new CartDropController(cart);
dragController.registerDropController(dropController);

This is the demo in action. Hopefully this will get you started with using the gwt-dnd library. The project page has several demos to show what the library is capable of. I’ve only just touched the surface of what can be done, and there’s a lot of functionality out of the box that you can play with. So take a look around!

14 Comments Stumble it!

« Previous Entries Next Entries »