20

I am trying to load country list and on select the country i just want to call an alert , but somehow I am not able to catch change event for the select box.

Can somebody please help me?

here is the code with the view, model and collection part with template script in html

    <!DOCTYPE html>
<html>
<head>
    <title>Backbone</title>
</head>
<body>
    <script type="text/template" id="country_select_template">
        <select id="country-selector">
             <% _.each(countries, function(country) {%>
                <option value="<%= country.fipsCode %>"><%= country.countryName %></option>
            <% }); %>
        </select>
    </script>
    <div id="country_select_container">
        Loading country...
    </div>

    <!--div>
    <select id="state" disabled=true>
        <option value="NAN">Select State</option>                    
    </select>
    </div>
    <div>
    <select id="city" disabled=true>
        <option value="NAN">Select City</option>                    
    </select>
    </div-->
</div>
<ul id="names-list">
</ul>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js"></script>
<script>

Country = Backbone.Model.extend();

CountryList = Backbone.Collection.extend({
    model : Country,
    url : "https://dl.dropbox.com/u/18190667/countryList.json",
    parse : function(response) {
        return response.geonames;
    }
});

Countries = new CountryList();

CountryView = Backbone.View.extend({
    events: {
        "change #country-selector": "countrySelected"
    },

    countrySelected: function(){
        alert("You can procceed!!!");
    },

    countrySelected  :function(){
        alert("Procceed");
    },

    initialize: function(){
        var countries = [];
        var self = this;
        Countries.fetch({
            success: function(){
                self.render();
            }
        });
    },

    render: function(){
        var self = this;
        var country_select_template = _.template($("#country_select_template").html(), {
            countries: Countries.toJSON(),
        });
        $('#country_select_container').html(country_select_template);
        return this;
    }
});
var view = new CountryView();
</script>

</body>
</html>
Urvish
  • 1,758
  • 4
  • 16
  • 23

2 Answers2

37

Try like this:

CountryView = Backbone.View.extend({
    el: $("#country_select_container"),
    template: _.template($("#country_select_template").html()),
    events: {
        "change #country-selector": "countrySelected"
    },

    countrySelected: function(){
        alert("You can procceed!!!");
    },

    initialize: function(){
        var self = this;
        Countries.fetch({
            success: function(){
                self.render();
            }
        });
    },

    render: function(){
        this.$el.html(
           this.template({countries: Countries.toJSON()})
        );
        return this;
    }
});

For more info check here, and hopefully this will be helpful :)

Community
  • 1
  • 1
mouad
  • 67,571
  • 18
  • 114
  • 106
  • Uncaught TypeError: Cannot call method 'html' of undefined @this.$el.html statement? any idea? but $(this.el).html(...) worked for me – Urvish Jun 08 '12 at 12:29
  • @Urvish: I guess you're using an old version of backbone.js, the new version 0.9 have a ``this.$el`` shortcut for ``$(this.el)``. Check here (http://documentcloud.github.com/backbone/#upgrading) – mouad Jun 08 '12 at 13:10
  • `el` is supposed to be a DOM object not a jQuery one. `el: document.getElementById('country_select_container')` or `el: $('#country_select_container').get(0)` – Charles-Édouard Coste Aug 29 '13 at 09:03
  • Your answer is not good, you shoul had put in the alert the newly selected value." – Yahya Yahyaoui Nov 28 '17 at 14:19
0

You must bind the view to an existing DOM element. Try this:

CountryView = Backbone.View.extend({

    el:'#country-selector',

    events: {
        "change #country-selector": "countrySelected"
    },

...

Or in your case you can pass the el parameter as an argument to the constructor:

new CountryView({el:'#country-selector'});

If you don't bind el to an existing DOM element, backbone will bind it to a div by default. Thus your events will be fired looking for div > #country-selector and won't match since no such element exists.

PhD
  • 11,202
  • 14
  • 64
  • 112
  • i tried new CountryView({el:'#country-selector'}); but still not able to alert? any other suggestion? – Urvish Jun 08 '12 at 12:15