javascriptcheckboxember.jsember-components

Ember JS component multiple checkboxes selection to array


I have an Ember frontend and i want to create a form with multiple checkboxes and somehow , either populate a collection of checked items upon check , or gather the selected checkboxes upon form submission

this is how i call my component

{{scheduled-report-form item=model buttonLabel=buttonLabel action='saveScheduledReport'}}

this is what happens in the template

                  {{#each item.vessels as |vessel|}}
                    <div>
                      <label class="custom-checkbox form-control-inline">
                        {{input type='checkbox' change=(action 'checkboxChangedVoice' item.scheduledReport vessel checkedVoice) selected=checkedVoice }}
                        <span>Voice</span>
                      </label>
                      <label class="custom-checkbox form-control-inline">
                        {{input type='checkbox' change=(action 'checkboxChangedData' item.scheduledReport vessel checkedData) checked=checkedData}}
                        <span>Data</span>
                      </label>
                      <span>{{vessel.name}}</span>
                    </div>
                  {{/each}}
                  .
                  .
                  .
                  <button type="submit" class="btn btn-main" {{action 'buttonClicked' item.scheduledReport item.user item.vessels }}>Generate report {{buttonLabel}}</button>

The checkboxes should be 2 for each model instance so for example

Data Voice 
[]   []    Name1
[]   []    Name2

The way I'm trying to tackle it doesn't seem to work at the moment

So in my component:

import Ember from 'ember';

export default Ember.Component.extend({
  optionsData: [],
  optionsVoice: [],
  srOptions: [],
  checkedVoice:false,
  checkedData:false,

  didInsertElemet() {
    this.selectedItems = [];
  },

  actions: {

    checkboxChangedVoice(options, vessel, paramValue) {
      console.log(paramValue);
      console.log(this.get('checkedVoice'));
      //this populates an array with the checked boxes
      this.get('optionsVoice').push(vessel);
      console.log(this.get('optionsVoice'))
    },
    checkboxChangedData(options, vessel,paramValue) {
      console.log(paramValue);
      console.log(this.get('checkedData'));
      //this populates an array with the checked boxes
      this.get('optionsData').push(vessel);
      console.log(this.get('optionsData'))
    },
    buttonClicked(paramsScheduledReport, paramsUser, srOptions) {
      srOptions = this.get('srOptions')
      this.sendAction('action', paramsScheduledReport, paramsUser, srOptions);
    }
  }
});

this is also the last action in the controller, in case someone finds it useful

import Ember from 'ember';

export default Ember.Controller.extend({
 actions: {
        saveScheduledReport(newScheduledReport, user , vessel) {
            var controller = this;

   console.log(vessel.toArray())
            newScheduledReport.set('user', user);
   newScheduledReport.set('vessels',vessel);
   newScheduledReport.set('srOptions',vessel);
   //TODO: Add recipients array from form!
   newScheduledReport.set('reportRecipients',[])
            newScheduledReport.save().then(function() {
                controller.transitionToRoute('/');
            });
        },
    }
});

Now what happens in the component , when i click on a checkbox:

the console.log(paramValue) will always answer undefined and the console.log(this.get('checkedVoice') will always answer false

At the moment you might notice that the component is just appending values to the array , i was trying to implement the 'toggling' feature but i can't get access to the checked (true/false) value.

If you think my implementation is completely off please do suggest any other viable solution.

thank you guys.


Solution

  • If you are dealing with ember-data you could simply bind the checkbox to the value of each vessels "data" or "voice" checkbox (e.g. {{input type='checkbox' checked=vessel.checkedVoice}}) and then save the model when you're ready.

    But for your specific request on tracking it in an array. It would be simpler to create an object array of each vessel. Then on form submission you could submit an array of objects based on a filterBy.

    Example implementation:

    // scheduled-report-form.js
    import Ember from 'ember';
    
    export default Ember.Component.extend({
      init() {
        this._super(...arguments);
    
        this.set('tempVessels', []);
        this.get('item.vessels').forEach((vessel) => {
          this.get('tempVessels').pushObject(Ember.Object.create({checkboxVoice: false, checkboxData: false, vessel: vessel}));
        });
      },
      actions: {
        buttonClicked() {
          console.log('Voice array:');
          console.log(this.get('tempVessels').filterBy('checkboxVoice', true));
          console.log('Data array:');
          console.log(this.get('tempVessels').filterBy('checkboxData', true));
        }
      }
    });
    
    // scheduled-report-form.hbs
    {{#each tempVessels as |vessel|}}
      // The sub-component isn't neccessary, just my design preference.
      {{checkboxes-component vessel=vessel}}
    {{/each}}
    .
    .
    .
    <button type="submit" class="btn btn-main" {{action 'buttonClicked'}}>Generate report {{buttonLabel}}</button>
    
    // checkboxes-component.hbs
    <label class="custom-checkbox form-control-inline">
      {{input type='checkbox' checked=vessel.checkboxVoice}}
      <span>Voice</span> = {{vessel.checkboxVoice}}
    </label>
    <label class="custom-checkbox form-control-inline">
      {{input type='checkbox' checked=vessel.checkboxData}}
      <span>Data</span> = {{vessel.checkboxData}}
    </label>
    <span>{{vessel.name}}</span>