Pyjamas Tutorial Part 3

This tutorial series is based on the Getting Started tutorial for GWT.

Part 2: Building the User Interface

At this point, you’ve created all the elements of the interface. Like many user interface frameworks, Pyjamas is event-based. This means that the code executes in response to some event occurring. Most often, that event is triggered by the user, who uses the mouse or keyboard to interact with the application interface.

In this section, you’ll wire up your widgets to listen for and handle mouse and keyboard events.

  1. Review the functional requirements.
  2. Listen for events.
  3. Respond to events.
  4. Test event handling.

1. Reviewing the requirements for event handling

Let’s review the StockWatcher requirements to see what events occur.

Task UI Event (Trigger mechanism) Response
User enters a stock code. Clicks the Add button
or presses return in the input box.
  • Verify input.
  • Check to see if stock already exists.
  • Add a new row.
  • Create a delete button.
User deletes stock from the table. Presses the Remove button.
  • Remove row from table.

provides a number of different event handler interfaces. To handle click events on the Add and Remove buttons, you’ll use the build in ClickHandler class of the Button. To handle keyboard events in the input box, you’ll use the KeyPressHandler class.

2. Listening for events

Event Handler Classes

Events in Pyjamas use the event handler model similar to other user interface frameworks. To subscribe to an event, you pass a particular event handler interface to the appropriate widget. An event handler class defines one or more methods that the widget then calls to announce (publish) an event.

Handling Mouse Events

One way StockWatcher users can enter a stock code is by using their mouse to click on the Add button.

You’ll handle the Add button’s click event by just assigning a function to the button, which fires when the user clicks on the widget.

When the user clicks on the Add button, StockWatcher should respond by adding the stock to the stock table. So, to handle the click event, call the addStock method. You haven’t written the addStock method yet; you’ll create a stub and then code it in the next section.

  1. Add a function handler to the Add button so it can receive click events.
    In stockwatcher.py, in the onModuleLoad method, cut and paste the code commented “Listen for mouse events on the Add button.” that is highlighted below.
  2. In stockwatcher.py, create the stub for the addStock method.
    Just copy and paste from the code highlighted below.
    from pyjamas.ui.RootPanel import RootPanel
    from pyjamas.ui.VerticalPanel import VerticalPanel
    from pyjamas.ui.FlexTable import FlexTable
    from pyjamas.ui.HorizontalPanel import HorizontalPanel
    from pyjamas.ui.TextBox import TextBox
    from pyjamas.ui.Button import Button
    from pyjamas.ui.Label import Label
    from pyjamas import Window
    
    class Stockwatcher:
    
        # Entry point method.
        def __init__(self):
    #        declare interface widgets
            self.mainPanel = VerticalPanel()
            self.stocksFlexTable = FlexTable()
            self.addPanel = HorizontalPanel()
            self.newSymbolTextBox = TextBox()
            self.addStockButton = Button("Add", getattr(self, "addStock"))
            self.lastUpdatedLabel = Label()
    
        def addStock(self):
    # Add stock to FlexTable. Executed when the user clicks the
    # addStockButton or presses enter in the newSymbolTextBox.
    
        def onModuleLoad(self):
            # Create table for stock data.
            self.stocksFlexTable.setText(0, 0, "Symbol")
            self.stocksFlexTable.setText(0, 1, "Price")
            self.stocksFlexTable.setText(0, 2, "Change")
            self.stocksFlexTable.setText(0, 3, "Remove")
    
            # Assemble Add Stock panel.
            self.addPanel.add(self.newSymbolTextBox)
            self.addPanel.add(self.addStockButton)
    
            #Assemble Main panel.
            self.mainPanel.add(self.stocksFlexTable)
    
            self.mainPanel.add(self.addPanel)
            self.mainPanel.add(self.lastUpdatedLabel)
    
            #Associate the Main panel with the HTML host page.
            RootPanel().add(self.mainPanel)
    
            # Move cursor focus to the input box.
            self.newSymbolTextBox.setFocus(True)
    
    if __name__ == '__main__':
        app = Stockwatcher()
        app.onModuleLoad()

Handling Keyboard Events

In addition to using the Add button, StockWatcher users can enter a stock code without taking their hands from the keyboard by pressing return in the input box.

