0

I am developing a multi-page form (kind of like a wizard) that will include one or more pages of controls, and those controls will be custom controls.

Here is a picture of what I'm trying to develop:

enter image description here

This is (as of now) a template-driven form, and here is the template behind it:

<multiform [debug]="true" [title]="'New Job'">
    <multiform-page [title]="'Basics'" >Page for job basics
        <trk-select
            [placeholder]="'Research Client'"
            [fieldId]="fields.client.key"
            [options]="toTrkOptions(fields.client)"
            [multiple]="true">
        </trk-select>
    </multiform-page>
    <multiform-page [title]="'Detail 1'" >This is the first detail page</multiform-page>
    <multiform-page [title]="'Detail 2'" >More details go here</multiform-page>
</multiform>

I had intended to have the <form> within <multiform>:

multiform.control.html

{{title}}
<div class="tabset">
    <a *ngFor="let page of pages"
       [class.tab]="true"
       [class.hidden-tab]="false"
       [class.active]="page.active"
       (click)="activatePage(page)">
        {{page.title}}
    </a>
</div>
<form #form="ngForm">
    <ng-content></ng-content>
</form>

<div *ngIf="debug">
    <h1>Form Values</h1>
    <pre>{{form.value | json}}</pre>
</div>

Within each <multiform-page> there are a number of custom form controls. In this example, there's only one <trk-select> control, but this will grow.

The individual form controls are projected, like so:

multiform-page.component.html

<div class="content" [class.active]="active">
    <ng-content></ng-content>
</div>

My select control is working fine. When I include it directly on a form (not using ) it works fine, too. It is being projected fine on to my <multiform> as well. Now it is time to make this a real form, and that's when everything falls apart.

I wanted multiform to have the actual <form> component, and to bind the controls to it.

But I can't do this:

<div class="content" [class.active]="active">
    <ng-content [(ngModel)]="field"></ng-content>
</div>

because I don't know what field is here. (remember, there will be multiple controls, and they can't all bind to the same variable)

So the arcitecture here kind of looks like this:

<multiform>
  |--> has <form>
  |--> projects <multiform-page>
                     |
                     |--> projects custom control 1
                     |--> projects custom control 2

But I can't figure out how to bond those controls to the form. How can I do it?

John Dibling
  • 99,718
  • 31
  • 186
  • 324

1 Answers1

1

You should be using selector

<div class="content" [class.active]="active">
    <ng-content select=".multiform-body"></ng-content>
</div>

And you have to push your html as

<div>
   <div class="multiform-body>
      ...........................................
      these contents are replaced in your multiform component
    </div>
</div>

Update:

<multiform [debug]="true" [title]="'New Job'">
    <multiform-page [title]="'Basics'" >Page for job basics
    <div class="multiform-body">
        <basics-component> </basics-component>
    </div>


    </multiform-page>
    <multiform-page [title]="'Detail 1'" >
    <div class="multiform-body">
        <detail1-component> </detail1-component>
        This is the first detail page
    </div>
    </multiform-page>
    <multiform-page [title]="'Detail 2'" >

    <div class="multiform-body">
        <detail2-component> </detail12-component>
        This is the first detail page
    </div>

    </multiform-page>
</multiform>

Update 2 :

When you are using custom controls which will be used across the application you can group them together as CustomControls and have them separately as individual components.

For instance, you have below components across your application

  1. Students dropdown
  2. Teachers dropdown

So you should have a a separate <students-dropdown> and <teachers-dropdown> with some input and output variables to manipulate the data.

Update based on comment to bind the selected value <trk-select>, follow these

<trk-select (change)="trkChanged($event)"><trk-select>

<detail-component (trkChange)="trkChanged($event)"> </detail-component>

<multi-form>
   <detail-component (trkChange)="trkChanged($event)"> </detail-component>
</multi-form>

So three emit variables in respective components.

Aravind
  • 40,391
  • 16
  • 91
  • 110
  • I'm trying to get my head around what you've said here. When you say 'push your html as...' which html are you referring to? Is that the control on the page? IOW are you saying I need to wrap my `` component within a `div`? Sorry, I'm just a bit confused. – John Dibling Mar 24 '17 at 22:06
  • Just saw you're edit, and that makes more sense, thanks. Still not quite seeing how I can get the controls on `` to bind to the form on ``. Could you help me understand that? – John Dibling Mar 24 '17 at 22:09
  • I didnt get your question can you elaborate? – Aravind Mar 24 '17 at 22:11
  • Sure. `` will have a `` on it. That's a custom form control. I want to bind the selection made in the `` component to the `
    ` component on ``.
    – John Dibling Mar 24 '17 at 22:16
  • So I've got (A) `` which has a `
    ` on it, and projects multiple (B) ``'s. Each `` projects (C) multiple custom form controls (like input, select, etc). How do I get the updates in (C) to bind to the form that lives in (A)?
    – John Dibling Mar 24 '17 at 22:19
  • BTW, that d/v is not from me. – John Dibling Mar 24 '17 at 22:21
  • have a look at my updated answer. One person has downvoted 6 answers of mine. @JohnDibling is this was your expectation – Aravind Mar 24 '17 at 22:22
  • It seems like you're indirectly suggesting that I can't use `` at all for the controls on the individual pages. Is that right? – John Dibling Mar 24 '17 at 22:24