Vítor Martins
Vítor Martins

Reputation: 1440

RadioButtonList in Ember, Binding a model property to the selected value

I've reading and trying some codes but nothing has been working like I want i to... this is the code I have right now.

index.html:

<div class="form-group">
    <label for="accommodation">3.2. ACCOMMODATION (*)</label> <br />
    <div>
        {{view Ember.RadioButton name="accommodation" valueBinding='accommodation' selectionBinding="isSelected" value="Not Required"}}
        Not Required 
    </div> <br />
    <div>
        {{view Ember.RadioButton name="accommodation" valueBinding='accommodation' selectionBinding="isSelected" value="Required"}}
        Required 
    </div> 
</div>

View radiobutton.js:

Ember.RadioButton = Ember.View.extend({
    tagName: "input",
    type: "radio",
    attributeBindings: ["name", "type", "value", "checked:checked:"],
    click: function () {
        this.set("selection", this.$().val())
    },
    checked: function () {
        return this.get("value") == this.get("selection");

        if (this.get("selection") == "Required") {
            $('#panelAccommodation').style.display = "block";
        }

        if (this.get("selection") == "Not Required") {
            $('#panelAccommodation').style.display = "none";
        }

    }.property()

What I want from these RadioButtonLists is to be able to retrieve the value of the selected item so I can send it as a POST to a api and to use the selected value to hide/show a div dependidng on the selected value. Any ideas on how to do this?

EDIT:

I'm trying andrusieczko's code and so far I have this:

radio.js :

App.RadioView = Ember.View.extend({
    tagName: 'input',
    type: 'radio',
    attributeBindings: ['type', 'htmlChecked:checked', 'value', 'name'],

    htmlChecked: function () {
        return this.get('value') === this.get('checked');
    }.property('value', 'checked'),

    change: function () {
        this.set('checked', this.get('value'));
    },

    _updateElementValue: function () {
        Ember.run.next(this, function () {
            this.$().prop('checked', this.get('htmlChecked'));
        });
    }.observes('htmlChecked')
});

Ember.Handlebars.helper('radio-button', App.RadioView);

controller:

App.EventsNewController = Ember.ObjectController.extend({

    acRequired: 'Required',
    acNotRequired: 'Not Required',

    accommodation: null,

Index.html :

<div class="form-group">
     <label for="accommodation">3.2. ACCOMMODATION (*)</label> <br />
     <div>
         {{radio-button value=acRequired checked=accommodation}}
         Not Required 
     </div>
     <div>
         {{radio-button value=acNotRequired checked=accommodation}}
         Required 
     </div> 
</div>

still not sending the selected value on the POST request.

EDIT 2:

I've written some code that in all others aspects is behaving like I want it to but it's still not binding the selected value to the property I want it to.

View radio.js:

Ember.Radio = Ember.View.extend({
    tagName: "input",
    type: "radio",
    attributeBindings: ["name", "type", "value", "checked:checked:"],
    click: function () {
        this.set("selection", this.$().val())

        if(this.get("selection") === "acRequired") {
            $('#panelAccommodation').css("display", "block");
            this.set("selection", "Required");
            selectionBinding: "App.event.accommodation"
        }
        if (this.get("selection") === "acNotRequired") {
            $('#panelAccommodation').css("display", "none");
            this.set("selection", "Not Required");
            selectionBinding: "App.event.accommodation"
        }
        if (this.get("selection") === "flRequired") {
            $('#panelFlight').css("display", "block");
            this.set("selection", "Required");
            selectionBinding: "App.event.flight"
        }
        if (this.get("selection") === "flNotRequired") {
            $('#panelFlight').css("display", "none");
            this.set("selection", "Not Required");
            selectionBinding: "App.event.flight"
        }
    },

    checked: function () {
        return this.get("value") == this.get("selection");
    }.property()
});

Index.html :

    <!-- Accommodation - RadioButtonList -->
<div class="form-group">
     <label for="accommodation">3.2. ACCOMMODATION (*)</label> <br />
     <div>
          {{view Ember.Radio name="accommodation" selectionBinding='accommodation' value="acNotRequired"}}
          Not Required
     </div>
     <div>
          {{view Ember.Radio name="accommodation" selectionBinding='accommodation' value="acRequired"}}
          Required
     </div>
</div>

controller new.js :

App.EventsNewController = Ember.ObjectController.extend({

    accommodation: "Not Required",
    flight: "Not Required",

    actions: {
        save: function () {
            var self = this;
            this.get('model').set('status', 'Created');
            this.get('model').save().then(function () {
                self.transitionToRoute('events.table');
            });
        }
    }
});

PS: I'm using Ember version 1.6.1

Upvotes: 1

Views: 940

Answers (2)

andrusieczko
andrusieczko

Reputation: 2824

If you're not using either Ember App Kit or ember-cli, then all you have to do is:

App.RadioView = Ember.View.extend({
  tagName: 'input',
  type: 'radio',
  attributeBindings: ['type', 'htmlChecked:checked', 'value', 'name'],

  htmlChecked: function() {
    return this.get('value') === this.get('checked');
  }.property('value', 'checked'),

  change: function() {
    this.set('checked', this.get('value'));
  },

  _updateElementValue: function() {
    Ember.run.next(this, function() {
      this.$().prop('checked', this.get('htmlChecked'));
    });
  }.observes('htmlChecked')
});

Ember.Handlebars.helper('radio-button', App.RadioView);

Then, in your Controller:

App.IndexController = Ember.Controller.extend({
  country1: 'USA',
  country2: 'Singapore',
  country3: 'Poland',

  country: null,
});

and in your template:

{{radio-button value=country1 checked=country}}
{{radio-button value=country2 checked=country}}
{{radio-button value=country3 checked=country}}

and you can listen to the properties you passed to the helper and based on that trigger other actions.

And it can be easily used along with {{each}} :)

Does it help?

The working example (Ember 1.6.1, ember-data 1.0.0-beta.9): https://github.com/andrusieczko/radiobutton-example.git

Disclaimer: I'm not the author of the code, I took it from somewhere some time ago.

Upvotes: 1

Jamie Chong
Jamie Chong

Reputation: 842

If you can handle not using HTML <input> elements, try using this component that I wrote.

Note that I'm using Ember 1.10 and Ember-CLI.

my-template.js (controller)

import Ember from 'ember';
export default Ember.Controller.extend({

    options: [Ember.Object.create({
        name: "Required",
        value: "1",
    }), Ember.Object.create({
        name: "Not Required",
        value: "0",
    })],

    actions: {
        optionChanged: function(option) {
            // option.value will either be 1 or 0 in this case.
        }
    }
});

my-template.hbs

{{#mutex-button-set key="value" default=options.firstObject stateChanged="optionChanged" buttons=options as |button|}}
    <div>{{button.name}}</div>
{{/mutex-button-set}}   

mutex-button-set.hbs

{{#each button in buttons}}
    <div {{bind-attr class=":mutex-button button.selected:selected"}} {{action "setSelected" button}}>
        {{yield button}}
    </div>  
{{/each}}

mutex-button-set.js

import Ember from 'ember';
export default Ember.Component.extend({
    classNames: ['mutex-button-set'],

    actions: {
        setSelected: function(obj) {
            var key = this.get("key");

            this.get("buttons").forEach(function(button) {
                Ember.set(button, "selected", obj && (button.get(key) === obj.get(key)));
            });

            if (obj) {
                this.sendAction('stateChanged', obj);   
            }
        }
    },

    didInsertElement: function() {
        this.send("setSelected", this.get("default"));
    }

});

HTML Generated

<div id="ember554" class="ember-view mutex-button-set">
    <div data-ember-action="559" class="mutex-button selected">
        <div>Required</div>
    </div>  
    <div data-ember-action="563" class="mutex-button ">
        <div>Not Required</div>
    </div>  
</div>

Upvotes: 0

Related Questions