0

I have an app that will show a line graph with a different number of lines depending on the number of selects (1 line for each selected field, maximum of 5 selects). The first two work very well because they are the pre-defined, I can specify (change)="function". The other 3 are optional, so I have added a button that adds selects to the html. The only problem is that when I add those selects dynamically they are not assuming the onchange function which is supposed to re-draw the graphic.

Here are samples of my code:

add() {

      var child = document.getElementById('addField');
      var selectList = document.createElement("select");

      if (child.previousElementSibling) {
          selectList.id = "field" + (parseInt(child.previousElementSibling.id.charAt(child.previousElementSibling.id.length-1)) + 1);
          selectList.innerHTML = selectList.innerHTML + child.previousElementSibling.innerHTML;
      }
      else {
          selectList.id = "field" + (parseInt(child.previousElementSibling.id.charAt(child.previousElementSibling.id.length-1)) + 1);
          selectList.innerHTML = selectList.innerHTML + child.previousElementSibling.innerHTML;
      }

      if(parseInt(selectList.id.charAt(selectList.id.length-1)) > 5)
        alert("Maximum number of parameters is : 5");
      else {
        selectList.setAttribute('onchange', "drawChart()");
        child.parentNode.insertBefore(selectList, child);
      }

    }

This function is to add the select above the addField button and it says that drawChart doesn't exist.

The html page looks like this:

<div id="principal">
<label>Parameters :</label>
    <select id="field1" (change)="drawChart()">
        <option *ngFor="let pos of array"
            [value] = "pos.name"
            [selected]="pos.name == 'def'">
            {{pos.name}}
        </option>
    </select>
    <select id="field2" (change)="drawChart()">
        <option *ngFor="let pos of array"
            [value] = "pos.name"
            [selected]="pos.name == 'def2'">
            {{pos.name}}
        </option>
        </select>
    <input type="button" class="button" id="addField" value="Add Field" (click)="add()"/>
</div>
12
  • Why are you writing directly to the DOM? Use a template. "drawChart()" cannot work because you are not working on the same context, that onchange is waiting for a window.drawChart() function. Commented Feb 2, 2017 at 13:00
  • That's not the angular way to do this. You should define your dynamic elements also in your template and add some conditions to them with *ngIf="showOptional" for instance. Commented Feb 2, 2017 at 13:02
  • How can I define dynamic elements in the component? @cy3er Commented Feb 2, 2017 at 13:07
  • Yes @camaron I know they are different contexts. But I'm new to angular 2 so I was hoping someone could enlight me on this. I have a template for the graphs page and in the middle somewhere there are the selects. Where should I use the template and how? Commented Feb 2, 2017 at 13:08
  • That doesn't look like Angular at all. How is Angular involved? Commented Feb 2, 2017 at 14:01

1 Answer 1

1

Just add something like this after your last select element.

<select id="{{extraItem.id}}" *ngFor="let extraItem of extraFields" (change)="drawChart()">
    <option *ngFor="let child of extraItem.children"
             [value] = "child.name"
             [selected]="child.name == 'Opt 2 - 1'">
             {{child.name}}
    </option>
</select>

Check this plunker:

https://plnkr.co/edit/p1WimIz3ygE2CSs2tmw2?p=preview

I think that you want something like this.

You want to have full control of everything from your angular app, it's better to have templates and find the way to do all without write directly to the DOM and let angular handle the DOM.

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

1 Comment

that's it! thank you very much for your help. a much cleaner code like that and I don't have to access DOM which is not very safe in angular 2.

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.