utils.editable.js
In-place editing for various form elements such as input, select, textarea, radios, checkboxes, etc...
Dropdown
Code |
Action |
---|---|
new UTILS.Editable({
target: $('#simple-select1'),
type: 'select',
items: [
{ label: 'United States', value: 1 },
{ label: 'Germany', value: 49 },
{ label: 'United Kingdom', value: 44 }
],
value: 49, //Germany
field: 'country_id'
}).enable();
|
Dropdown with field
|
new UTILS.Editable({
target: $('#simple-select2'),
type: 'select',
items: [
{ label: 'United States', value: 1 },
{ label: 'Germany', value: 49 },
{ label: 'United Kingdom', value: 44 }
],
value: 1, //US
params: function(value,Editable){
return {
cid: value
};
}
}).enable();
|
Dropdown with params
|
new UTILS.Editable({
target: $('#simple-select3'),
type: 'select',
items: [
{ label: 'Dogs', value: 1 },
{ label: 'Cats', value: 2 },
{ label: 'Unicorns', value: 3 }
],
value: 3, //Unicorns
field: 'animal_id',
ajax: {
url: '/api/update',
params: {} //any extra params needed to be passed
}
}).enable();
|
Dropdown with ajax
|
new UTILS.Editable({
target: $('#simple-select4'),
type: 'select-selectize',
items: [
{ label: 'Dogs', value: 1 },
{ label: 'Cats', value: 2 },
{ label: 'Unicorns', value: 3 }
],
value: 2, //cats
params: function(value,Editable){
return {
animal_id: value
};
}
}).enable();
|
Dropdown with selectize.js integration
|
new UTILS.Editable({
target: $('#simple-select5'),
type: 'select-multiselect',
items: [
{ label:'Dogs', value:1 },
{ label:'Cats', value:2 },
{ label:'Unicorns', value:3 }
],
value: [2,3], //cats & unicorns
params: function (value, Editable){
return {
animal_ids: JSON.stringify(value) //[1,2]
};
}
}).enable();
|
Multi-Select Dropdown (uses selectize.js)
|
new UTILS.Editable({
target: $('#simple-select6'),
type: 'select-multiselect',
items: [
{ label:'United States', value:1 },
{ label:'Germany', value:86 }
],
value: [1,86], //US & Germany
options: {
search_url: '/api/countries',
content_type: '', //optional - default
//used to format how the search query will be send to the server
//==> api/countries?q={query}
onBeforeSearch: query => {
return {
q: query
};
},
//used to re-format the values that come back from the server into
//a more friendly format that is accepted
onAfterSearch: response => {
let items = _.map(response.coutries, country => {
return {
label: country.country,
value: country.id
}
});
return items;
},
limit: 3 //limit selection to 3 items
},
ajax: {
url: '/api/update',
params: {} //any extra params needed to be passed in the server call
},
params: (value, Editable) => {
return {
country_ids: JSON.stringify(value)
};
}
}).enable();
|
Multi-Select Dropdown (required selectize.js)
|
Input
Code |
Action |
---|---|
var name = new UTILS.Editable({
target: $('#simple-input1a1'),
type: 'input',
value: 'Jack Bauer',
placeholder: '**'
}).enable();
|
Input with placeholder option
|
new UTILS.Editable({
target: $('#simple-input1b1'),
type: 'input',
value: 'John Rambo',
placeholder: '...',
contenteditable: true
}).enable();
|
Input with contenteditable option
|
new UTILS.Editable({
target: $('#simple-input1c1'),
type: 'input-autocomplete',
value: 'Germany',
placeholder: '---',
contenteditable: true,
options: {
search_url: '/api/countries',
onBeforeSearch: query => {
return {
q: query
};
},
onAfterSearch: response => {
let items = _.map(response.coutries, country => {
return {
label: country.country,
value: country.country
}
});
return items;
}
},
ajax: {
url: '/api/update',
params: {} //any extra params needed to be passed
},
params: (value, Editable) => {
return {
country: value
};
}
}).enable();
|
Auto-Complete with contenteditable option where the suggestions are obtained through an ajax call to the server
|
new UTILS.Editable({
target: $('#simple-input1d1'),
type: 'input-autocomplete',
value: 'Mickey Mouse',
placeholder: '---',
contenteditable: true,
items: [
'Mickey Mouse','Donald Duck',
'Oswald the Lucky Rabbit',
'Genie','Goofy','Snow White',
'Minnie Mouse','Scar','Tinker Bell', 'Dory'
],
params: (value, Editable) => {
return {
disney_name: value
};
}
}).enable();
|
Contenteditable Auto-complete with pre-defined suggestions |
let phone_imask;
let phone = new UTILS.Editable({
target: $('#simple-input2'),
type: 'input',
value: '2345678906',
params: (value, Editable) => {
return {
phone: value.replace(/[\(\)\s\-\+]/g, '') //need to remove any non-digit char
};
},
onInputCreate: (Editable) => {
//getting the input field created by UTILS.Editable
var $input = Editable.getInputField();
//assigning phone_imask object (found in utils.js)
phone_imask = UTILS.inputMask.phone($input);
//setting the editable display value
Editable.setDisplayValue(phone_imask.value);
},
onShow: () => {
if (phone_imask)
phone_imask._onChange(); //undocumented method to trigger the formatting manually
},
custom_methods_override: {
name: 'filterValueForDisplay',
method: function(phone){
//if phone_imask is defined lets use that, otherwise whatever was passed in
return (phone_imask) ? phone_imask.value : phone;
}
}
}).enable();
|
Input with imask.js integration
|
let phone_imask;
new UTILS.Editable({
target: $('#simple-input2a'),
type: 'input',
placeholder: '---',
contenteditable: true,
value: '234-567-8906',
params: (value, Editable) => {
return {
phone: value.replace(/[\(\)\s\-\+]/g, '') //need to remove any non-digit char
};
},
onActionTriggered: Editable => {
//getting the input field created by UTILS.Editable
let $target = Editable.getTarget();
if (!$target.data('imask')){
//need to set contenteditable here b/c imask when instantiated needs to know about it
$target.prop('contenteditable',true);
//assigning phone_imask object (found in utils.js)
phone_imask = UTILS.inputMask.phone($target);
//setting the editable display value
Editable.setDisplayValue(phone_imask.value);
}
},
onShow: () => {
if (phone_imask)
phone_imask._onChange(); //undocumented method to trigger the formatting manually
},
custom_methods_override: {
name: 'filterValueForDisplay',
method: function(value){
if (phone_imask)
value = phone_imask.value;
if (!value.length)
value = this.getPlaceholder();
return value;
}
}
}).enable();
|
Input with contenteditable option and imask.js validation
|
Textarea
Code |
Action |
---|---|
var name = new UTILS.Editable({
target: $('#simple-textarea1a'),
type: 'textarea',
value: 'Some text that goes here...'
}).enable();
|
Textarea
|
new UTILS.Editable({
target: $('#simple-textarea1b'),
type: 'textarea',
value: `Lorem ipsum dolor sit amet, qui ex appetere invidunt insolens, ad
numquam vocibus sed. Et iisque assueverit nam. Choro referrentur definitiones quo et.
Et labore audiam legimus nec. Tollit habemus maluisset et eum, ea usu nusquam mentitum.
`,
contenteditable: true
}).enable();
|
Textarea contenteditable |
new UTILS.Editable({
target: $('#simple-textarea2'),
type: 'textarea-wysiwyg',
value: 'Some text that goes here...'
}).enable();
|
Textarea with summernote.js integration
|
Date
Code |
Action |
---|---|
var date = new UTILS.Editable({
target: $('#simple-input3'),
type: 'date',
value: '',
field: 'start_date',
options: {
//options passed down to bootstrap-datepicker.js
}
}).enable();
|
Input with bootstrap-datepicker.js integration
|
new UTILS.Editable({
target: $('#simple-input4a'),
type: 'date',
value: '',
options: {
startDate: null //open to any date selection
},
ajax: {
url: '/api/update'
},
params: function(date,Editable){
return {
start_date: date
};
}
}).enable();
|
Input without date restrictions |
new UTILS.Editable({
target: $('#simple-input4b'),
type: 'date-range',
value: '09/28/2023 - 10/12/2023',
options: {
date_format: 'MM/DD/YYYY',
separator: ' - '
}
}).enable();
|
Originally inspired by daterangepicker.js by Chunlong Liu, but unfortunately some needed features such as months-only/years-only selection were not available. That prompted the development of utils.daterange.js utility. A few examples below
|
Checkbox
Code |
Action |
---|---|
var checkbox = new UTILS.Editable({
target: $('#simple-input5'),
type: 'checkbox',
params: (value) => {
return {
setting: 'isAutosave', //name of the DB column
is_checked: value //==> true/false
};
},
value: true, //initial value (checked)
options: {
desc: 'Auto-Save'
}
}).enable();
|
Checkbox
|
//using shards to style the checkboxes
var checkbox1a = new UTILS.Editable({
target: $('#simple-input6a'),
type: 'checkbox-switch',
params: (value) => {
return {
setting: 'isPopulate',
is_checked: value
};
},
value: false, //initial value (unchecked)
options: {
desc: 'Auto-Populate' //@desc is the label text next to the checkbox
}
}).enable();
var checkbox1b = new UTILS.Editable({
target: $('#simple-input6b'),
type: 'checkbox-switch',
params: (value) => {
return {
setting: 'isAutoUpdate',
is_checked: value
};
},
value: true, //initial value (checked)
options: {
desc: 'Auto-Update' //@desc is the label text next to the checkbox
}
}).enable();
|
Checkbox with shards integration
|
Radio
Code |
Action |
---|---|
var radio = new UTILS.Editable({
target: $('#simple-input7'),
type: 'radio',
field: 'button_color',
value: '#fff',
items: [
{ label: 'Red', value: '#f00' },
{ label: 'White', value: '#fff' },
{ label: 'Black', value: '#000' }
],
//if no ajax specified we can also pass the value into a custom function
onAfterSave: (Editable, response) => {
console.log(response); //=> {errors: [], button_color: "#000", direction: "top"}
}
}).enable();
|
Radio
|
API
Option |
Required |
Default |
Description |
---|---|---|---|
target | required | $('body') |
DOM that will be replaced by the Editable element |
params | optional | null |
Params that will be passed in the ajax call along side the value of the editable parameter. field: 'animal_id',
params: { code_id:123, cat_id:9 }
//passed to server --> { code_id:123, cat_id:9, animal_id:25 } //animal_id is appended
Another way is to assign it a function field: 'animal_id',
params: (value) => {
return {
code_id: 123,
cat_id: 9,
lion_id: value //holds the updated value
};
}
//passed to server --> { code_id:123, cat_id:9, lion_id:25 }
//@field is ignored in this case
|
type | required |
input
|
|
options | optional | {} |
Native options that are passed down to the underlying libs used by the process, such as bootstrap-datepicker.js {
container: $('body'),
orientation: 'bottom',
autoclose: false,
format: 'MM/DD/YYYY',
startDate: moment().add(1,'day').toDate(),
todayHighlight: true
}
|
css | optional | '' |
Extra css classes that will be added to the editable elements for further styling |
tabbing | optional | false |
If enabled, by hitting the TAB will make the next-in-line element editable |
lazyload | optional | false |
If enabled, the element will be activated on user click and the _onActionTriggered will have to be triggered manually Note, this is mainly used for performance enhencement when you have 100+ editable elements and you want to enable them through direct user action var $span = $('');
//editable options that will be used when activated
var editable_options = {
target: $span,
type: 'input',
tabbing: true,
lazyload: true,
field: 'animal_id',
value: 123
};
$span.addClass('xedit editable-target').data('editable-options',editable_options).on('click',function(event){
event.preventDefault();
//getting options
var options = $(event.target).data('editable-options'));
//activating
new UTILS.Editable(options).enable()._onActionTriggered();
});
|
toggle | optional | click |
Events that trigger the editable activation ( click, dblclick, etc... ) |
items | optional | [] |
Even though this is marked as optional it is required for certain types such as select and radio |
container | optional | $('body') |
Specifies the DOM where editable HTML will be appended to |
value | optional | '' |
The value of the editable. Note, the value and display value are two different things |
placeholder | optional | -- |
Specifies the character that will be displayed in case the value is empty placeholder: '**' //if empty, ** will be shown
|
contenteditable | optional | false |
Makes an HTML element be editable from within the HTML |
Methods
Method |
Default |
Repeat |
Description |
---|---|---|---|
onInputCreate | null |
ONE-TIME | Triggered when the editable input element is created |
onShow | null |
REPEAT | Triggered every time when the editable is activated |
onHide | null |
REPEAT | Triggered every time when the editable is de-activated |
onCancel | null |
REPEAT | Triggered when the user decides not to make any changes by either clicking off or hitting the ESC key |
onActionTriggered | null |
REPEAT | Triggered every time when the editable is activated, but before it is shown |
onBeforeSave | null |
REPEAT | Triggered every time before the value is saved/ajax call made |
onAfterSave | null |
REPEAT | Triggered every time after the value is saved/ajax call made |
onSaveError | null |
REPEAT | Triggered every time if an error occurs while saving the value |