To subscribe to keyboard events, you can call the addKeyPressHandler(KeyPressHandler) method and pass it a KeyPressHandler.

    Hook up the keypress event handler for the input box, newSymbolTextBox.
    In the Stockwatcher class, cut and paste the code that is highlighted below.
    
        def onKeyDown(self, sender, keycode, modifiers):
            pass
    
        def onKeyUp(self, sender, keycode, modifiers):
            pass
    
        def onKeyPress(self, sender, keycode, modifiers):
            if sender == self.newSymbolTextBox and \
               keycode == KeyboardListener.KEY_ENTER:
                self.addStock()

The event handlers are now wired up and ready for an event. Your next step is to fill out the stub addStock method.

3. Responding to user events

At this point, StockWatcher should be listening for user input, a mouse or keyboard event that signals the user has entered a stock code. So next you’ll test whether or not the event handler interfaces are working by coding the response that StockWatcher should make when it detects an event: add the stock. StockWatcher responds on the client side without sending any requests back to server or reloading the HTML page.

Adding the stock to the stock table

In StockWatcher, users will enter the stock codes of the stocks they want to monitor one at a time into the input box. When they press Enter or click on the Add button, you want StockWatcher to respond as follows:

  1. Validate the input.
  2. Check for duplicates.
  3. Add the stock.
  4. Add a button for removing the stock from the list.

In this section, you’ll code the first response, validating the input, just to see if the event handler interfaces are working. In the next section, Coding Functionality on the Client, you’ll code the rest of the steps to add the stock.

You’ll implement this functionality in the addStock method.

Validating input in a text box

You want verify that the stock code entered is valid. Rather than verify whether the user input matches an actual stock code, for the purposes of this tutorial, you’ll just perform a simple character validity check.

First, extract the stock code. To retrieve the text in the TextBox widget use its getText method.

Next, ensure that the charcters are not within the set of illegal characters you specify. After you’ve converted the user input to a standard form, use a regular expression to check its format. Remember to use regular expressions.

If the input is valid, clear the text box so the user can add another stock code.

Finally, if the input is not valid, warn users via a dialog box.

  1. Validate user input of the stock code.
    In StockWatcher.java. replace the stub addStock method with following code.
    def addStock(self):
    
    # Add stock to FlexTable. Executed when the user clicks the
    # addStockButton or presses enter in the newSymbolTextBox.
            symbol = self.newSymbolTextBox.getText()
            self.newSymbolTextBox.setText("")
            self.newSymbolTextBox.setFocus(True)
    
            symbol = symbol.upper().strip()
    
            if not testRegEx(symbol):
                Window.alert("Please choose a different name than %s.\n\
                                    The Name should only contain number \
                                     and characters" % (symbol))
                return
    
        # TODO Don't add the stock if it's already in the table.
    
        # TODO Add the stock to the table.
    
        # TODO Add a button to remove this stock from the table.
    
        # TODO Get the stock price.
    
      }
  2. Test the regular expression in Javascript.
    I didn’t figured out how to test regular expression with pyjamas yet. So you have to define this function in your stockwatcher.py
    def testRegEx(string):
        """Test a regular expression"""
        JS("""
            var re = new RegExp("^[0-9a-zA-Z\s]{1,30}$");
    
            return re.test(string);
        """)
    

4. Testing event handling

At this point you should be able to enter text in the input box. If you use an illegal character, a dialog box should pop up and display a warning. Try it and see.

  1. Test event handling in hosted mode.
  2. Test that both event handler interfaces work.
    Enter stock codes in the input box. Enter using both methods, by pressing return and by using the mouse to click on the Add button.
    At this point, the stock is not added to the table. However, the input box should clear so that you can add another stock.
  3. Test the validity checking and error message.
    Make some typos that include illegal characters.

Validation Error Message

What’s Next

At this point you’ve implemented event handler interfaces for mouse and keyboard events that signal the user has entered a stock. Stockwatcher responds by validating the input.

From now on, you should be able to go on your own.

You could improve the client that it adds the stock to the table and provide a button to remove it. See the original Google tutorial for inspiration.

Portions of this page are modifications based on work created and shared by Google and used according to terms described in the Creative Commons 2.5 Attribution License.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s