0

This is a follow-up question to Error | Removing disallowed attribute on SelectElement

I created a table as shown in the figure below:

Table with cloned rows

on-change events are attached to the select dropdowns. For the first row, the event is fired as expected with the dropdown content changes. However, when a new row is added by cloning, the event-listener does not fire. I need some help as to how best to get the attached event to fire.

.html

    <link rel='import' href='../../../../packages/polymer/polymer.html' >

    <link rel='import' href='../../../../packages/paper_elements/paper_checkbox.html' >
    <link rel='import' href='../../../../packages/paper_elements/paper_button.html' >
    <link rel='import' href='../../../../packages/core_elements/core_collapse.html' >
    <link rel='import' href='../../../../packages/core_elements/communication_icons.html' >

    <polymer-element name='phone-form'>
      <template>


        <table id='table-1'>
          <thead>
            <tr>
              <th width='20px'></th>
              <th width='67px'>Type</th>
              <th width='130px'>Provider</th>
            </tr>
          </thead>        

        </table>

        <table id='table'>
          <tbody>
            <tr>
              <td><input name='chk' type='checkbox'></td>
              <td>
                <select id='phone-type'
                  selectedIndex='{{typeSelected}}' 
                  on-change='{{onChangeTypeFired}}'>
                  <option template repeat='{{key in types.keys}}' 
                    value='{{types[key]}}'>{{types[key]}}
                  </option>
                </select>
              </td>

              <td>
                <select id='phone-provider'
                  selectedIndex='{{providerSelected}}' 
                  on-change='{{onChangeProviderFired}}'>
                  <option template repeat='{{key in providers.keys}}' 
                    value='{{providers[key]}}'>{{providers[key]}}
                  </option>
                </select>
              </td> 
            </tr>
          </tbody>
         </table>
          <div>
            <paper-button raised id='add-row-btn' class='margin-8px'     
              on-click='{{addRow}}'>
              Add Row
              <core-icon id='add-row-btn-icon' icon=''></core-icon>
            </paper-button>

            <paper-button raised id='delete-row-btn' class='margin-8px'     
              on-click='{{deleteRow}}'>
              Delete Row
              <core-icon id='delete-row-btn-icon' icon='fa:minus-circle'></core-icon>
            </paper-button>
           </div>
      </template>
      <script type='application/dart' src='phone_form.dart'></script>
    </polymer-element>

.dart

import 'package:polymer/polymer.dart';
import 'dart:html' as dom;

//import 'package:paper_elements/paper_toggle_button.dart' show PaperToggleButton;
import 'package:paper_elements/paper_button.dart' show PaperButton;

//import 'package:epimss_shared/epimss_shared.dart';
//import 'package:epimss_shared/epimss_shared_client.dart' hide DataEvent;

@CustomTag('phone-form')
class PhoneForm extends PolymerElement {

  @observable String icon = '';
  @observable String errorMsg;
  String topic;
  PaperButton addBtn;

  @observable int typeSelected = 0;
  @observable int providerSelected = 0;
  @observable int relationsSelected = 0;

  Map<String, String> types = const <String, String> {
    '': '',
    'Car': 'Car',
    'Direct': 'Direct',
    'Fax': 'Fax',

  };

  Map<String, String> providers = const <String, String> {
    '': '',
    'AT & T': 'AT & T',
    'Cable & Wireless': 'Cable & Wireless',

  };

  PhoneForm.created() : super.created();


  void onSelectTypeFired()
  {

  }

  void onChangeTypeFired( dom.Event e, var detail, dom.SelectElement target)
  {

    print(target.value);
  }

  void onChangeProviderFired( dom.Event e, var detail, dom.SelectElement target)
  {
    print(target.value);
  }


  void onChangeRelationsFired( dom.Event e, var detail, dom.SelectElement target)
  {
    print(target.value);
  }

  void addRow()
  {
    var table = $['table'];
    var rowCount = table.rows.length;
    var row = table.insertRow(rowCount);
    var colCount = table.rows[0].cells.length;



      for(var i = 0; i < colCount; i++ )
      {
        var newcell = row.insertCell(i);

        newcell.children.clear();
        newcell.children.addAll(table.rows[0].cells[i].children.map((c) =>
            c.clone(true)));

        switch(newcell.childNodes[0].runtimeType.toString())
        {
          case 'text':
            newcell.childNodes[0].value = '';
            break;

          case 'checkbox':
            newcell.childNodes[0].checked = false;

            break;

          case 'select':
            newcell.childNodes[0].selectedIndex = 0;
            break;
        }
      }




  }


  void deleteRow()
  {

    var rowsToDelete = [];

    try{
      var table = $['table'];
      var rowCount = table.rows.length;

      for(var i = 0; i < rowCount; i++)
      {
        var row = table.rows[i];
        var chkbox = row.cells[0].childNodes[0];

        if(chkbox != null && chkbox.checked)
        {
          if(rowCount <= 1)
          {
            print('Cannot delete all the rows.');
            break;
          }
          else
          {
            rowsToDelete.add(i);
          }
        }
      }

      rowsToDelete.forEach( (row)
          {
            table.deleteRow(row);
          });
    }
    catch(e)
    {  print(e); }
  }


  @override
  void attached() {
    super.attached();
    topic = this.dataset['topic'];

    addBtn = $['add-btn'];
  }
}

Thanks

Community
  • 1
  • 1
st_clair_clarke
  • 5,453
  • 13
  • 49
  • 75

1 Answers1

1

Clone just doesn't copy event handlers (see for example https://groups.google.com/a/dartlang.org/forum/#!topic/misc/-z_8sVp_uPY)

You could use <template repeat> to generate the rows and cells as mentioned in your previous question. Another way is to use injectBoundHtml (https://www.polymer-project.org/docs/polymer/databinding-advanced.html#boundhtml).

With injectBoundHtml you can't read the HTML from the DOM (innerHtml, or similar) because what you get here is already with bindings interpreted by Polymer. When you store the HTML in a string in Dart code you can add it multiple times and it will interpreted every time when inserted.

If you prefer to have the content in the HTML file you could use a template instead

injectBoundHtml((this.querySelector('#my_template') as TemplateElement)
    .innerHtml);

(haven't actually tried)

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567