Separate angular structure into various sections

I am developing a form builder using Angular dynamic form functionality. The form data is loaded from a JSON object, as shown below:

  jsonData: any = [
    {
      "elementType": "textbox",
      "class": "col-12 col-md-4 col-sm-12",
      "key": "first_name",
      "label": "First Name (Part 1 includes first name and last name with title name of Person Name)",
      "type": "text",
      "value": "",
      "required": true,
      "minlength": 3,
      "maxlength": 20,
      "order": 1
    },
    // Additional JSON elements go here...
  ];

The current implementation successfully generates the complete form. However, I aim to divide the form into distinct sections such as Person Name, Personal details, Family Details, each with a varying number of input boxes.

A live example can be found at this link.

In the provided example, you will notice that the JSON structure does not support inserting titles within the form. My goal is to split the form into different sections and add titles for each part.

Is there a way to achieve this ordering and separation of the form, similar to the following layout?

Person Name

 -> First Name
 -> Last Name

Personal Details

 -> Email
 -> Mobile Number
 -> Age

Family Details

 -> Father Name
 -> Mother Name

Please review the provided demo, showcasing the JSON file structure, and help me implement the form separation as described above.

Answer №1

Having tackled a similar task before, I understand the concept of creating a specialized elementType to manage groups of elements.

Take, for instance, the group configuration for a person's name:

const grouped: any = {
  "elementType": "group",
  "label": "Person Name",
  "children":[
    {
      "elementType": "textbox",
      "class": "col-12 col-md-4 col-sm-12",
      "key": "first_name",
      "label": "First Name",
      "type": "text",
      "value": "",
      "required": true,
      "minlength": 3,
      "maxlength": 20,
      "order": 1
    },
    {
      "elementType": "textbox",
      "class": "col-12 col-md-4 col-sm-12",
      "key": "last_name",
      "label": "Last Name",
      "type": "text",
      "value": "",
      "required": true,
      "order": 2
    }
  ]
};

To handle these groups effectively, you'll need to develop a dedicated component that can iterate through the children elements. Be mindful of the possibility of nested groups and ensure your solution is recursive.

For example:

<div *ngFor="let question of questions" class="form-row">
    <ng-container *ngIf="!question.children">
        <app-question [question]="question" [form]="form"></app-question>
    </ng-container>
    <ng-container *ngIf="question.elementType === "group" && question.children && question.children.length > 0">
        <app-dynamic-group [questions]="question.children" [form]="form"></app-dynamic-group>
    </ng-container>
</div>

In the group container component, the approach mirrors what's done in the dynamic form, suggesting potential consolidation of functionality:

<div *ngFor="let question of questions" class="form-row">
    <ng-container *ngIf="!question.children">
        <app-question [question]="question" [form]="form"></app-question>
    </ng-container>
    <ng-container *ngIf="question.elementType === "group" && question.children && question.children.length > 0">
        <app-dynamic-group [questions]="question.children" [form]="form"></app-dynamic-group>
    </ng-container>
</div>

If more clarification is needed, feel free to reach out.

A functional demonstration can be found here: https://stackblitz.com/edit/angular-x4a5b6-gwkc2z?file=src%2Fapp%2Fdynamic-group.component.html

Answer №2

If you're looking to create a sub-form component

Within your main form component, place all of your sub-components

Main Form Component:

<form [formGroup]="form" (ngSubmit)="onSubmit()">
  <app-person></app-person>
  <app-family></app-family>
  <app-personal></app-personal>
  <button class="btn btn primary">Save</button>
</form>

Utilize ControlContainer for managing multiple instances of NgControl within directives

ControlContainer:

A base class used by the forms module for directives containing multiple registered instances of NgControl.

Use ViewProviders to provide ControlContainer and leverage existing formGroupDirective to access the parentForm and add form controls

Sub-Component File: app-person.component.ts

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, ControlContainer, FormGroupDirective } from '@angular/forms';
@Component({
  selector: 'app-personal',
  templateUrl: './personal.component.html',
  styleUrls: ['./personal.component.css'],
  viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }]
})
export class PersonalComponent implements OnInit {
  personalForm;
  constructor(private parentForm: FormGroupDirective) { }
  ngOnInit() {
    this.personalForm = this.parentForm.form;
    this.personalForm.addControl('personal', new FormGroup({
      email: new FormControl(''),
      mobile: new FormControl(''),
      age: new FormControl('')
    }))
  }
}

Example: View on StackBlitz

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

What could be causing Gson to struggle with parsing my document that contains a nested escaped JSON string?

