Using Aurelia to create a schema form

In my project, I am utilizing Aurelia to create a dynamic form based on a JSON data. The form is being generated from a JSON structure similar to the one shown below:

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 required to fill in the form is accessible via a Web API service. So far, I have managed to successfully implement the following template.

    <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>
            <label if.bind="item.type === 'textarea'">${item.display}
                <textarea placeholder.bind="item.placeholder" value.bind="Model[item.key]></textarea>
            </label>
            ...
        </div>
    </form>
    </section>

    </template>

However, I am currently encountering challenges when the Model contains another object as a property. For instance, for the Address property, I would like to include an input field specifically for City.

This leads to a scenario where item.key = "Address.City".

I am unable to bind with either (1) Model.Address.City or (2) Model['Address']['City'] since the form is dynamically generated at runtime. My aim is to use something like (3) Model['Address.City'], allowing me to utilize Model[item.key] for binding. Is there a straightforward syntax to achieve this?

An example of a similar application using Angular JS can be found at: Angular Schema Form

Thank you for any assistance provided in advance.

Answer №1

One way to achieve this is by using a binding behavior that can interpret and handle the keys appropriately. This approach will enable the binding to operate similarly to other binding expressions.

For instance, consider the following:

app.html

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

  <label>
    Address 1:
    <input value.bind="model & dynamicExpression:'address.address1'">
  </label>
  <label>
    Address 2:
    <input value.bind="model & dynamicExpression:'address.address2'">
  </label>
  <label>
    City:
    <input value.bind="model & dynamicExpression:key">
  </label>
  <label>
    State:
    <input value.bind="model & dynamicExpression:'address.state'">
  </label>
  <label>
    Zip:
    <input value.bind="model & dynamicExpression:'address.zip'">
  </label>
</template>

app.js

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

  key = 'address.city';
}

dynamic-expression-binding-behavior.js

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

@inject(Parser)
export class DynamicExpressionBindingBehavior {
  constructor(parser) {
    this.parser = parser;
  }

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

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

    // Store the original expression of the binding for future reference.
    binding.originalSourceExpression = binding.sourceExpression;

    // Set the new expression for the binding.
    binding.sourceExpression = expression;
  }

  unbind(binding, source) {
    // Restore the original state of the binding.
    binding.sourceExpression = binding.originalSourceExpression;
    binding.originalSourceExpression = null;
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The pattern() and onkeyup() functions are unable to function simultaneously

When trying to display a certain password pattern using regex while typing in the fields, I encountered a problem. The onkeyup() function works for checking if both passwords match, but it causes the pattern info box not to appear anymore. I'm curiou ...

When I use `console.log` with `req.body` in Node, the password is

Currently, I am utilizing NodeJs on the backend to console.log(req.body) data from a form that gathers usernames and passwords from users. I have noticed that this method exposes the collected username and password information. Should I be concerned abou ...

Exploring the world of Node.js callback parameter passing

Currently, I am diving into the world of Node callbacks and JavaScript in general. As I delve deeper, I find myself puzzled by the following snippet: var request = require('request'); request('http://www.google.com', function (error, ...

Activating controllers with 2 independent sliders

(Using the WordPress Slider Revolution plugin) I have set up two sliders next to each other - one displaying the service name and description, and the other showing images. The goal is for clicking a specific bullet on the service slider to also trigger t ...

Heroku Internal Server Error with NextJs version 5.0.0

Below are the scripts that I am using: "scripts": { "dev": "node server.js", "build": "next build", "start": "NODE_ENV=production node server.js", "heroku-postbuild": "next build" }, This is the content of my procfile: web: npm start ...

"Exploring the symbiotic relationship between Node.js and Express.js: an

I recently started learning Node.js and Express.js. I used the Express.js executable (express) to create an express application, which generated the following lines in app.js: ... var app = express(); http.createServer(app).listen(app.get('port' ...

Adding client-side scripts to a web page in a Node.js environment

Currently, I am embarking on a project involving ts, node, and express. My primary query is whether there exists a method to incorporate typescript files into HTML/ejs that can be executed on the client side (allowing access to document e.t.c., similar to ...

Invoke a JSON request using either the subscribe method or a promise

Whenever I implement the promise function, an Error arises: **Property 'TEST' does not exist on type 'Object'** my ServiceClass This issue occurs in the following method: getTEST() { return this.http.get(this.configUrl) ...

Getting JSON Data Using Django's get_or_create

As a self-taught programmer exploring Python and Django, I am eager to optimize my code. One challenge I have encountered is performing a get_or_create operation with JSON data that directly correlates to my model entries. data=json.load(file) Person.objec ...

Unexpected error when using Slack SDK's `client.conversations.open()` function: "User Not Found"

I am currently utilizing the Slack node SDK in an attempt to send private messages through a bot using user IDs: const client = new WebClient(process.env.SLACK_TOKEN); const sendMessage = async (userId) => { try { await client.conversations.open( ...

The method .setArray has been deprecated in THREE.BufferAttribute. Instead, please use BufferGeometry .setAttribute for unindexed BufferGeometry operations

Seeking assistance with updating the webgl-wireframes library code to the latest version of threejs. The current function is generating the following errors: Uncaught TypeError: THREE.Geometry is not a constructor THREE.BufferAttribute: .setArray has ...

Only the first column of a row in Flexbox will have a line break when exceeding the

Currently, I am utilizing flex with a row direction for a set of items with fixed widths causing overflow and a horizontal scrollbar, which is the desired outcome. Nevertheless, my requirement is for the first column in these rows to be full-width, while ...

Unable to execute PHP alongside a JavaScript event listener

Using PHP, I am creating a canvas for writing and the text output will appear in a textarea (handled by other functions). There are additional input tags like a title to gather user input. The values from these input tags (title and textarea) will be submi ...

The JSON primitive provided is invalid while attempting to send a POST request

I'm currently facing an issue with an AJAX request where I'm attempting to send a JSON Object to the server: function sendData(subscriptionJson) { $.ajax({ type: "POST", url: '@Url ...

Utilize ethereumjs-wallet in your web browser as a standalone module

I am looking to generate a wallet (which includes creating an account address and private key) directly in the browser without the need to connect to a node. It seems that in order to utilize web3.js, a provider (such as Metamask or localnode) needs to be ...

Angular JS is up and running

My journey into the world of Angular JS has just begun. While I can put together an Angular module, I find myself with a myriad of questions regarding the inner workings of Angular. How exactly does $scope function? I know that a root scope is created ...

The issue with $.parseJSON when encountering double quotes

Could someone please clarify why a JSON string with double quotes can disrupt the functionality of $.parseJSON? This example works: [{"type":"message","content":{"user":"tomasa", "time":"1321722536", "text":"asdasdasd"}}] And so does this one: [{"type" ...

Assign a class to an element depending on the date

I need to customize a span element in my HTML code like this. html <span class="tribe-event-date-start">September 5 @ 7:00 pm</span> My objective is to identify that specific element based on its date and then apply a class to its parent co ...

The attribute 'inventory' cannot be found in the declaration of 'WarehouseModule'

I am facing an issue with my AngularFire setup. I have recently installed the latest version of AngularFire using npm i @angular/fire and have successfully configured Firestore. However, when attempting to load data into my Firestore database, I encounte ...

creation of cascading drop-down lists

I have been struggling to create a dependent dropdown list using ajax and php, but unfortunately I am not getting the desired outcome. Below is my ajax code: <html> <head> <title>findperson</title> <script type="text/javascript ...