Table of Contents

Data Bindings API

You can use the Data Binding API to manually force a data transfer from the binding source to the binding target, effectively triggering a re-render of the data-bound UI element.


Get bindings

getBindings(model) : { updateTarget: () => void, targetName: string }[]

Gets an array of bindings associated with the specified model.


Example

The example below shows how to retrieve a list of all bindings associated with the Customers list. It then forces each binding target (UI element) to update unless it's named "bar".

      <Function Name="foo">
          for(let binding of this.dataBindings.getBindings(this.lists.Customers)){
                   if(binding.targetName !== 'bar'){
                           binding.updateTarget();
                   }
          }
      </Function>

Complete Example

The example below shows a sample implementation of how to use the Data Bindings API together with the ItemsSourceFilter option to ensure that a user cannot select the same customer from two dropdown controls at the same time.

Notice that both dropdowns are data-bound to the same source (Customers) and that both are using the ItemsSourceFilter to choose a subset of customers to render.

<Form>
  <Style>
    <Css><![CDATA[
.label{
    margin-top:10px;
}

.input{
    margin-top:3px;
}]]></Css>
    <Layouts>
      <Grid Name="ui-root" Rows="auto auto auto auto auto auto 1fr" Columns="150px 1fr" />
    </Layouts>
  </Style>
  <Texts />
  <Data>
    <Models/>
      <Model Name="CustomerInfo" Source="@Object[CustomerInfo].DbObjectName" Fields="ID,Name" />
      <Model Name="CustomerInfo2" Source="@Object[CustomerInfo].DbObjectName" Fields="ID,Name" />
    </Models>
    <Lists>
        <List Name="Customers" Source="@Object[Customers].DbObjectName" Fields="ID,Name"/>
    </Lists>
    <SetModels />
    <Dimensions />
  </Data>
  <Functions>
      <Function Name="onItemSelected" Parameters="selectedItem, controlName">
          if(!selectedItem){
              // The user deselected / cleared the selected item from the dropdown
              delete this.selections[controlName];
          }else{
               // The user changed the selected item in the dropdown
               this.selections[controlName] = selectedItem.ID;
          }

          // Get all the bindings associated with the Customers list,
          // and update all except the one that is associated with the control that triggered the change
          for(let binding of this.dataBindings.getBindings(this.lists.Customers)){
              if(binding.targetName !== controlName){
                  binding.updateTarget();
              }
          }
      </Function>
      <Function Name="Filter" Parameters="items, controlName">
          // This function is called every time a dropdown render, to determine
         // which items to show in the dropdown menu
          if(!this.selections){
             return items;
          }

          let notSelectableItems = [];
          for(let p of Object.keys(this.selections).filter(f => f !== controlName)){
              notSelectableItems.push(this.selections[p]);
          }

          return items.filter(f => notSelectableItems.indexOf(f.ID) == -1);
      </Function>
  </Functions>
  <EventHandlers>
      <FormEventHandler On="Init">
          // Create a variable to store the state of each dropdown control.
          // We will use it in the Filter function to determine which items to show
          this.selections = {};
      </FormEventHandler>
  </EventHandlers>
  <UI Grid="ui-root">
    <Label Row="1" Column="1" CssClass="label" Text="ID" />
    <Dropdown Name="dd1" Row="2" ItemsSource="Customers" ItemsSourceFilter="Filter($Data, $Ctrl.Id)" DisplayMember="Name" ValueMember="ID" SelectedValue="{Binding Path:CustomersInfo.ID}" ItemSelected="onItemSelected($Data, $Ctrl.Id)"/>

    <Label Row="3" Column="1" CssClass="label" Text="ID2" />
    <Dropdown Name="dd2" Row="4" ItemsSource="Customers" ItemsSourceFilter="Filter($Data, $Ctrl.Id)" DisplayMember="Name" ValueMember="ID" SelectedValue="{Binding Path:CustomersInfo2.ID}" ItemSelected="onItemSelected($Data, $Ctrl.Id)"/>
  </UI>
</Form>