Suman Kundu Suman Kundu - 5 months ago 141x
JSON Question

Schema form using Aurelia

I am using aurelia to build a dynamic form based on a json. The form is generating from a json like the following:

Schema = [{
'key': 'Name',
'display': 'Name',
'type': 'text',
'placeholder': 'Name',
'required': true
'key': 'IsSubscribed',
'display': 'Subscribed to newsletter?',
'type': 'checkbox',
'placeholder': null,
'required': false

The model to fill the form is available via a Web API service. So, far I succeed by the following template.


<section class="au-animate">
<h2>Edit Form</h2>
<form class="form-group">
<div repeat.for="item of Schema" class="form-group">
<label if.bind="item.type === 'text' || item.type === 'checkbox'" class="control-label" for.bind="item.key">${item.display}
<input class="form-control" id.bind="item.key" placeholder.bind="item.placeholder" type.bind="item.type" value.bind="Model[item.key]" />
<label if.bind="item.type === 'textarea'">${item.display}
<textarea placeholder.bind="item.placeholder" value.bind="Model[item.key]></textarea>


Now I am facing difficulties, when the Model contains another object as property. E.g., for the property Address I would like a input box for City. Hence, item.key = "Address.City".

I can bind with (1) Model.Address.City or (2) Model['Address']['City'] which are not possible as the form is generating at runtime. I would like to use something like (3) Model['Address.City'], so that I can use Model[item.key] for the binding. Is their any easy syntex to achive this.

Example of similar application in Angular Js is Angular Schema Form

Thanks in advance.


This can be accomplished with a binding behavior that understands what to do with the keys. The end-result is the binding will function like any other binding expression.

Here's an example:


  <require from="./dynamic-expression-binding-behavior"></require>

    Address 1:
    <input value.bind="model & dynamicExpression:'address.address1'">
    Address 2:
    <input value.bind="model & dynamicExpression:'address.address2'">
    <input value.bind="model & dynamicExpression:key">
    <input value.bind="model & dynamicExpression:'address.state'">
    <input value.bind="model & dynamicExpression:''">


export class App {
  model = {
    address: {
      address1: '1 Main Street',
      address2: '',
      city: 'Burlington',
      state: 'VT',
      zip: '05401'

  key = '';


import {inject} from 'aurelia-dependency-injection';
import {Parser} from 'aurelia-binding';
import {rebaseExpression} from './expression-rebaser';

export class DynamicExpressionBindingBehavior {
  constructor(parser) {
    this.parser = parser;

  bind(binding, source, rawExpression) {
    // Parse the expression that was passed as a string argument to
    // the binding behavior.
    let expression = this.parser.parse(rawExpression);

    // Rebase the expression
    expression = rebaseExpression(expression, binding.sourceExpression);

    // Squirrel away the binding's original expression so we can restore
    // the binding to it's initial state later.
    binding.originalSourceExpression = binding.sourceExpression;

    // Replace the binding's expression.
    binding.sourceExpression = expression;

  unbind(binding, source) {
    // Restore the binding to it's initial state.
    binding.sourceExpression = binding.originalSourceExpression;
    binding.originalSourceExpression = null;