Search code examples
ember.jshandlebars.js

how to manage multiple checkboxes in ember?


I'm still trying to figure out how ember works and I want to have more info on managing multiple checkboxes in ember..
here's what I tried to do: http://jsbin.com/datojebu/2/edit
as you can see all checkboxes get selected and the checked function doesn't get called
what's the correct way of doing this?


Solution

  • Okay further to your additional questions, I've basically finished your app for you:

    http://jsbin.com/datojebu/11/edit

    App = Ember.Application.create();
    App.ApplicationAdapter = DS.RESTAdapter.extend({
        host: '/api',
        namespace: 'fr'
    });
    
    /* router */
    App.Router.map(function() {
      this.resource('animes');
    });
    App.AnimesRoute = Ember.Route.extend({
      model: function() {
        return this.store.find('anime');
      },
      setupController: function(controller, model) {
        this._super();
        this.store.find('genre').then(function(genres) {
          controller.set('genres', genres);
        });
        controller.set('model', model);
      }
    });
    
    /* models */
    var model = DS.Model,
        attr = DS.attr,
        hasMany = DS.hasMany;
    
    App.Genre = model.extend({
        animes: hasMany('anime', {async: true}),
        nom: attr('string')
    });
    App.Anime = model.extend({
        nom: attr('string'),
        parution: attr('number'),
        synopsis: attr('string'),
        likes: attr('number'),
        auteur: attr('string'),
    
        genres: hasMany('genre', {async: true})
    });
    /* controllers */
    App.AnimesController = Em.ArrayController.extend({
      genres: Em.A([]),
      selectedGenreIds: Em.A([]), // a set of ids
      selectedGenres: function() {
        var genres = this.get('genres'),
            selectedGenreIds = this.get('selectedGenreIds');
        return genres.filter(function(genre) {
          return selectedGenreIds.contains(genre.get('id'));
        });
      }.property('selectedGenreIds.@each', 'genres.@each'),
      selectedAnimes: function() {
        var allAnimes = this.get('model'),
            selectedGenres = this.get('selectedGenres'),
            filteredAnimes;
        // for an anime to be shown, it has to have at
        // least one of its genres selected
        filteredAnimes = allAnimes.filter(function(anime) {
          return anime.get('genres').any(function(animeGenre) {
            return selectedGenres.contains(animeGenre);
          });
        });
        return filteredAnimes;
      }.property('model.@each', 'selectedGenres.@each', 'genres.@each')
    });
    App.GenreController = Em.ObjectController.extend({
      needs: ['animes'],
      isChecked: function(key, value) {
        if(arguments.length > 1) {
          // setter
          var selectedGenreIds = this.get('controllers.animes.selectedGenreIds'),
              thisId = this.get('id');
          if(!selectedGenreIds.contains(thisId) && value) {
            selectedGenreIds.addObject(thisId);
          } else {
            selectedGenreIds.removeObject(thisId);
          }
        }
        // always return the value for the getter and the setter
          return value;
      }.property('controllers.animes.selectedGenreIds')
    });
    
    /* mockjax */
    var animes = [
        {
            id: 1,
            nom: 'Blah',
            parution: 2014,
            genres: [1, 3],
            synopsis: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore, eveniet, ab pariatur omnis dolor sunt alias atque voluptate neque reiciendis maiores impedit quibusdam perferendis optio ratione expedita adipisci et. Cupiditate!',
            likes: 206,
            auteur: 'Moi :p'
        }
    ],
    genres = [
        {
            id: 1,
            nom: 'action',
            animes: []
        },
        {
            id: 2,
            nom: 'magie',
            animes: [1]
        },
        {
            id: 3,
            nom: 'amour et amitier',
            animes: []
        },
        {
            id: 4,
            nom: 'aventures',
            animes: [1]
        }
    ];
    $.mockjax({
      url: '/api/fr/animes',
      responseTime: 750,
      responseText: {
        'animes': animes
      }
    });
    $.mockjax({
      url: '/api/fr/genres',
      responseTime: 750,
      responseText: {
        'genres': genres
      }
    });