4 'remoto!stdlib:js/panes/pane.js',
5 'remoto!stdlib:js/panes/panes/form.js',
6 'remoto!stdlib:js/paneManager/paneManager.js',
7 "remoto!stdlib:js/paneManager/paneMenu.js",
8 'remoto!stdlib:js/include/objectRegistry.js',
10 'remoto!stdlib:js/include/utils.js',
11 'remoto!stdlib:js/panes/panes/formListEditor.css',
12 'jquery/ui/jquery.ui.sortable',
43 pane.call(
this, layout);
47 this._type =
"formListEditor";
49 this._saveFields = { showItemList:
"_showItemList", showHeaderWidgets:
"_showHeaderWidgets" };
50 this._showItemList = layout.showItemList===
false ? false :
true;
51 this._showHeaderWidgets = layout.showHeaderWidgets===
true ? true :
false;
52 this._showAddRemoveButtons = layout.showAddRemoveButtons===
false ? false :
true;
56 this._context = layout.metadata ? (layout.metadata.context || {}) : {};
58 this._lastSelected =
null;
60 this._formListJq =
null;
61 this._itemListJq =
null;
63 this._objectLoader =
null;
79 if (this._html)
return this._html;
85 if (this._showItemList)
86 { this._formListJq = $(
"<div class='formListForms'>").appendTo(this._content);
88 this._itemListJq = $(
"<div class='formListItemList'>").appendTo(this._content);
90 this._itemListJq.on(
"pointerdown",
".formListItemListItem", this.
selectItem.bind(
this) );
92 this._itemListJq.bind(
"pointerdown", this.
selectItem.bind(
this,
"deselectAll") );
94 var w = this._itemListWidgetJq = $(
"<div class='formListItemListWidget'>").appendTo(this._content);
95 var add = $(
"<button>").
html(
"+").appendTo(w).bind(
"click", this.
newFormItemClick.bind(
this)).attr(
"disabled",
"disabled");
96 var del = $(
"<button>").
html(
"−").appendTo(w).bind(
"click", this.
deleteFormItemsClick.bind(
this)).attr(
"disabled",
"disabled");
97 var num = $(
"<span class='formListCount'>").
html(
"0 items").appendTo(w);
99 this._itemListWidgetAddJq = add;
100 this._itemListWidgetDelJq = del;
101 this._itemListWidgetNumJq = num;
104 this._formListJq = this._content;
120 if (this._header)
return this._header;
122 pane.prototype.createHeader.call(
this);
126 var h = this._header;
168 if (!this._objectLoader)
171 var FF = Object.keys(this._forms);
176 __p = this._path+
"/"+p;
179 if (!(__p in this._forms))
181 this._forms[__p] =
new formLoader( __p,
this );
187 FF = FF.filter(
function(e) {
return e !== __p });
193 console.warn(
"Remove items during subscribe",FF);
195 FF.map(
function(key) { DD[key] =
null; } );
208 if (menu && !menu.hasItemWithLabel(n))
214 icon:
"<img height=16 width=16 src='"+c[n].icon+
"' style='position:relative; top:2px; left:-1px'/>",
220 this._itemListWidgetAddJq.show().removeAttr(
"disabled");
222 this._itemListWidgetAddJq.hide();
225 this._itemListWidgetAddJq.hide();
236 if (menu && !menu.hasItemWithLabel(n))
242 icon:
"<img height=16 width=16 src='"+d[n].icon+
"' style='position:relative; top:2px; left:-1px'/>",
248 this._itemListWidgetDelJq.show().removeAttr(
"disabled");
250 this._itemListWidgetDelJq.hide();
253 this._itemListWidgetDelJq.hide();
255 this._subscribed =
true;
286 __p = p.substr(0,this._path.length) === this._path ? p : this._path+
"/"+p;
287 if (d!==
null && !(__p in this._forms))
301 f = this._forms[__p];
305 f._wrapper.wrapper.remove();
308 delete this._forms[__p];
367 this._selection =
null;
368 this._widgets =
null;
370 this._objectLoader =
null;
390 icon = icon || require.toUrl(
'include/loader/loader-contrast.gif');
394 var f = $(
"<div class='formListForm'>" ).appendTo( this._formListJq ).attr(
"path",
path);
395 var h = $(
"<div class='formListFormHeader'>").appendTo(f);
396 var c = $(
"<div class='formListFormContent'>").appendTo(f);
402 var hi = $(
"<img class='formListFormHeaderIcon' width='16' src='"+icon+
"'/>").appendTo(h);
404 var ht = $(
"<div class='formListFormHeaderTitle'>").appendTo(h);
405 ht.text(
"Loading '"+
form._path+
"'");
407 var b = $(
"<div class='formListFormHeaderButtons'>").appendTo(h);
408 var bh = $(
"<div class='formListFormHeaderButton' title='Help Text'>?</div>").appendTo(b);
409 var bm = $(
"<div class='formListFormHeaderButton' title='Collapse / Expand'>═</div>").appendTo(b);
410 var bc = $(
"<div class='formListFormHeaderButton' title='Close'>✕</div>").appendTo(b);
412 form._formJq.appendTo(c);
414 bh.bind(
"click",
function()
416 modal.alert(
form._help,
null,
"Help" );
422 bh.attr(
"title",
form._help.replace(/<br>/i,
"\n") );
429 if ( c.is(
":visible") ) bm.html(
"═");
430 else bm.html(
"+");
433 h.bind(
"dblclick", toggler );
434 bm.bind(
"click", toggler );
436 bc.bind(
"click",
function()
439 THIS._selection[ f.attr(
"path") ] =
false;
440 THIS.syncSelection();
473 this._formListJq.sortable( {
474 handle:
'.formListFormHeader',
476 containment:
'parent',
478 items:
'.formListForm',
493 if (!this._itemListJq)
return;
496 var list = this._itemListJq;
497 var chop = this._path.length+1;
503 var keys = Object.keys(this._forms).sort();
504 for (var j=0;j<keys.length;j++)
509 var i = $(
"<div class='formListItemListItem' path='"+p+
"'>").appendTo(list);
512 var f = this._forms[p];
513 if (f._attributes && f._attributes.name)
514 n = f._attributes.name.value;
519 n = $(
"<span>").
text(n);
526 f._wrapper.selector = i;
527 f._wrapper.selectorName = n;
529 var _icon = $(
"<span class='formListItemListItemIcon'>");
530 _icon.css(
"-webkit-mask-box-image",
"url(\""+f._wrapper.icon.attr(
"src").replace(/[\
"']/g,"\\\
"")+
"\")" );
535 var _icon = $(
"<span class='formListItemListItemIcon'>");
536 _icon.css(
"-webkit-mask-box-image",
"url(\""+f._icon.replace(/[\
"']/g,"\\\
"")+
"\")" );
543 if (f._attributes.active)
544 if (!f._attributes.active.value)
545 i.addClass(
"formListItemListItemInactive" );
547 if (f._attributes.status)
548 i.addClass(
"formListItemListItemStatus_"+f._attributes.status.value);
552 var alphabetical = list.find(
".formListItemListItem").sort(
function (a, b) {
553 if ( $(a).text() < $(b).
text() )
return -1;
554 if ( $(a).text() > $(b).
text() )
return 1;
560 list.html(alphabetical);
564 this._itemListWidgetNumJq.html( keys.length+
" item"+(keys.length!==1?
"s":
"") );
577 for (var p in this._forms)
579 if (this._selection[p])
580 { this._forms[p]._wrapper.wrapper.show();
581 this._itemListJq.children(
".formListItemListItem[path='"+p+
"']").addClass(
"formListItemListItemSelected");
584 { this._forms[p]._wrapper.wrapper.hide();
585 this._itemListJq.children(
".formListItemListItem[path='"+p+
"']").removeClass(
"formListItemListItemSelected");
608 if (e===
"deselectAll")
610 this._selection = {};
611 this._lastSelected =
null;
616 var p = $(e.currentTarget);
617 var shift = e.shiftKey;
619 var meta = e.metaKey;
620 var
path = p.attr(
"path");
629 var list = this._itemListJq;
630 var items = list.find(
".formListItemListItem");
631 var index = p.index();
632 var keys = jQuery.map( items,
function( n, i ) {
return $(n).attr(
"path"); } );
636 if (!shift || this._lastSelected ===
null)
637 this._lastSelected = index;
640 { this._lastSelected =
null;
646 this._selection = {};
648 var s = shift ? this._lastSelected : index;
650 var start = Math.min(s,ee);
651 var end = Math.max(s,ee);
655 for (var i = start; i<=end; i++)
660 if (meta) this._selection[ keys[i] ] = this._selection[ keys[i] ] ? false :
true;
661 else this._selection[ keys[i] ] =
true;
690 if (menu._items.length == 1)
691 menu._items[0]._callback.call();
693 menuManager.
openMenu(
"__formListEditor_creators_"+this._id, this._itemListWidgetAddJq,
"T" );
696 console.warn(
"formListEditor: no creator menu!");
714 var
metadata = { where:
"modalForm" };
717 context.sourcepath = this._path;
720 this._content.trigger(
"openApplicationLayout", [ context, action,
metadata ] );
739 if (menu._items.length == 1)
740 menu._items[0]._callback.call();
742 menuManager.
openMenu(
"__formListEditor_deletors_"+this._id, this._itemListWidgetDelJq,
"T" );
745 console.warn(
"formListEditor: no deletors menu!");
763 if ( !Object.keys(
this._selection ).length )
768 var m = action.confirmMessage ||
"You are about to delete the selected items.<br><br>Are you sure?";
793 for (var s in this._selection)
800 this._selection = {};
805 console.log(
"formListEditor applyRequestSuccess!");
810 console.log(
"formListEditor applyRequestError");
849 this._icon = require.toUrl(
'include/loader/loader-contrast.gif');
850 this._formList = _formList;
855 this._timeout = setTimeout( this.
timeout.bind(
this), 5000 );
858 { console.log(
"DIFF IN CTOR!");
876 console.warn(
"Timeout on "+this._path );
878 this._timeout =
null;
896 if (this._subscribed)
899 this._subscribed =
true;
910 return this._formList._objectLoader.fetchDefinition( data.base, data,
this.applyDiff.bind(
this) );
934 return this._formList._objectLoader.fetchDefinition( diff.base, {}, this.
createForm.bind(
this,diff) );
957 var spec = this._formList._objectLoader.applyValues( diff, definition );
963 var f =
new form( {
path:this._path, parent:this._formList } );
964 this._formList.addForm( this._path, f, this._icon );
970 var addedChanges = {};
971 var oAD = f.applyDiff;
972 f.applyDiff =
function(diff,
user)
975 { f._help = diff.help;
976 f._wrapper.help.show();
981 if (
"attributes" in diff)
983 oAD.call(
this,diff.attributes,
user);
985 if (
"name" in diff.attributes)
987 f._wrapper.title.text( diff.attributes.name.value );
988 f._wrapper.selectorName.text( diff.attributes.name.value )
990 if (!addedChanges.name)
992 var ocn = f._attributes.name._change;
993 f._attributes.name._change =
function(variable,
value,
widget)
995 f._wrapper.title.text(
value );
996 f._wrapper.selectorName.text(
value );
1000 addedChanges.name =
true;
1001 THIS._formList.syncItemList();
1005 if (
"active" in diff.attributes)
1009 if (diff.attributes.active.value)
1010 f._wrapper.selector.removeClass(
"formListItemListItemInactive" );
1011 else f._wrapper.selector.addClass(
"formListItemListItemInactive" );
1013 if (!addedChanges.active)
1015 var oca = f._attributes.active._change;
1016 f._attributes.active._change =
function(variable,
value,
widget)
1018 if (
value) f._wrapper.selector.removeClass(
"formListItemListItemInactive" );
1019 else f._wrapper.selector.addClass(
"formListItemListItemInactive" );
1024 addedChanges.active =
true;
1028 if (
"status" in diff.attributes)
1030 f._wrapper.selector.removeClass(
function(index, css) {
1031 return (css.match( /(^|\s)formListItemListItemStatus_[^\s]+/g) || []).join(
' ');
1034 f._wrapper.selector.addClass(
"formListItemListItemStatus_"+diff.attributes.status.value );
1036 if (!addedChanges.status)
1041 var ocs = f._attributes.active._change;
1042 f._attributes.active._change =
function(variable,
value,
widget)
1044 f._wrapper.selector.removeClass(
function(index, css) {
1045 return (css.match( /(^|\s)formListItemListStatus_.*/g) || []).join(
' ');
1048 f._wrapper.selector.addClass(
"formListItemListStatus_"+
value );
1054 addedChanges.status =
true;
1073 var oPU = f.postUpdate;
1074 f.postUpdate =
function(u)
1076 u = { attributes: u };
1083 return oPU.call(
this, u);
1091 f._subscribed =
true;
1113 { clearTimeout( this._timeout );
1114 this._timeout =
null;
applySubscription(data, metadata)
getter html
Get the html color representation of this object.
setter value
a setter DOCME
getter id
returns the number of milliseconds since midnight January 1, 1970 UTC
setter widget
a setter DOCME
applyDiff(id, diff, user, except)
registerObject(id, o, nosubscribe)
Register an object in the registry, and call the pathAddedCallback.
unregisterObject(id, o, silent, nounsubscribe, now)
Unregister an object from the registry.
Create a pane which will be mounted into a paneManager layout.
applyRequestSuccess(command, id, data, metadata)
applyRequestError(command, id, reason)
getter help
A getter that will return a pane object's help message, or a default message indicating that no help ...
The paneManager manages panes in a user layout.
getter path
a getter DOCME
createHTML()
Create the HTML contents of the pane.
Utility functions for javascript clients.
cleanPath(path)
Clean and normalize a resource path.
fileNameFromPath(p, orDirIfNeeded)
Retrieve the last part of a file path.
keyCount(o)
Return the number of keys in an object.
dirNameFromPath(p)
Retrieve the directory portion of a path.
resolveContextValues(o, ctx)
Recursively resolve any context values in an object.