fbynite
fbynite

Reputation: 2661

datetimepicker and Backbone.View Interaction

This is the code:

var MyModel = Backbone.Model.extend({
    defaults: {std:"",
               pod:""
              }
});

var MyView = Backbone.View.extend({
    tagName:'ul',
    events: {
    'change input' : 'changed',  // When input changes, call changed.
    'hover .std'   : 'timepick', // 
    'mouseout .std': 'doesntwork'
    },
    template:_.template($('#mytemplate').html()),

    initialize: function() {
        this.model.bind('change:pod',this.render,this); // When pod changes, re-render
    },
    timepick: function(e) {
        $('.std').each(function(){
            $.datepicker.setDefaults({dateFormat:'mm-dd'});
            $(this).datetimepicker({timeFormat:'hh:mm',ampm:false});
        });
    },
    doesntwork: function() {
        // Would this.model.set here but mouseout happens when you select date/time values with mouse
    },
    render: function() {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    },
    changed: function(e) {
        var value = $(e.currentTarget).val();       // Get Change value
        var cls = $(e.currentTarget).attr('class'); //Get Class of changed input
        var obj = {}; 
        obj[cls] = value;                       // The model variables match class names
        this.model.set(obj);                        // this.model.set({'std':value})
    }
});

I have a datetimepicker in the UI I'm working on, and having difficulties assigning the value that is selected from the datetimepicker to MyModel.

It appears from using console.log output that 'change input' is triggered when clicking on the DTP and assigns the default value of (MM-DD 00:00). Even when you select a different date/time value than the default, the 'change input' is not triggered again, unless you click on the input box (for a second time), and then the correct value is assigned. Not very user-friendly.

So I had the idea that I would just assign the value on mouseout, which didn't work since mouseout happens when you start to select date/time values. I also tried blur, and that didn't work either.

Where am I going wrong?

Edit: Here is a jsfiddle.net link that illustrates my problem http://jsfiddle.net/9gSUe/1/

Upvotes: 0

Views: 2132

Answers (1)

mu is too short
mu is too short

Reputation: 434755

Looks like you're getting tripped up by jQuery UI's CSS. When you bind a datepicker to an <input>, jQuery UI will add a hasDatepicker class to the <input>. Then you do this:

var cls = $(e.currentTarget).attr('class');

on the <input> and get 'std hasDatepicker' in cls.

There are too many things that will mess around with class so you're better off using something else to identify the property you want to change. You could use an id if there is only one std:

<!-- HTML -->
<input id="std" class="std" ...>

// JavaScript
var cls = e.currentTarget.id;

or the name attribute:

<!-- HTML -->
<input name="std" class="std" ...>

// JavaScript
var cls = $(e.currentTarget).attr('name');

or perhaps even a HTML5 data attribute:

<!-- HTML -->
<input class="std" data-attr="std" ...>

// JavaScript
var cls = $(e.currentTarget).data('attr');

I think the name attribute would be the most natural: http://jsfiddle.net/ambiguous/RRKVJ/

And a couple side issues:

  • Your fiddle was including multiple versions of jQuery and that's generally a bad idea.
  • You don't have to build an object for set, you can say just m.set(attr, value) if you're just setting one attribute.
  • You don't have to $(this.el) in your views, newer Backbones have this.$el already cached.
  • console.log can handle multiple arguments so you can say console.log('Std: ', attrs.std, ' Pod: ', attrs.pod, ' Poa: ', attrs.poa); instead of console.log('Std: ' + attrs.std + ' Pod: ' + attrs.pod + ' Poa: ' + attrs.poa); if you don't want + stringify things behind your back.

Upvotes: 1

Related Questions