0

I am making angular dynamic form with form-elements loaded through JSON..

The form element generation are working fine, but i am in the need of change of form elements based on options selected from dropdown..

JSON that generates form-elements

  jsonData: any = [
    {
      "elementType": "textbox",
      "class": "col-12 col-md-4 col-sm-12",
      "key": "project_name",
      "label": "Project Name",
      "type": "text",
      "value": "",
      "required": false,
      "minlength": 3,
      "maxlength": 20,
      "order": 1
    },
    {
      "elementType": "dropdown",
      "key": 'project',
      "label": 'Choose option to display',
      "options": [
        { "key": 'description', "value": 'Show Project Description' },
        { "key": 'level', "value": 'Show Project Level' },
        { "key": 'members', "value": 'Show Project Members' }
      ],
      "order": 2
    },
    {
      "elementType": "textbox",
      "class": "col-12 col-md-4 col-sm-12",
      "key": "project_desc",
      "label": "Project Description",
      "type": "text",
      "value": "",
      "order": 3
    },
    {
      "elementType": "dropdown",
      "key": 'project_level',
      "label": 'Choose Project Level',
      "options": [
        { "key": 'low', "value": 'Low' },
        { "key": 'medium', "value": 'Medium' },
        { "key": 'high', "value": 'High' }
      ],
      "order": 4
    },
    {
      "elementType": "dropdown",
      "key": 'project_members',
      "label": 'Choose Project Member',
      "options": [
        { "key": 'developer', "value": 'Developer' },
        { "key": 'leader', "value": 'Leader' },
        { "key": 'manager', "value": 'Manager' }
      ],
      "order": 5
    }
  ];

Based on the above JSON, the elements are generated..

Here you can see that Order 1 has textbox with project name which has no changes.

Then in next we have a dropdown with key as project, from here only the requirement starts..

In options, if i choose Show Project Description, then the Project Description textbox needs to be displayed and other two project_level and project_members needs to be in hidden format..

Likewise if i choose Show Project Level then the Project Level dropdown alone needs to be displayed and the Project Description and Project Members needs to be in hidden..

In the same way for Project Members..

So how to change the form-elements based on the selection of project dropdown values??

The working example for the same was here https://stackblitz.com/edit/angular-x4a5b6-5ys5hf

Kindly help me to hide the other elements based on the selection from the project dropdown using angular dynamic form alone..

2 Answers 2

2

As @benshabatnoam say the only thing you need is change you dinamic-form-question to include some like

<div [formGroup]="form" *ngIf="?????">

You can use a condition like @Benshabatnoam say, but I suggest you some more "parametrizable"

Imagine your json has a new property "visible" that was an object with two properties, field and value. So, your element "project_desc" can be like

{
  "elementType": "textbox",
  "class": "col-12 col-md-4 col-sm-12",
  "key": "project_desc",
  "label": "Project Description",
  "type": "text",
  "value": "",
  "order": 3,
  "visible":{"field":"project","value":'description'} //<--add this "property"
},

So the dinamic-form-question can be like

<div [formGroup]="form" 
   *ngIf="!question.visible || 
   form.get(question.visible.field).value==question.visible.value">
...
</div>

See that I include the condition (!question.visible) so, if you don't give the property "visible" to one field, this field is showed always.

Well, you must work some more, you must change question-base.ts to admit this new property

export class QuestionBase<T> {
  value: T;
  ...
  visible:any; //<--ad this property


  constructor(options: {
    value?: T,
    ...
    visible?:any, //In constructor include "visible" too
    ..
  }){
    this.value = options.value;
    ...
    this.visible = options.visible;
  }

You can see your forked stackblitz

Sign up to request clarification or add additional context in comments.

4 Comments

Eliseo, In your stacblitz i am able to see two input boxes showing always.. But i need to display only one on selection..
Sorry now the requirement was changed and so i have posted new question stackoverflow.com/questions/53626407/… , there i need to switch form element based on the dropdown either it can be input box or dropdown for the same key..
about your question, only need add the property "visible":{"field":"project","value":'level'}, and "visible":{"field":"project","value":'members'}, in your json to the "questions" 4 and 5
Unable to get you.. As the requirement was changed, i am expecting the same output for this stackoverflow.com/questions/53626407/… , i hope you can give a better solution.. Here we are hiding the elements, whereas there i need to switch between either textbox or dropdown based on the order 1 dropdown selection.. Hope you got that question.. If not i can clear you.. I am sorry for it, please help me to switch the form element..
0

You need to make few changes to your code.

  1. Change the json so that the options key will match the controls key.

    ... { "elementType": "dropdown", "key": 'project', "label": 'Choose option to display', "options": [ { "key": 'project_desc', "value": 'Show Project Description' }, { "key": 'project_level', "value": 'Show Project Level' }, { "key": 'project_members', "value": 'Show Project Members' } ], "order": 2 }, { "elementType": "textbox", "class": "col-12 col-md-4 col-sm-12", "key": "project_desc", "label": "Project Description", "type": "text", "value": "", "order": 3 }, ...

  2. In your form add a *ngIf to the app-question component that will execute a function passing it the question, and this function will holding the logic for hiding the given question.

    <app-question *ngIf="isShowQuestion(question)" [question]="question" [form]="form"> </app-question>

  3. The function logic would check if the question is one of the controls you want to hide, and if so it will check the value of the dropdown 'option to display' for match, if match it will show the question else it will hide the question.

    isShowQuestion(question: QuestionBase<any>): boolean { // If one of the controls you want to hide if (question.key === 'project_desc' || question.key === 'project_level' || question.key === 'project_members') { // if the option to display have value and it is this question that show it else don't show it return !this.form.controls['project'].value || this.form.controls['project'].value === question.key; } else { // if not, always display return true; } }

I've forked your stackblitz project, so you can see it in action here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.