jQuery Mobile Collapsible Content Control with LightSwitch

Download a sample project via GitHub

LightSwitch makes it easy to include custom controls in your HTML screen designs using the render method.  In this method, the developer has complete control, but has to manually compose the necessary html.

This isn’t a problem for simple value controls – for instance a color picker or date picker.  But it can be a bit cumbersome and tedious for group or collection controls.  As a concrete example, let’s consider the jQuery Mobile collapsible content or accordion control.

Let’s create a screen and add some properties as children of a Rows Layout control.  Now, if we were to change that Rows Layout control to a Custom Control, we’d be responsible for rendering not only the custom control, but all the child controls as well.  It would be better if we could get LightSwitch to take care of the child controls while we simply modify the Rows Layout control to do what we want.

RowsLayout

However with normal (non-custom) controls in LightSwitch, we only have access to the postRender method, not the render method.  The render method fires before jQuery mobile has expanded the html based on data attributes.  The postRender method fires after.

So if you want to change the Rows Layout from a simple <div> to a Collapsible Content Control, you can’t use the postRender method – it fires too late!  Right?

Well… not quite.  You can make dynamic changes to a page’s html, including adding new elements or changing data attributes of existing elements, and then tell jQuery Mobile to work its magic on these new elements.  The key is trigger(‘create’).

This is a powerful technique.  LightSwitch takes care of rendering all the child controls using the built-in control types… no need for custom controls.  And we’ve essentially repurposed the Rows Layout control to act as our jQM Collapsible Content control, with just a few lines of code.

Here’s what our postRender method looks like, along with a helper method (which you’d normally place in a reusable library, but for simplicity in this example, I’ll leave in the screen’s .js file):

<br />function collapsibleContent(element, contentItem, options) {<br /><%%KEEPWHITESPACE%%>    // provide some defaults for the optional "options" parameter<br /><%%KEEPWHITESPACE%%>    var defaults = { theme: 'a', collapsed: false };<br /><%%KEEPWHITESPACE%%>    options = $.extend({}, defaults, options);<br /><br /><%%KEEPWHITESPACE%%>    // create a header based on the displayName of the bound content<br /><%%KEEPWHITESPACE%%>    var h1 = $('&lt;h1&gt;').text(contentItem.displayName);<br /><%%KEEPWHITESPACE%%>    $(element).prepend(h1);<br /><br /><%%KEEPWHITESPACE%%>    // build the &lt;div&gt; for the jQM collapsible content control<br /><%%KEEPWHITESPACE%%>    var d = $('&lt;div data-role="collapsible" data-content-theme="' +<br /><%%KEEPWHITESPACE%%>        options.theme + '" data-theme="' +<br /><%%KEEPWHITESPACE%%>        options.theme + '" data-collapsed="' +<br /><%%KEEPWHITESPACE%%>        options.collapsed + '"/&gt;');<br /><br /><%%KEEPWHITESPACE%%>    // wrap the existing children with this div<br /><%%KEEPWHITESPACE%%>    $(element).children().wrapAll(d);<br /><br /><%%KEEPWHITESPACE%%>    // tell jQM to render the new &lt;div&gt;<br /><%%KEEPWHITESPACE%%>    d.trigger("create");<br />}<br /><br />myapp.AddEditPerson.Address_postRender = function (element, contentItem) {<br /><%%KEEPWHITESPACE%%>    collapsibleContent(element, contentItem, { collapsed: true });<br />};<br />

If we run this, we’ll see it works fine, except there’s a bit of a styling glitch.

Styling_Issue

There are several ways to correct this.  I’m going to do it by adding an override in Content/user-customization.css:

<br />.ui-collapsible-inset .ui-collapsible-heading {<br /><%%KEEPWHITESPACE%%>    margin-right: 0px;<br /><%%KEEPWHITESPACE%%>    margin-left: 0px;<br />}<br />

Now the header aligns cleanly with the left and right border lines.

Styling_Fixed_001 Collapsed_001

13 thoughts on “jQuery Mobile Collapsible Content Control with LightSwitch

  1. If you’re using Live Writer please let us know which plugin you use to embed the source code.

  2. Hello,

    I have a table that contains categories with items. Data is inserted into a single table from a parent with children.

    It may look like:

    Category Item
    Floor 1: floor
    Floor 1: Ceiling
    Floor 1: Staircase
    Floor 2: kitchen
    Floor 2: Bathroom

    Is it possible to create collapsible content for each category, although these are in the same table?
    Regards
    Sven

Comments are closed.