I've encountered a frustrating issue with GSON. For some reason, I can't seem to parse this document: [{"id":0,"assetId":2414775,"shipId":717,"assetType":"0","document":"{\"ratios\":[{\"points\":{\"x1\":0,\"y1 ...

Searching for matching strings in jQuery and eliminating the parent div element

Here's an HTML snippet: <div id="keywords"> <div id="container0"> <span id="term010"> this</span> <span id="term111"> is</span> <span id="term212"> a</span> <span ...

Scheduled Job unable to complete post request

(I am completely new to the world of JavaScript, node.js, and Heroku so I apologize in advance if my question is not very clear) I recently set up a Heroku node.js application with a scheduled task that should run every hour. The task does run as expecte ...

Change the state within the click event handler

One issue I'm facing is dealing with 2 submit buttons in my react form. To differentiate between the two buttons, I need to extract the `id` of the one that was clicked using the `onClick` function. Currently, when trying to set the state with this ` ...

Can one retrieve a catalog of Windows Updates that have been installed by utilizing node.js?

Currently, I am working on a JavaScript/Node.js project where I am seeking to retrieve a comprehensive list of all installed windows updates, similar to how it is done using the C# WUAPI 2.0 Type Library. I have attempted utilizing WMI calls (specifically ...

How to Make Buttons Vanish and Reappear

Check out this fiddle for a picture button 'scroller' that I created. It may not be perfect, but my main focus is on making the arrow buttons fade in and out when reaching the end of the picture order. I am considering using a JavaScript functio ...

The error message "Declaration file for module 'mime' not found" was issued when trying to pnpm firebase app

Currently, I am in the process of transitioning from yarn to pnpm within my turborepo monorepo setup. However, I have run into an issue while executing lint or build commands: ../../node_modules/.pnpm/@<a href="/cdn-cgi/l/email-protection" class="__cf_e ...

What could be causing the .hover function to malfunction and how can I make it so that the .hover function only applies within the corner radius area?

I am attempting to make circles react to my jquery .hover function. Below is the JavaScript code I am using: jQuery.fn.center = function () { this.css("position","absolute"); this.css("top", Math.max(0, (($(window).height() - this.outerHeight()) / 2) + ...

Modify the CSS using JavaScript after a brief delay

I'm creating a homepage that includes animations. Inside a div, I initially have display: none, but I want it to change to display: block after a few seconds. I've been trying to use JavaScript for this purpose, but I'm struggling to find th ...

Removing numerous elements in JSON structures

name_list = [{'name': 'John'}, {'name': 'Johan'}, {'name': 'John'}] for i in xrange(len(name_list)): if name_list[i]["name"] == "John": del name_list[i] Once the code rec ...

Distinguishing Data Input Formats for REST WCF Services (JSON vs XML)

So, I am experimenting with WCF and creating a restful service. Currently, users are sending me data through http post requests in json format and I have one method set up to receive this data. But now I want to configure another method to be able to acce ...

Using React to iterate through the child components of the parent

I have created a component that can accept either a single child or multiple children. Here is an example with multiple children: <SideDataGridItem> <div id='top'> <div>A1</div> <div>B1</div> ...

Troubleshooting base href issues in AngularJS routing

For a demonstration, I decided to try out this plunker from a tutorial that showcases tab routing across different pages. After downloading the entire zip file and running it as is (e.g. with all files in the same directory and utilizing CDN links), I enco ...

Avoid the problem of animations triggering twice when clicking

Hey there, I am facing an issue with my slider. If you could take a look at this website , you will notice that after clicking on the arrows, the slider behaves asynchronously. It changes speed rapidly at times and then slows down, repeating this pattern ...

updateStatusCallback function is not defined in the Facebook example using jQuery

I've been trying to incorporate Facebook integration into my HTML code, specifically adding features like Facebook login and sharing functionalities. However, I've hit a roadblock in the process. Even after searching extensively for solutions, I ...

"Converting PostgreSQL data into a PHP array with the column serving as the index

Is it possible to return a JSON object directly from a PostgreSQL query? Let's say the query produces results like this: who count ================= mary 2 had 9 a 12 lamb 9 The database has columns "who" and "count." I ...

My custom function is not invoking the Firebase function createUserWithEmailAndPassword

The function createUserWithEmailAndPassword is not being triggered within the SignUpUser function when the onClick event occurs. However, it works when I use onClick={signUpUser(email,password)} import React from 'react'; import styled from &apo ...

What would be the ideal labels for the parameters within Array.reduce?

When it comes to enhancing code readability, what naming convention should be employed when naming callback arguments in Array.reduce for optimal best practices? const studentAges= [15,16,14,15,14,20] Generalized Approach const sum = studentAges.reduce ...

MUI version 5 - Checkboxes are receiving a variety of unique classes

After recently upgrading from Mui v4 to v5, I've noticed a strange behavior with checkboxes. Upon inspecting the DOM differences between the two versions, it appears that some additional classes are now being applied in v5 and the extra span with the ...

text within the table is overlapping when being created dynamically in the <table> using javascript and jquery.quickflip.js

Hello everyone, I am currently working on dynamically generating a table using tabs created with jquery.quickflip.js. However, I have run into an issue where the text from one tab may overwrite values in another tab when switching between them. Below is ...