Google APIs

Posted on

I have been thinking what I should write about for a while. Believe it or not, even though I have two weeks off from work during this holiday season, I still want to do what I do at work – building applications. This blog post is about Google APIs, specifically the Books API with which I built a simple book search application. While there are a lot of APIs available out there, Google APIs is pretty cool to try out.

Currently, there are 55 available APIs on Google APIs Console including Analytics API, Drive API, and YouTube Analytics API. Most APIs have request limits for free usage but some of them are available only with pricing plan such as Google Cloud SQL and Google Maps Geolocation API. The usage of API access is tracked by the API key generated on the website and you can view the quotas and report as well.

Google Books API allows you to perform CRUD operations on Google Books database with the proper authorization. The search scope can be the whole database or specific users’ both custom and pre-defined bookshelves like books they marked as favorites or read. Operations to retrieve user private data require OAuth token which can be easily generated on the Google API access page. The book concepts are easy to understand except that a book is given a term “volume” in the API.

For the coding part, you will need to request a script from Google API website.

//load script to access Google API
<script src="https://apis.google.com/js/client.js?onload=onLoadCallback"> </script>

Once the script is loaded, you can configure the client object for the query request that you are making.

function onLoadCallback(){
   var _this = this;
   //in this example, the param for API is "books" and the param for API version is 'v1' 
   this.client.load('books', 'v1', function (data) {
      //specify your API key       
      _this.client.setApiKey("{Your API key}");
   });
}

Now you can send any search requests with different parameters. The parameter “fields” defines the data fields to be returned. It’s important because without it, a large object with the complete information of books will be returned. You will never need so much information for your application and it would decrease the performance significantly.

var params = {
          //fields to return. return full information by default.
          fields:"items(volumeInfo/title, volumeInfo/authors,volumeInfo/publishedDate, 
                  volumeInfo/description, volumeInfo/imageLinks/thumbnail)",
          //maximum number of results to return. 10 by default
          maxResults:15,
          //sorting method. "relevance" by default
          orderBy:"newest"
    },
    restRequest = this.client.request({
          //specify the query request. 
          //the path below will return maximum number of 15 books 
          //with information matching "javascript" ordered by the most recent published date
          path:"/books/v1/volumes?q=javascript" + "&fields=" + params.fields 
               + "&maxResults=" + params.maxResults + "&orderBy=" + params.orderBy
    });

//sent the request
restRequest.execute(function (resp) {
   //use the return data 
});

With the proper data, you can build so many amazing applications. Google Books API is one of the easy-to-use APIs that I have used but there are a lot more features that I want to add to my Book Search with Google Books API application. If I ever run out of ideas for blogging, that’s what I am going to do :)


Developing Accessible Web Applications

Posted on

Accessible web applications provide means for people with disabilities to view, understand, and perform all the major tasks with the application. In short, applications that are equally usable for everyone. It is one of the important factors to a successful application especially for enterprise software.

WAI, stands for Web Accessibility Initiative, is a group of individuals and organizations dedicate to improve the web accessibility. ARIA stands for Accessible Rich Internet Applications. WAI-ARIA refers to the Accessible Rich Internet Applications specification and its latest version is WAI-ARIA 1.0 published in 2011.

HTML is not made for achieving accessibility with its limited variation of tags and HTML5 addresses this issue with the semantic tags. I have a blog post about HTML5 semantic structure. Here are a few other things you should make sure when developing an accessible application.

Keyboard Navigation
Users should be able to navigate through the web application and perform available tasks with keyboard. Tabbing is the common way to get to the element. Make sure the order of tabbing is correct visually and logically but not all the elements should be included in the tabbing sequence. Imagine that you need to tab through all the cells in a table before getting to the next page action element. The elements with action should have the tabindex as 0 or positive values while the others should be set to -1. Besides tabbing, arrows keys with combination of control or shift keys are also used in keyboard navigation but since it’s not standard, they should be documented so the user will know about them. Users should be able to tell the focused element with border.

Use of Color
Using high contrast colors is not just for the need of people with color-deficient vision, it makes it easier and more comfortable to read the content for everyone. Also, applications should not rely solely on color to convey important meaning. For example, an warning message should not be just displayed in red but also needs the term “warning”.

