Handlebars Field Plugin
Handlebars Field Plugin
bradmacgregor
Posts: 9Questions: 0Answers: 0
in Editor
If you want to create a more complicated custom control with an arbitrary number of inputs or complexity, you might be interested in this plugin which allows you to use a handlebars template to build html with given data.
Here is my plugin for handlebars:
(function ($, DataTable) {
if ( ! DataTable.ext.editorFields ) {
DataTable.ext.editorFields = {};
}
let editor = DataTable.Editor;
DataTable.ext.editorFields.handlebars = {
create: function (conf) {
// A jquery promise, which when resolved provides the template
if (typeof conf.templatePromise !== 'object') {
return undefined;
}
if (typeof conf.get !== 'function') {
return undefined;
}
if (typeof conf.set !== 'function') {
return undefined;
}
//create attachment point
conf._actualId = editor.safeId(conf.id);
conf._container = $('<div>', {id: conf._actualId});
//build the control within a div and return it
conf.templatePromise.done(function (template) {
conf._template = template;
conf._container.html(template(conf.data));
if (typeof conf.init === 'function') {
conf.init(conf._container, conf.data);
}
});
return conf._container;
},
get: function (conf) {
return conf.get(conf._container);
},
set: function (conf, data) {
conf.data = data;
// conf._container.html(conf._template(data));
return conf.set(conf._container, data);
},
input: function (conf) {
return conf._container;
},
update: function (conf, data) {
//be sure to use delegation for events or rebind them in init
conf.data = data;
conf._container.html(conf._template(data));
if (typeof conf.update === 'function') {
conf.update(conf._container, data);
if (typeof conf.init === 'function') {
conf.init(conf._container, data);
}
}
}
};
})(jQuery, jQuery.fn.dataTable);
Here is how you might use it
function getHandlebarTemplate(name, callback) {
let path = '/assets/handlebars/handlebars_templates/' + name + '.hbs';
return $.ajax({
url: path
}).then(function (source) {
let template = Handlebars.compile(source);
if (callback && typeof callback === 'function') callback(template);
return template;
});
}
let fields = editor.fields;
fields.push({
type: 'handlebars',
label: 'My Custom Field',
name: 'customField',
templatePromise: getHandlebarTemplate('myTemplate'),
get: function (control) { return control.find('input.myClass').val(); },
set: function (control, data) { control.find('input.myClass').val(data.test); },
//init is called after template is attached to container (update or create)
init: function (control, data) {
//here is where you might bind events or otherwise modify the control
},
//field update regenerates source from template, sets into container, and calls this then init
update: function (control, data) {
//since editor likes to add this class to all inputs, you might need to do this.
control.find('div.someClass input.form-control').removeClass('form-control');
},
data: {test: 1}
});
You can create a new resolved promise in the case that you want to cache the fetched templates.
This discussion has been closed.
Replies
That's superb, thank you for sharing this with us! I really like handlebars, so its great to see this.
Allan