Category Archives: html5

JQuery Mobile Checkboxes

31 Oct 2012

JQuery Mobile has some nice form element replacements that are more mobile device/touch-friendly than the way browsers currently present form elements. One of them is the visual replacement for a checkbox. To be clear the ugly checkbox is still there, its now layered underneath the JQM checkbox art.

The end results looks like this:

Click here to see a working example.

The docs IMO don’t quite tell you one critical thing – that certain tag attributes need to be identical in order for the framework to enhance the checkbox. If one of these is out of place you won’t get what you’re looking for.

Here’s how I implemented a checkbox today after trial and error:

...
  <style type="text/css">
    .checkboxWidth{
      width:53px;
    }
  </style>
...
  <fieldset data-role="controlgroup" class="checkboxWidth">
    <input type="checkbox" name="checkbox_value_0" id="checkbox_value_0" data-iconpos="notext" />
    <label for="checkbox_value_0" data="test"></label>
  </fieldset>
...

According to the docs the only thing to pay attention to is to ensure that the LABEL tag’s for attribute value is the same as the INPUT tag’s name value so that they are semantically linked together and displayed appropriately by the framework. There is one critical piece of information and that’s the INPUT tag’s id – it too must be the same value as the previous two attribute values. Omit that last bit and you don’t get any visual enhancement of the CHECKBOX element.

As far as getting the label removed all that is needed (as can be seen in the code sample above) is to add data-iconpos=”notext” to the input tag.

Lastly, I wanted to set the width so I added a class to the FIELDSET element and that was it, my check box was created and ready to go.

A handy tip is the use of the jQuery trigger method when inserting checkboxes into your document after it has loaded. Doing so ensures that you get the visual enhancement.

For example:

...
var newcbox = '<input type="checkbox" name="checkbox_value_0" id="checkbox_value_0" data-iconpos="notext" />';
    newcbox = '<label for="checkbox_value_0" data="test"></label>';

// add html to DOM and "trigger" jQuery visual enhancement
$(newcbox).appendTo('#contentWrapper').trigger('create');
...

Scrolling in LungoJS HTML5 Framework

12 Jul 2012

I’ve been looking at other frameworks lately, among them LungoJS. After fiddling with the framework I had difficulties creating scrolling views. The docs say that getting a scrolling area is as simple as adding a “scrollable” class to a div – not quite, there are some other requirements.

To get scrolling articles you must have the following structure – notice the DIV that wraps the content:

...
<article id="something" class="scrollable">
   <div> <!-- This DIV is important!! -->
      Your content in here
   </div>
</article>
...

If you attempt to create a scrollable div inside an article tag you **must** also set a height for that div, like so:

...
<article id="something">
   <div id="myDiv" class="scrollable" style="height:300px;">
      <div> <!-- This DIV is important!! -->
         Your content in here
      </div>
   </div>
</article>
...

Notice the ID in the scrollable divs – ID is **required**, you will see as much in the console if you forget this.

Note the DIV that is the immediate child of the scrollable div – that is also required. No need to style it or add an ID. Your content must be wrapped by a DIV – P’s, Lists and header elements also work. Spans do not.

If the scrolling area is not an article tag then you **must** include the height for the scrolling div, which is illustrated in the second example above.

I noticed a lot of confusion in the forums and was confused myself – IMO the docs should be amended with the above.

XTemplates and Sheets in Sencha Touch

24 Feb 2012

I was recently working on a project where there was specific help text that proved to be quite long in many cases. The original plan was to use Ext.Msg but that quickly became impractical due to the sheer amount of text. Next thing to use was Ext.Sheet which has the flexibility and options that I needed.

The Sheet ended up configured to have a toolbar and footer, docked to the top and bottom respectively. I further configured it to float in the center of the screen with about a 40 pixel margin around the sides. The lone item in the Sheet was a panel configured to use an XTemplate so that I could update it as needed with whatever help text came across the help web service.

The problem I encountered was that I could only populate the content panel within the Sheet once. It turns out that the activate listener for the content panel only ever fires one time – the very first time that the Sheet is displayed which is the first time the panel is activated.

