Reputation: 355
I'm currently using the jquery datetimepicker inside a backbone view that will have a model tied to it for each datepicker control I use.
I'm not sure what the best way to implement this but there is huge rendering slowness issues if I have more than a few datetimepicker controls in my CompositeView.
Here is my current setup, ideas on ways to make this faster or change would be appreciated.
There looks to be a bottle neck in the JQuery _updateDatePicker code as well. empty() eventually calls $.cleanData which is a choke.
/* Generate the date picker content. */
_updateDatepicker: function(inst) {
this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
instActive = inst; // for delegate hover events
inst.dpDiv.empty().append(this._generateHTML(inst));
Underscore template code:
<div style="float:left;">
<div class="lbltext" id="startdate-datepicker"></div>
</div>
CompositeView onRender:
onRender: function () {
// Add datetimepicker
var dtp_mod = Page.Module("datetimepicker");
this.dateTimePickerDailyStart = new dtp_mod.View({
model: new dtp_mod.Model({
CurrentDate: null,
LabelText: "Start Date",
showTimepicker: false
}),
el: this.ui.dailystartdatepicker[0]
}).on("change.datetimepicker", this._onDateChange, this);
Upvotes: 0
Views: 2233
Reputation: 752
Alright, took a stab at this. See fiddle: http://jsfiddle.net/Cardiff/SbDcZ/.
Demo notes
It will show two identical views which can be reloaded using a button. This is to demonstrate the onClose
functionality of the view. It also shows that the views are synced and display the latest set value.
Datetimepicker specific code
// Itemview (line 16 in jsfiddle)
var movieItemView = Marionette.ItemView.extend({
tagName: "li",
className: 'listItem',
template: "#movie-list-item",
ui: {
dateInput: '.datetimepicker'
},
onShow: function () {
// Invoke the datetimepicker plugin
this.ui.dateInput.datetimepicker({
// Lazy init to prevent a lot of instances right away
lazyInit: true,
// Proxy the callback function to retain view scope
onChangeDateTime: $.proxy(this.changeDate, this)
});
},
changeDate: function (dp, $input) {
this.model.set('date', $input.val());
},
onClose: function () {
// Destroy the datetimepicker plugin
this.ui.dateInput.datetimepicker('destroy');
},
modelEvents: {
'change:date': 'updateDate'
},
updateDate: function () {
// Check if we need to update the date.
var modelDate = this.model.get('date');
if (modelDate != this.ui.dateInput.val()) {
this.ui.dateInput.val(modelDate);
}
}
});
Implementation notes
ui
attribute to provide easy access. onShow
method before instantiating the plugin. This assumes the datetimepicker plugin is dom-dependent. If you do this in the onRender
function, dom-dependent plugins may not work as intended. lazyInit
option which is supposed to be beneficial in long(er) lists. onChangeDateTime
function to stay in the view scope and provide easy access to the view's model. updateDate
first check if we really need to update the value in this view. In this case this check is not really necessary, however if you're using plugins which require re-initialization on value changes or any other heavy actions it may be beneficial to check if you really need to do this.Upvotes: 1