I am looking for a solution to bind an object attribute that contains an array of string (representing an enum on the server) to a list of checkboxes. The binding should be two-way.
On the server, we have some enum defintion, e.g., Role with the values "ADMIN", "GUEST", "USER". A user object may have several of thus roles, thus the user object in Ember is of the form
App.User = Ember.Object.create({
roles: ["USER", "ADMIN"]
});
In the user administration, there should be a group of checkboxes. One checkbox per role. So, it is possible to select none, all, or several.
I know that there is the Ember.Checkbox
view that can be used for this. What I am looking for would be a easy and generic view to handle any kind of enums as mentioned above.
Thus, the questions are:
Thanks in advance. // ph
A generic way to handle a two way binding between an Ember object and Checkboxes can be implemented using plain Ember.js without the need of any plugins if you are willing to sync the enums on the server and the client manually (using AJAX or WebSockets). Note that Ember can update the list of options with Checkbox automatically after a sync.
So henceforth, I will assume that you have am enum with roles as an Ember Array:
App.Roles = [ "USER", "ADMIN", "GUEST" ];
Then we will show the options available to the user in a CollectionView like this (the template is given below).
OptionsView = Em.CollectionView.extend({
contentBinding: 'App.Roles', // Show a list of _all_ available roles
userBinding: 'App.User', // This points to the active user
tagName: 'ul', // Shown as a <ul>
itemViewClass: Em.View.extend({
userBinding: 'parentView.user', // For convenience
templateName: 'user-roles' // Defined later
})
});
The template for each option is:
<script data-template-name="user-roles" type="text/x-handlebars">
<label> {{view App.RoleCheckbox
contentBinding="view.content"}}
{{view.content}}
</label>
</script>
Note that the use of <label>
tag makes sure that the Checkbox's click
event is fired on clicking anywhere on the tag.
Finally the App.RoleCheckbox
is an extension of the Ember.Checkbox
class which handles the checked
property and click
event to toggle the role:
App.RoleCheckbox = Em.Checkbox.extend({
userRolesBinding: 'parentView.user.roles', // Points to the roles of the user
checked: function () {
var userRoles = this.get('userRoles');
return userRoles.contains(this.get('content'));
}.property('content', 'userRoles.@each'),
click: function (evt) {
var isPresent = this.get('checked'),
userRoles = this.get('userRoles'),
role = this.get('content');
if (!isPresent) {
userRoles.pushObject(role);
} else {
userRoles.removeObject(role);
}
}
});
An working example of this is: http://jsfiddle.net/BLQBf/ (Look at the console to see the log messages)
Note that this is not completely Ember-esque, since the View is doing part of the job meant for the controller
. Ideally, the click
event would call a function on the RoleCheckboxController
which would make changes to the User
object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With