CSS Sprites
CSS sprites are background images so they won’t be shown on high contrast mode. If you haven’t checked out HCM, you can switch to it with shortcut shift + left Alt + PrtScr on Windows. Labels should be provided for the missing sprite images and they should perform the some action as the image.

Role and States
A Screen reader used to just read out all content on the page but it is now enhanced with the ability to response to the semantic web. Adding roles and states to the document so the screen reader can focus on only the important elements so it’s easier to understood by the listeners. For example, a node with role as presentation, an image node or table node, means it is just for page layout and does not have actions specified. A check box’s state can be set as “aria-checked” and it will be picked up by the screen reader.

More detailed advice with examples can be found on WAI-ARIA 1.0 Authoring Practices. One of the reasons that enterprise software favors Dojo Web Toolkit is that all the widgets in the library have been tested for Dojo accessibility requirements and it’s well documented in each widget. Dijit can detect the high contrast mode and apply the style with class “dijit_a11y” so you should utilize that class to add additional styling for your custom widgets in HCM.


Survey Form with Validation

Posted on

Form is one of the key elements of a web application. It enables the communication and interaction between the users and a website. However, it is also a major channel of attacking a web site as I mentioned in my earlier blog post Web Application Security. Although it is not enough to secure a website by validating and sanitizing user input in the front-end, validation for a form can detect unintentional human mistakes and reduce invalid calls to the server. In this blog post, I will explain a few form validation methods using dojo form widgets.

The most common web forms are for managing a user account, leaving a message or conducting a survey. In this post, we will use a survey form for example. Let’s take a look at the form below and spend a few minutes to think about how you can validate the user input in different specific fields.

a blank form

Since a valid name only include letters, spaces, and sometimes dash, the validation can be done by a simple regexp expression and specify it with the regExp property of the ValidationTextBox. ValidationTextBox checks user input as they type and show error message if needed.

// code for name input field
<label for="name">Name*: </label>
  <input id="name" type="text" name="name" 
         data-dojo-type="dijit.form.ValidationTextBox"
         data-dojo-props="regExp:'^[- A-Za-z]+$',
         required:true, trim:'true', maxlength:64"/>

Age input field is a drop down menu which is good for security as well as usability. It provides options for user to choose from and the options can be only those interested ones. Since the value for each option is set, nothing much needs to be done in the front-end. The value of form does not contain most of the advanced form widgets and this rating widgets is one of them, thus you will need to get the values for those fields individually and mix in with the rest of the form data when submitting the form.

Besides using regexp to validate the input, you can take advantage of the predefined validate functions in dojox/validate.

// code for email input field
<label for="email">Email*: </label>
<input id="email" type="text" name="email" data-dojo-attach-point="email" 
    data-dojo-type="dijit.form.ValidationTextBox"
    data-dojo-props="required:true, invalidMessage:'Invalid Email address', 
    trim:'true', maxLength:32"/>

The rating field is one of dojox form widgets where you can specify number of stars and default value. Same with other textbox input, I used a customized regexp to validate the reference # field. SimpleTextArea widget lets you specify the rows and cols for the text area while TextArea widget will display a text box and change the size as the user types in more data.

// set validator for reference # field
_setValidator: function _setValidator(){
    this.refNum.validator = function(value){
        return value== "" || /^[s-zS-Z][a-hA-H][0-9]{6}$/.test(value);
    };
}

// strip off invalid characters in textarea
_cleanString: function _cleanString(text){
    return text.match(/[^<>\\]?/g).join("");
}

Last but not least, connecting events with the submit button.

on(this.submitBtn, "click", lang.hitch(this, function(){
    var rating = this.rating.get("value"),
	    commentText = this._cleanString(this.comment.value);

    if(this.form.validate() && rating !== 0){
        response = "Form data in json format:<br/>";
        response += json.stringify(lang.mixin(this.form.get("value"), 
            {comment:commentText, rating:rating}));
    }
    else{
        response = "Form can not be submitted.<br/>";
        response += "Please fill in all required field and verify the data 
            you have entered.";
    }
    this.formDataDiv.innerHTML = response;
}));

Check out the Demo.