Monday, April 29, 2013

Dynamic Tables With Mustache

Problem: Generate dynamic tables from a dynamic array with Mustache given that:

  1. Total column count is unknown
  2. Only one or two column names are known and must be rendered conditionally
  3. Helper functions many not be used
  4. Data is only provided in arrays. Not model classes
Typical data-set with variable column count where ID is the only column know to always be provided:

[id*]   [Col-1]    [Col-2]    [Col-3]   ...(more)
 1      'Foo'      'Bar'      'Baz'    ...(more)
 2      'Foo'      'Bar'      'Baz'    ...(more)
 3      'Foo'      'Bar'      'Baz'    ...(more)
 ...
(more)

Solution: Mix variating key names with constant key name

In this example below, the variating keys are based on the various column names provided dynamically from the datasource which are ("id"; "name"; "legal_name"; "email"; "signon_email"; "editable") and the constant key name is "field"

array (size=6)
  0 => 
    array (size=2)
      'id' => string '10' (length=2)
      'field' => string 'id' (length=2)
  1 => 
    array (size=2)
      'value' => string 'J. Doe' (length=8)
      'field' => string 'name' (length=8)
  2 => 
    array (size=2)
      'value' => string 'Jane Doe' (length=8)
      'field' => string 'legal_name' (length=8)
  3 => 
    array (size=2)
      'value' => string 'Jane@Doe.com' (length=12)
      'field' => string 'email' (length=12)
array (size=6)
  0 => 
    array (size=2)
      'id' => string '11' (length=2)
      'field' => string 'id' (length=2)
  1 => 
    array (size=2)
      'value' => string 'Jon Doe' (length=8)
      'field' => string 'name' (length=8)
  2 => 
    array (size=2)
      'value' => string 'John Doe' (length=8)
      'field' => string 'legal_name' (length=8)
  3 => 
    array (size=2)
      'value' => string 'John@Doe.com' (length=12)
      'field' => string 'email' (length=12)

The original data source's column name is provided which can be used in Mustache to know what field is being iterated whilst "field" key provides an invariable token name which can be used in Mustache to reference the value for the field as follows:

{{#rows}}
<tr>{{#fields}}
        <td>{{#id}}<a href="foo/{{id}}">{{id}}</a>{{/id}}
            {{^id}}{{field}}: {{value} {{/id}}
        </td>
    {{/fields}}
</tr>
{{/rows}}

The following is produced:
<tr>
        <td><a href="foo/10">10</a></td>
        <td>name: J Doe</td>
        <td>legal_name: Jane Doe</td>
        <td>email: Jane@Doe.com</td>
</tr>
<tr>
        <td><a href="foo/11">11</a></td>
        <td>name: Jon Doe</td>
        <td>legal_name: John Doe</td>
        <td>email: John@Doe.com</td>
</tr>