Skip to content

Instantly share code, notes, and snippets.

@ssire
Created November 10, 2013 11:18
Show Gist options
  • Save ssire/7396964 to your computer and use it in GitHub Desktop.
Save ssire/7396964 to your computer and use it in GitHub Desktop.
/**
* AXEL Plugin
*
* Sample input element transformed into an AXEL plugin (called "date" in this example) but this is a plain vanilla plugin
*
* The purpose is to have an example to brainstorm on AXEL plugin API and keyboard manager API
*
* Synopsis :
* - <xt:use types="date">default value</xt:use>
*
*/
(function ($axel) {
var _DateField = {
////////////////////////
// Life cycle methods //
////////////////////////
onGenerate : function ( aContainer, aXTUse, aDocument ) {
var _handle = xtdom.createElement(aDocument, 'input');
xtdom.setAttribute(_handle, 'type', 'text');
if (this.getParam('noedit') === 'true') {
_handle.disabled = true;
}
aContainer.appendChild(_handle);
return _handle;
},
onInit : function ( aDefaultData, anOptionAttr, aRepeater ) {
var h = this.getHandle();
this.isEditable = !this.getParam('noedit');
this.defaultData = aDefaultData || '';
if (size = this.getParam('size')) {
xtdom.setAttribute(h, 'size', size);
}
h.value = this.defaultData; // FIXME: placeholder if HTML5 (?)
if (this.getParam('hasClass')) {
xtdom.addClassName(h, this.getParam('hasClass'));
}
},
onAwake : function () {
var h = this.getHandle();
var _this = this;
if (this.isEditable) {
xtdom.addEventListener(h, 'focus',
function(ev) {
if (!_this.isEditing()) {
_this.startEditing(ev);
}
xtdom.stopPropagation(ev);
xtdom.preventDefault(ev);
}, true);
xtdom.addEventListener(h, 'click',
function(ev) {
if (!_this.isEditing()) {
_this.startEditing(ev);
}
xtdom.stopPropagation(ev);
xtdom.preventDefault(ev);
}, true);
xtdom.addEventListener(h, 'mouseup', // needed on Safari to prevent unselection
function(ev) {
xtdom.stopPropagation(ev);
xtdom.preventDefault(ev);
}, true);
xtdom.addEventListener(h, 'blur',
function(ev) {
if (_this.isEditing()) {
_this.stopEditing(false, true);
}
}, true);
}
},
onLoad : function (aPoint, aDataSrc) {
var value, fallback;
if (aPoint !== -1) {
value = aDataSrc.getDataFor(aPoint);
fallback = this.getDefaultData();
this.getHandle().value = value || fallback || '';
this.setModified(value !== fallback);
this.set(false);
} else {
this.clear(false);
}
},
onSave : function (aLogger) {
var value;
if (this.isOptional() && !this.isSet()) {
aLogger.discardNodeIfEmpty();
} else {
value = this.getHandle().value;
if (value) {
aLogger.write(value);
}
}
},
////////////////////////////////
// Overwritten plugin methods //
////////////////////////////////
api : {
getData : function ( ) {
return this.getHandle().value;
},
isFocusable : function () {
return (this.isEditable && ((!this.isOptional()) || this.isSet()));
},
// AXEL keyboard API (called from Keyboard manager instance)
isEditing : function () {
return this._isEditing;
},
// AXEL keyboard API (called from Keyboard manager instance)
doKeyDown : function (ev) {
},
// AXEL keyboard API (called from Keyboard manager instance)
doKeyUp : function (ev) {
},
// AXEL tab group manager API
// Gives the focus to *this* instance. Called by the tab navigation manager.
focus : function () {
this.getHandle().focus();
this.startEditing();
},
// AXEL tab group manager API
// Takes the focus away from *this* instance. Called by the tab navigation manager.
unfocus : function () {
this.stopEditing();
}
},
/////////////////////////////
// Specific plugin methods //
/////////////////////////////
methods : {
// Starts an edition process on *this* instance's device.
startEditing : function (aEvent) {
var h, kbd = xtiger.session(this.getDocument()).load('keyboard');
if (! this._isEditing) {
h = this.getHandle();
this._legacy = h.value;
this._isEditing = true;
// registers to keyboard events
this.kbdHandlers = kbd.register(this, h);
kbd.grab(this, this);
if (!this.isModified()) {
xtdom.focusAndSelect(h);
}
}
},
// Stops the ongoing edition process
stopEditing : function (isCancel, isBlur) {
var h = this.getHandle();
var kbd = xtiger.session(this.getDocument()).load('keyboard');
if (this._isEditing) {
this._isEditing = false; // do it first to prevent any potential blur handle callback
kbd.unregister(this, this.kbdHandlers, h);
kbd.release(this, this);
if (!isCancel) {
this.update(h.value);
}
if ((! isBlur) && (h.blur)) {
h.blur();
}
}
},
// Called by Keyboard manager (Esc key)
cancelEditing : function () {
this.getHandle().value = this._legacy;
this.stopEditing();
},
// Updates this model with the given data.
// If this instance is optional and "unset", autocheck it.
update : function (aData) {
// 1. no change
if (aData === this._legacy) {
return;
}
// 2. normalizes text (empty text is set to _defaultData)
if (aData.search(/\S/) === -1 || (aData === this._defaultData)) {
this.clear(true);
} else {
// 3. notifies data was updated
this.setModified(aData !== this.defaultData);
this.set(true);
}
},
// Clears the model and sets its data to the default data.
// Unsets it if it is optional and propagates the new state if asked to.
clear : function (doPropagate) {
this.getHandle().value = this.defaultData;
this.setModified(false);
if (this.isOptional() && this.isSet()) {
this.unset(doPropagate);
}
},
// Overwrite 'optional' mixin method
set : function(doPropagate) {
// propagates state change in case some repeat ancestors are unset at that moment
if (doPropagate) {
if (!this.getParam('noedit')) {
xtiger.editor.Repeat.autoSelectRepeatIter(this.getHandle());
}
xtdom.removeClassName(this._handle, 'axel-repeat-unset');
// fix if *this* model is "placed" and the handle is outside the DOM at the moment
}
if (! this._isOptionSet) {
this._isOptionSet = true;
if (this._isOptional) {
this._handle.disabled = false;
this._optCheckBox.checked = true;
}
}
},
// Overwrite 'optional' mixin method
unset : function (doPropagate) {
if (this._isOptionSet) {
this._isOptionSet = false;
if (this._isOptional) {
this._handle.disabled = true;
this._optCheckBox.checked = false;
}
}
}
}
};
$axel.plugin.register(
'date',
{ filterable: true, optional: true },
{
// checked : 'false'
},
_DateField
);
}($axel));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment