Dashborg Documentation / Docs / Binding Data

Binding Data

Dashborg uses two-way data binding in order to make your UI dynamic. This means:

  • When you update your panel’s data the UI updates
  • When a user interacts with your UI (input controls, selections, checkboxes, etc.) your panel’s data updates.

Basic Data Binding

Here are some examples of binding data to your UI. These examples all assume the following data:

{
   "message": "Test Message",
   "x": 55,
   "y": 3.14159,
   "items": [
       { "id": 4561, "name": "Mike" },
       { "id": 5202, "name": "Chris" },
       { "id": 6728, "name": "Eric" }
   ],
   "point": [2, 3],
   "color": "blue",
   "button_role": "primary"
}

To display text use the <d-text> element:

   <d-text bind="$.message"/>                    => Test Message
   <d-text bind="$.x"/>                          => 55
   <d-text bind="$.x * 2"/>                      => 110
   <d-text bind="$.x > 50 ? 'blue' : 'green'"/>  => blue
   <d-text bind="$.y" format="%d"/>              => 3
   <d-text bind="$.y" format="%0.2f"/>           => 3.14
   <d-text bind="$.point"/>                      => [Object]
   <d-text bind="$.point" format="json"/>        => [2, 3]
   <d-text bind="fn:len($.message)"/>            => 12
   <d-text bind="fn:len($.items)"/>              => 3

You can also bind to HTML attributes and style properties by starting the value with the * character. For most style properties Dashborg will automatically add the “px” suffix to numeric values (not strings). It will not add them for “unitless” properties.

   <button class="*$.button_role">               => <button class="primary">
   <div style="width: *$.x; height: *$.x+10">    => <div style="width: 55px; height: 65px;">
   <div style="flex-grow: *$x > 10 ? 1 : 0">     => <div style="flex-grow: 1;">
   <div style="width: *$.x + '%'">               => <div style="width: 55%">
   <div style="background-color: *$.color; width: 20%">      => <div style="background-color: blue; width: 20%;">

For classes and styles writing a lots of inline dynamic properties can be cumbersome. Dashborg allows a special . syntax to set classes and styles. class.primary="value" evaluates it’s value (remember to use a * if you want it to be a data model expression) and adds the class if the value is truthy, and removes the class if it is falsey.

   <button class.primary="* $y > 1.0">           => <button class="primary">
   <button class="btn" class.secondary="*true">  => <button class="btn secondary">
   <div class="wide" class.wide="* $x > 100">    => <div>
   <div class.foo="1">                           => <div class="foo">
   
   <div style.background-color="*$.color">       => <div style="background-color: blue;">

To optionally include/remove an element you can use the special attribute if. if is always evaluated as an expression (so do not add a * prefix). If the attribute is truthy the element is shown, otherwise it will be removed.

   <div if="$.color == 'green'">green</div>      => 
   <div if="$.color == 'blue'">blue</div>        => <div>blue</div>
   <d-text bind="$.x"> apple<d-text if="$x == 0 || $x >= 2" bind="'s'/>   => 55 apples

For groups of elements you can also use the <if> or <d-if> element

   <if condition="$.color == 'green'">                       => 
     The color is <span style="color: green">green</span>!
   </if>
   
   <if condition="$.color == 'blue'">                        => The color is <span style="color: blue">blue</span>!
     The color is <span style="color: blue">blue</span>!
   </if>

To loop over data, use <foreach> (or <d-foreach>). Inside of the loop . (or $local) is set to the current loop item, and @index is set to the 0-indexed loop index.

   <d-foreach bind="$.items">                                => 1. Mike
       <d-text bind="@index+1">. <d-text bind=".name"/>         2. Chris
   </d-foreach>                                                 3. Eric
   
   <ul>                                                         => <ul>
     <d-foreach bind="$.items">                                      <li style="color: blue">Mike</li>
       <li style="color: *$.color"><d-text bind=".name"/></li>       <li style="color: blue">Chris</li>
     </d-foreach>                                                    <li style="color: blue">Eric</li>
   </ul>                                                           </ul>

Binding Inputs / Controls

Some HTML elements can set values into the data-model as well as read values from the data model. For example a checkbox, or text input.

   <input type="checkbox" bindvalue="$state.ischecked"/>
   <input type="text" bindvalue="$state.name" placeholder="Name"/>

We use the bindvalue attribute on <input>, <textarea>, and <select> elements. The bindvalue attribute creates a 2-way data binding. If a value is set in the data model the input will be updated to have that value. If the user interacts with the control and changes the input’s value (by typing, checking, or selecting) then the data value will be updated to the user selected value.

To set a default value for the control (only used if the underlying data model’s value has not been set e.g. null) then you can add the defaultvalue attribute.

Setting Static Data

Normally you can use your panel’s root handler (/) to set the initial panel data. Sometimes it is more convenient to set the data directly in the HTML. To do this you use the <d-data> element. It parses it’s body as JSON (not JavaScript, you must quote your key names and not have trailing commas!) and sets it into the data model at the bindvalue attribute. <d-data> will only execute the first time the tag is loaded. But be careful of using <d-data> in an if or foreach loop as it could execute unexpectedly or multiple times.

    <d-data bindvalue="$.options">
      [ "blue", "green", "red" ]
    </d-data>