iScroll Input Button Broken

In our Mobile Web Applications we use iScroll to provide scrolling behavior.  The way it works is that iScroll takes all of the touch(mouse) events and converts them in to scrolling actions.

Unfortunately there is a problem with this when including some other controls that are also expecting to process the touch events.  In my case this is the input type=”button” which does not process the onClick event.  Other html fields including input, select, and textarea also exhibit this problem.  For instance:

<input type="button" onclick="return ShowItemInfo(2,0);" value="Details">

After searching, I found a couple of solutions that appear to relate to different versions of iScroll (we are using v4.2.4) which modify onBeforeScrollStart including this one under Issue 17 on the iScroll site:

// ORIGINAL
//            onBeforeScrollStart: function(e) { e.preventDefault(); },
// FIX:     Don't prevent the events for select input, and textarea.  Allows these inputs
//          to be used on iPad. 
            onBeforeScrollStart: function(e) {
                var target = e.target;
                while (target.nodeType != 1) target = target.parentNode;
                if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA')
                    e.preventDefault();
            },

You can also configure onBeforeScrollStart without modifying by configuring the iScroll options.  I chose not to do this because we use iScroll in many parts of the application and it seemed safer to comment iScroll and fix it in one place instead of many.

References:

http://stackoverflow.com/a/10279215/86923

ASP.Net MVC Modular Component Architecture

I have started adding a little bit more structure to our ASP.Net MVC project to start separating out the various components.  We needed to do this to create a framework that allowed multiple people to work on the application and modularize the code to make it more maintainable.

The basic architecture is to separate the various components in the web application in to the HTML and JavaScript components to reduce the coupling between them.   The HTML is moved in to Partial Views, similar to controls under Web Forms, and the JavaScript is separated in to a namespace hierarchy with separate modules for each of the components.

Partial Views

Separate the various components of the website in to partial views to allow them to be designed independently, shared between views, and to simplify the layout of the page.  This is very similar to how controls work in WebForms.

To do this, create a virtual page:

  1. Select the view directory to place the partial view, “Common” for those shared between different controllers, or in the View folder related to the controller, and select “Add->View”.
  2. Give the view a name, select “Create a partial view (.ascx)”, and “Add” the partial view.
  3. Copy the HTML layout in to the partial view.
    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
    <div id="TimedPopup" class="popup hide">
      <div class="popupHeader">
        <div class="popupTitle">Message</div>
      </div>
      <div class="TimedMessageStyle">
        <div id="TimedMessageText"></div>
      </div>
    </div>
  4. Insert the Partial View in to the Views where it is needed.
       <% Html.RenderPartial("TimedPopup"); %>

Create the Namespace

Namespaces can be used to separate the code in to different separate blocks to avoid naming conflicts.

The namespaces that I we are using for our project is:

  • S1S: Root namespace for all code
  • UI: User interface code
  • <component>: The individual component code
  1. Define the namespace
    For this component the namespace will be “S1S.UI.TimedPopup”
  2. Add the component to the directory tree
    The scripts directory is segmented in to a hierarchy that maps to the namespace.  Add the component under the appropriate directory.  In this case add “TimedPopup.js” to “~/Scripts/S1S/UI”.
  3. Add the namespace setup to the javascript file
    Create the appropriate variables, being careful not to destroy previous objects.

    if (typeof S1S == "undefined" || !S1S) {
    S1S = {};
    }
    if (typeof S1S.UI == "undefined" || !S1S.UI) {
    S1S.UI = {};
    }

 Create the Component Module

  1. Now create a module for the actual logic for the component.  Use a basic module based on the following format:
    S1S.UI.TimedPopup = (function() {
     
      // Private Stuff Here
     
      return {
        // Public Stuff Here 
        Display: function(message) {
        }
      }
    } ());
  2. Implement the component functionality
    Finally implement the component functionality encapsulating the functionality in the module.  For instance you could have a private event handler:

    S1S.UI.Error = (function() {
      /* Close the Popup */
      var onOK = function() {
        $('#ErrorMessage').hide();
        $('#blanket').hide();
      };
     
      return {
        /* Display the Popup */
        Display: function(errorText) {
          // stuff
          $('#OK').one("click", onOK);
          }
        }
    } ());
  3. Use the Component
    To use the component, first add the JavaScript file to the view:

    <script src="<%= Url.Content("~/Scripts/S1S/UI/TimedPopup.js") %>" type="text/javascript"></script>

    and call the method as required:

    S1S.UI.TimedPopup.Display("Item successfully added!");

HTML5 Signature Pad

 Signature Pad

Signature Pad is a jQuery plugin for assisting in the creation of an HTML5 canvas based signature pad. Records the drawn signature in JSON for later regeneration.  Here’s a demo.  And a nice video walk-through, Capture a Signature with jQuery and HTML 5.

This all looked great, and seems to be very nice, but it relies on FlashCanvas, which is an HTML5 Canvas for Internet Explorer via Flash.  This in turn relies on Flash which of course does not run on iPads, so its a non-starter.  Perhaps there’s a way to just use it directly with Canvas, but I didn’t look that closely.

Andrew Trice: Mobile Signature Capture

Next I found Andrew Trice’s Mobile Signature Capture Project (the JavaScript version) which is just a basic HTML5 Canvas signature capturing module.  It just captures the mouse or touch events, draws it on the canvas, and then can be saved as a .png file.  Here’s the demo.

It doesn’t save the strokes, like the one we developed for Windows CE, but its good enough for now.  I stripped out the Modernizr check to determine if it is a touch device and just used ‘ontouchstart’ in window to save some overhead, and I was in business.

This is also nicely written up in Capturing User Signatures in Mobile Applications.