Thunder Rabbit
Thunder Rabbit

Reputation: 5449

backbone render not rendering select tags

I've got a simple div into which I'd like backbone to render a select box and options from my server.

The options seem to render just fine, but the select box does not. I'm sure it's a simple tweak, but can't seem to find it.

I created a simplified fiddle for it: http://jsfiddle.net/thunderrabbit/BNZY3/

The HTML

<div id="where_fields"></div>

The script I'm using uses fetch() to get the data. The Fiddle above hardcodes the data, but the issue is the same.

(function($){
    var Field = Backbone.Model.extend();

    var UnitFields = Backbone.Collection.extend({
        url: '/<?php echo CONFIG_ADMIN_DIR; ?>/api/fieldnames/units',
        model: Field
    });

    var BuildingFields = Backbone.Collection.extend({
        url: '/<?php echo CONFIG_ADMIN_DIR; ?>/api/fieldnames/buildings',
        model: Field
    });

    var FieldView = Backbone.View.extend({
        tagName: "option",

        initialize: function(){
            _.bindAll(this, 'render');
        },
        events: {
            "click":"clicked"
        },
        clicked: function(e) {
            var data_type = this.model.get("DATA_TYPE");
            if(data_type == "varchar") {
                console.log("it's a varchar");
            }
            if(data_type == "int") {
                console.log("it's an int");
            }

        },
        render: function(){
            $(this.el).attr('value', this.model.get('COLUMN_NAME')).html(this.model.get('display_name'));
            return this;
        }
    });

    var FieldsView = Backbone.View.extend({
        tagName: "select",
        el: $('#where_fields'),
        initialize: function(){
            _.bindAll(this, 'render', 'renderItem');
            this.collection.bind('reset', this.render);
        },
        renderItem: function(model) {
            console.log('rendr item');
            var fieldView = new FieldView({model:model});
            fieldView.render();
            $(this.el).append(fieldView.el);
        },
        render: function(){
            console.log('rendr');
            this.collection.each(this.renderItem);
            return this;
        }
    });

    var units_fields = new UnitFields();
    var buildings_fields = new BuildingFields();

    var unitsView = new FieldsView({collection: units_fields});
    var buildingsView = new FieldsView({collection: buildings_fields});

    units_fields.fetch();
    buildings_fields.fetch();

})(jQuery);

Why is my backbone script not rendering the select tags?

Upvotes: 1

Views: 970

Answers (1)

Peter Lyons
Peter Lyons

Reputation: 146084

You have both tagName and el attributes in your FieldsView class. You don't need both. Use tagName if you want to render a view detached from the DOM and then backbone will use that tag instead of the default of div. However, in your render(), you don't ever actually get a select tag involved. $(this.el) is your #where_fields div and you just append fieldView.el, which is an option element. That's why there is no select element. Some quick tips:

  • use this.$el as a more efficient shorthand for $(this.el)
  • It's preferable to keep your view loosely coupled from the DOM, so el: $('#where_fields') is not as clean a design as rendering an element detached from the DOM and letting other code decide where exactly in the existing DOM it should be attached.
  • So you should remove your el properly, set tagName to select if you like, then your render() method will be doing what you want with is appending options to a select tag, then move the actual code to append your view's rendered el to the #where_fields div out of the view into your router perhaps.

Upvotes: 3

Related Questions