After some thought this behavior makes sense. The panel is rendered the first time and the activate event fires. Thereafter, it doesn’t need to fire because it is always the lone active item of the sheet – it has already been activated/rendered. If I were to add another item to the sheet and switch between the two I would then get the activate event firing for both panels every time they are switched. As it is, the panel is activated the very first time out of necessity, activate naturally fires, and that is pretty much the end of it.

Back to the task at hand, I don’t have anything bound to stores, no proxies… I didn’t want to mess with that, I just wanted to push an object into the panel and I could only do it once with the panel’s activate event. Every other call to show the Sheet would not update the content with new text – only the very first item was ever displayed and all further use of the Sheet would only show the content that it was initially updated with.

See the following code which fits this scenario:

...
var helpSheet_tpl = new Ext.XTemplate(
    '',
        '
{data}
', '
', { compiled:true } ); var helpContent = new Ext.Panel({ id:'helpContent', layout:'card', scroll:'vertical', tpl:helpSheet_tpl, listeners:{ activate:function(e,o){ // this event will only ever fire once!!! helpContent.update(DATA); } } }); var helpSheet = new Ext.Sheet({ id:'helpSheet', cardSwitchAnimation:{type:'pop',duration:1000}, height: window.innerHeight - 40, width: window.innerWidth - 40, centered:true, floating:'true', layout: { type: 'card', align: 'stretch' }, items:[ helpContent ], dockedItems:[ { xtype:'toolbar', layout:'card', dock:'top', id:'help_header', title:'Help', }, { xtype:'button',text:'OK', layout:'card', dock:'bottom', listeners:{ tap:function(o,e){ helpSheet.hide(); } } } ] }); ...

The learning here is that the activate event for the above content panel will only fire once because it is the lone item – there is no item-switching happening and so therefore no opportunities for activate to fire again. Also, Ext.Sheet doesn’t have any events so you can’t put an activate event listener on it. At least, when I attempted this nothing happened at all. The Sencha docs imply that it is inherited but if you check the option to hide inherited you will see that there is nothing left event-wise for Ext.Sheet.

If you want to push an object into a panel in the above scenario by using the panel update() method you will have to do so outside of the panel, and not rely on the panel’s activate event. In my case I placed it within the JSONP callback. First I use the show() method to show the sheet and then I follow that up with the update() method on the panel.

XHR Post in Sencha Touch 1 & PhoneGap

13 Feb 2012

Sencha Touch has built in support for JSONP via “GET”, but if you have a lot of data to send you may quickly run into the GET character limit which varies across browsers. For a lot of data, “POST” is the preferred method and may be even preferred over GET for security reasons. The rub is that form POSTs will reload a page meaning that your app will reload and you’ll lose whatever state you had. That means we’ll have to do the POST via AJAX.

The astute among you might first ask about the cross domain policy and how it would prevent such a thing from happening (which JSONP by definition allows but is not useful here because its essentially a GET). As PhoneGap loads your Sencha Touch project via the file:// protocol cross domain XHR (XMLHttpRequest) is thus possible. Files loaded in this manner a free of the same domain policy.

With that aside it appears that Sencha Touch 1 just doesn’t have AJAX form posts as part of its framework but we can use Ext.Ajax.request() which allows us to set the desired form method and gives us success and error callbacks and even a timeout – which Ext.util.JSONP.request() lacks (bonus!).

The only additional setup is to add android.permission.INTERNET to the android manifest and to add the domain that you’re posting to to the whitelist in iOS. There has been some discussion about whitelisting in PhoneGap, it might be worthwhile to see how its evolved.

Here is a code snippet showing how the Ext.Ajax.request() method can be utilized within Sencha Touch:

...
Ext.Ajax.request({
	url: 'http://www.somewhere.com',
	method:'POST',
	params: 'configuration object goes here',
	scope:this,
	timeout:15000,
	disableCaching:true,
	failure: function(responseObj, opts){
		// handle your error response object here
	},
	success: function(responseObj, opts){
		// handle your success response object here
	}
});
...

The configuration object is simply something along these lines: {name:value,name:value,name:value,……}

Logo

All content © 2012-2017.