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

Navigating to a parent URL where the Angular configuration is set can be achieved by following these steps

My application revolves around a webpage created with the use of node and angular. On the root URL (/), I have incorporated a signup and login form without the use of Angular. Upon successful login, Angular scripts and configuration files are loaded on the ...

Clicking on a checkbox within an HTML table that incorporates handlebar and Express.js

My situation involves a HTML table within a form that is being populated with Handlebars. I need to be able to select certain rows in the table using checkboxes, and upon form submission through a POST request in an Express.js framework, I require the JSON ...

What exactly constitutes a circular data structure within JSON?

I'm encountering an issue in my Express app where I am receiving the following error: UnhandledPromiseRejectionWarning: TypeError: Converting circular structure to JSON Despite searching for similar problems, I am struggling to grasp the concept o ...

Node.js does not allow the extension of the Promise object due to the absence of a base constructor with the required number of type

I'm trying to enhance the Promise object using this code snippet: class MyPromise extends Promise { constructor(executor) { super((resolve, reject) => { return executor(resolve, reject); }); } } But I keep encou ...

Tips for transforming an array of images (from an input field) into a JSON string

After creating an array of images using var a = Array.from(document.getElementById("id").files); I tried to generate a JSON string of that array using var b = JSON.stringify(a); However, all I get is an empty array. It seems like this issue is common w ...

Is there a way for me to implement a service method that retrieves the onSnapshot result, allowing me to seamlessly integrate it into my Component or Ionic Page?

Currently, I am using "ionic-angular": "3.7.1" along with Firebase Cloud Firestore. My goal is to retrieve all the documents from the Post collection whenever they are updated, deleted, or added. I have been informed that by calling the onSnapshot Method, ...

Validation in custom components within an Angular reactive form is failing to function correctly

Currently, I am in the process of developing a new component within Angular reactive forms. To view my sample project: https://stackblitz.com/edit/angular-pyi9jn The angular form I created follows this structure: form - simple counter The form output i ...

Accept either a string or an integer in the JSON response

When dealing with a dictionary fetched from a rest API call, the catData variable holds important information: NSString* catId = catData[@"id"]; This approach works well if catData["id"] is a string. However, it may not be suitable if it's an intege ...

What could be the reason behind json_encode() omitting the object's functions that were specified?

Recently, I decided to experiment with json_encode for the first time. I created a simple object: class Test { public $action= 'sleep'; public function wake() { $this->action = 'wake'; } } After creating the object, I en ...

Incorporate external JavaScript libraries not built with Angular

Our project utilizes NPM in conjunction with Browserify for managing third-party dependencies, which pairs well with AngularJS due to the CommonJS-modules. Below is a code snippet showcasing the dependency structure that integrates seamlessly with Angular ...

An empty array is being returned by the Model.find() method after sorting

let query = Tour.find(JSON.parse(queryStr)); if (req.query.sort) { query = query.sort(req.query.sort);//a string 'ratings' } const tours = await query; res.status(200).json({ status: 'success', requestedAt: req.requestTime, ...

What is the best way to enable my search function to filter out specific items from a table?

Currently, I have created a table populated with data fetched from a JSON file. Now, my focus is on implementing a search functionality that filters out items based on user input and displays only those table rows matching the search criteria. The code sni ...

Utilizing JSON arrays retrieved from an API to generate an introductory message for an IRC Bot

1st Question: Currently, I am in the process of developing an IRC Bot using Pircbot in Java that integrates with the OpenWeatherMap API. However, I am facing a challenge in displaying a preliminary message once the bot connects to the channel. The intenti ...

Every time I attempt to submit the login form on the Ionic and Angular page, instead of capturing the values of the form group, the page simply refreshes

Struggling with submitting the login form in Ionic and Angular? When attempting to submit, the page reloads instead of capturing the form group values. I am utilizing angular reactive forms and form builder within the ionic framework. Need assistance in id ...

Tracking mouse positions across an HTML document

I've been working on a project inspired by the voxel painter example on the three.js page. In this particular example, the mouse coordinates are utilized to move a roll-over helper that indicates where a box will be placed upon click. mouse.set((even ...

Utilizing Angular 2 to pass parameters in an HTTP GET request

How can I include parameters in a GET request using Angular 2? I attempted the following method, but received an error message: Argument of type '{ params: URLSearchParams; }' is not assignable to parameter of type 'RequestOptionsArgs' ...

Encountering difficulties displaying navigation interface with react native navigation's stack navigator

I am trying to implement a custom side navigation bar in React Navigation without using drawerNavigator. I have fixed the side nav bar and bottom bar in app.js so that they appear on all screens. The main content area should change based on button clicks o ...

Using CSS or JavaScript to trigger events while scrolling with touch

Imagine a scenario where multiple boxes are stacked on top of each other: <div style="width: 100%; height: 100px; background-color: red"> stuff </div> By clicking or touching them, the background color can be easily changed using CSS (:hover, ...

Unable to locate module within a subdirectory in typescript

The issue I'm facing involves the module arrayGenerator.ts which is located in a subfolder. It works perfectly fine with other modules like Array.ts in the parent folder. However, when I introduced a new module called Sorting.ts, it started giving me ...

Tips for employing e.preventDefault within the onChange event handler for a select element

Is there a way to prevent the select tag value from changing using preventDefault? I have successfully prevented input from changing the value with event.preventDefault, but have not been able to do the same for the select tag. Here is an example code sni ...