diff --git a/README.md b/README.md
index 271b930..a834691 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,6 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/webability-go/wajaf)](https://goreportcard.com/report/github.com/webability-go/wajaf)
[![GoDoc](https://godoc.org/github.com/webability-go/wajaf?status.png)](https://godoc.org/github.com/webability-go/wajaf)
-[![GolangCI](https://golangci.com/badges/github.com/webability-go/wajaf.svg)](https://golangci.com)
WAJAF for GO v0.1
=============================
@@ -52,7 +51,7 @@ For objects:
- WA.extend: Will extends an object from another (inheritance).
- WA.clone: Will clone an object and all its children.
-- If you dont care the type of object but only its attributes, you can use WA.clone(object, true)
--- If you use the normal method WA.clone(object), it will close the whole object with attributes and methods.
+-- If you use the normal method WA.clone(object), it will clone the whole object with attributes and methods.
- WA.sizeof: Will calculates the size (number of attributes) of an object.
For DOM nodes:
@@ -109,6 +108,31 @@ TO DO:
Version Changes Control
=======================
+v0.3.0 - 2024-04-09
+------------------------
+- Added searcheabletextfieldElement, go and JS modified
+- mmcFieldElement now supports multifile upload too, and a template to present information
+- lovFieldElement now supports radio and checkboxes, and multiple select
+- groupContainer now supports sub-forms for master-details administration screens with templates to format detail records
+- Errors corrected con crowser getNodeDocumentLeft and getNodeDocumentTop to be correctly calculated with scroll offsets
+- Added function findNodeByClass in browser class
+- Added coretemplate.js to inject templates with data sets
+- Added floatingContainer for floating windows in page
+- Added resize of columns, order of columns and drag and drop for order into gridContainer
+- Error corrected on tabContainer when unloading the instance
+- TreeContainer now supports dragging and hover, sinchronized with server with the listener
+- textfieldElement and textareafieldElement corrected to display correctly the number of words and letters
+- New classes into css for new components
+
+
+v0.1.4 - 2022-12-02
+------------------------
+- Added listener option to AjaxRequest to follow the upload of request to the server
+- Error corrected in the 4GL Manager, the node with an inner application was not linking the application attribute
+- ggraphElement has been changed to control errors with try-catch when calling the google library
+- mmcFieldElement has been modified to work as expected and be able to manage any kind of files
+- gridContainer has been modified to be able to order the information by columns
+
v0.1.3 - 2022-06-12
------------------------
- Added CodeNode.go to create a node of code.
diff --git a/examples/public/skins/4gl/dommask-upload.png b/examples/public/skins/4gl/dommask-upload.png
new file mode 100644
index 0000000..f812555
Binary files /dev/null and b/examples/public/skins/4gl/dommask-upload.png differ
diff --git a/examples/public/skins/4gl/textfield-error.png b/examples/public/skins/4gl/textfield-error.png
new file mode 100644
index 0000000..1554c12
Binary files /dev/null and b/examples/public/skins/4gl/textfield-error.png differ
diff --git a/examples/public/skins/css/4gl.css b/examples/public/skins/css/4gl.css
index 1c1607a..b919af5 100644
--- a/examples/public/skins/css/4gl.css
+++ b/examples/public/skins/css/4gl.css
@@ -108,6 +108,9 @@
.group>fieldset>.hidden { display: none; }
+.group>.group>fieldset {
+ margin-left: 50px; border-left: 1px solid black;
+}
/* grid CONTAINER CLASSES */
@@ -116,10 +119,13 @@
/* 3 types of zones: title, field, control */
.grid .grid-header { position: absolute; left: 0px; right: 0px; top: 0px; height: 20px; background-color: #eee; border-bottom: 1px solid #ccc; overflow: hidden; }
.grid .grid-header-content { position: relative; }
-.grid .grid-header-column { float: left; }
+.grid .grid-header-column { float: left; position: relative; }
+.grid .grid-header-column.hover { color: #336; }
.grid .grid-header-column-title { background-color: white; height: 16px; padding-top: 3px; padding-left: 5px; border-bottom: 1px solid #999; border-right: 1px solid #999; }
.grid .grid-header-column-sizer { float: right; background-color: green; width: 3px; height: 20px; cursor: col-resize; }
-
+.grid .grid-header-column-order { float: right; width: 15px; height: 16px; background-image: url('../../skins/4gl/order-asc.png'); background-repeat: no-repeat; }
+.grid .grid-header-column-order-asc { width: 15px; height: 16px; background-image: url('../../skins/4gl/order-asc.png'); background-repeat: no-repeat; background-position: center; position: absolute; right: 1px; top: 1px; background-color: #fff; border-radius: 50%; }
+.grid .grid-header-column-order-desc { width: 15px; height: 16px; background-image: url('../../skins/4gl/order-desc.png'); background-repeat: no-repeat; background-position: center; position: absolute; right: 1px; top: 1px; background-color: #fff; border-radius: 50%; }
.grid .grid-body { position: absolute; left: 0px; right: 0px; top: 21px; bottom: 21px; background-color: #eee; overflow: auto; }
.grid .grid-body-content { position: relative; }
@@ -218,10 +224,34 @@ margin-left: 0px; }
.textfield.ok>.field { border-left: 1px solid #44aa44; border-bottom: 1px solid #44aa44; background-color: #eef8cc; }
.textfield.error>.field { border-left: 1px solid #cc8800; border-bottom: 1px solid #cc8800; background-color: #ffeeee; }
.textfield.edition>.field { border-left: 1px solid #8888ff; border-bottom: 1px solid #8888ff; background-color: #eeeeff; }
-
+.textfield>.selected {
+ border: 0px;
+ padding: 2px;
+ height: 15px;
+ border-left: 1px solid #aaa;
+ border-bottom: 1px solid #aaa;
+ background-color: #eee;
+ color: #888;
+}
.textfield>.help { display: block; padding: 5px; color: #999; float: right; width: 400px; }
.textfield>.error { display: block; padding: 5px; color: #f00; float: right; width: 400px; }
-
+.textfield>.list {
+ position: absolute;
+ top: 20px;
+ background-color: #cceeff;
+ border: 2px solid blue;
+ height: 100px;
+ display: none;
+ z-index: 10;
+ overflow-y: scroll;
+}
+.textfield>.list>.item {
+ cursor: pointer;
+}
+.textfield>.list>.item:hover, .textfield>.list>.item.selected {
+ background-color: blue;
+ color: white;
+}
.textfieldlabel.medium { }
.textfieldlabel.tiny { width: auto; float: none; text-align: left; padding-left: 20px; }
@@ -273,6 +303,9 @@ margin-left: 0px; }
.lovfield>.count { color: #999; font-size: 10px; padding-top: 3px; }
.lovfield>.value { }
.lovfield>.field { width: 270px; border: 0px; height: 20px; border-left: 1px solid #aaa; border-bottom: 1px solid #aaa; background-color: #eee; }
+.lovfield>div.field {
+ height: auto;
+}
.lovfield.ok>.field { border-left: 1px solid #44aa44; border-bottom: 1px solid #44aa44; background-color: #eef8cc; }
.lovfield.error>.field { border-left: 1px solid #cc8800; border-bottom: 1px solid #cc8800; background-color: #ffeeee; }
.lovfield.edition>.field { border-left: 1px solid #8888ff; border-bottom: 1px solid #8888ff; background-color: #eeeeff; }
@@ -364,9 +397,46 @@ margin-left: 0px; }
.dommaskcolorfield.maskdisabled .entryinput { border: 0px; background-color: #eeeeee; padding: 2px; height: 15px; }
-
-
-
+/* MMC field */
+
+.mmcfieldlabel { float: left; width: 140px; padding-top: 1px; text-align: right; display: block; color: #333; font-size: 12px; font-weight: bold; line-height: 18px;
+ width: auto; float: none; text-align: left; padding-left: 20px; }
+.mmcfieldlabel.error { color: red; }
+
+.mmcfield { padding-left: 20px; background-repeat: no-repeat; background-position: 2px 4px; position: relative; min-height: 50px; }
+.mmcfield.ok { background-image: url('../../skins/4gl/field-ok.png'); }
+.mmcfield.error { background-image: url('../../skins/4gl/field-error.png'); }
+.mmcfield.edition { background-image: url('../../skins/4gl/field-edition.png'); }
+
+.mmcfield .upload { border-left: 2px dashed #aaa; border-bottom: 2px dashed #aaa; background-color: #eee; margin: 1px; font-size: 10px; font-weight: bold; min-height: 50px; padding-top: 5px; cursor: pointer; }
+.mmcfield .upload-icon { background-image: url('../../skins/4gl/filefield-upload.png'); background-size: cover; background-position: center; background-repeat: no-repeat; width: 25px; height: 25px;}
+.mmcfield.ok .upload { border-left: 2px dashed #44aa44; border-bottom: 2px dashed #44aa44; background-color: #eef8cc; color: #0a0; }
+.mmcfield.error .upload { border-left: 2px dashed #cc8800; border-bottom: 2px dashed #cc8800; background-color: #ffeeee; color: #a00; }
+.mmcfield.edition .upload { border-left: 2px dashed #8888ff; border-bottom: 2px dashed #8888ff; background-color: #eeeeff; color: #00a; }
+.mmcfield.ok .upload.dragover { border-left: 2px solid #44aa44; border-bottom: 2px solid #44aa44; background-color: #eef8cc; color: #0a0; }
+.mmcfield.error .upload.dragover { border-left: 2px solid #cc8800; border-bottom: 2px solid #cc8800; background-color: #ffeeee; color: #a00; }
+.mmcfield.edition .upload.dragover { border-left: 2px solid #8888ff; border-bottom: 2px solid #8888ff; background-color: #eeeeff; color: #00a; }
+
+.mmcfield .uploading { position: relative; border-left: 2px solid #8888ff; border-bottom: 2px solid #8888ff; background-color: #eeeeff; margin: 1px; font-size: 12px; font-weight: bold; min-height: 50px; }
+.mmcfield .uploading-icon { background-image: url('../../skins/4gl/loader.gif'); background-size: cover; background-position: center; background-repeat: no-repeat; width: 25px; height: 25px; margin-left: 10px; margin-top: 10px; float: left;}
+.mmcfield .uploading-name { position: absolute; top: 10px; left: 60px; }
+.mmcfield .uploading-perc { position: absolute; top: 10px; right: 5px; }
+.mmcfield .uploading-bar { position: absolute; bottom: 10px; right: 5px; height: 10px; width: calc(100% - 55px); background-color: white;}
+.mmcfield .uploading-progressbar { position: absolute; left: 0; width: 0; height: 10px; background-color: #77a;}
+
+.mmcfield .uploaded { position: relative; margin: 3px; font-size: 10px; font-weight: bold; min-height: 50px; }
+.mmcfield.editing .uploaded { background-color: #eef;}
+.mmcfield .uploaded-icon { max-height: 50px; max-width: 50px; float: left; }
+.mmcfield .uploaded-image { max-height: 50px; max-width: 100px; float: left; margin-right: 5px; }
+.mmcfield .uploaded-value { margin-left: 5px; }
+.mmcfield .uploaded-delete { width: auto; border: 1px solid red; padding: 5px; position: absolute; bottom: 0; right: 0; cursor: pointer; }
+.mmcfield .uploaded-delete:hover { background-color: red; color: white; }
+
+.mmcfield>.help { display: block;padding: 5px; color: #999; float: right; width: 400px; }
+.mmcfield>.error { display: block; padding: 5px; color: #f00; float: right; width: 400px; }
+
+.mmcfieldlabel.tiny { width: auto; float: none; text-align: left; padding-left: 20px; }
+.mmcfield.tiny { margin-left: 0px; }
diff --git a/groupcontainer.go b/groupcontainer.go
index 9c8d514..fdee6af 100644
--- a/groupcontainer.go
+++ b/groupcontainer.go
@@ -13,7 +13,7 @@ func NewGroupContainer(id string) *GroupContainer {
c.RegisterKnownAttributes([]string{"display", "style", "classname", "classnamezone",
"left", "width", "right", "top", "height", "bottom", "haslistener",
- "varmode", "varorder", "varkey",
+ "varmode", "varorder", "varkey", "maingroup",
"mode", "authmodes", "key"})
// c.RegisterKnownMessages([]string{"alertmessage", "servermessage", "titleinsert", "titleupdate", "titledelete", "titleview", "insertok", "updateok", "deleteok"})
c.RegisterKnownChildren([]string{"zone", "dataset", "event", "help"})
diff --git a/js/containers/floatingContainer.js b/js/containers/floatingContainer.js
new file mode 100644
index 0000000..f874f41
--- /dev/null
+++ b/js/containers/floatingContainer.js
@@ -0,0 +1,530 @@
+
+/*
+ floatingContainer.js, WAJAF, the WebAbility(r) Javascript Application Framework
+ Contains container to control moveable zones
+ (c) 2008-2010 Philippe Thomassigny
+
+ This file is part of WAJAF
+
+ WAJAF is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ WAJAF is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with WAJAF. If not, see .
+*/
+
+/* The floating Container is a division-nav-sized that lock windows in it with a overflow: hidden */
+/* The floating Container have a list of windows accesible to switch windows on the left */
+
+WA.Containers.floatingContainer = function(domNodeFather, domID, code, listener)
+{
+ var self = this;
+
+ WA.Containers.floatingContainer.sourceconstructor.call(this, domNodeFather, domID, code, 'div', { classname: 'float' }, listener);
+
+ this.classes = WA.getClasses(code.attributes,
+ {
+ classname: 'float',
+ classnameheader: 'float-header', classnameheadercontent: 'float-header-content',
+ classnamebody: 'float-body', classnamebodycontent: 'float-body-content',
+ classnameclose: 'buttonmenudisconnect',
+ });
+
+ this.haslistener = (code.attributes.haslistener === 'yes');
+ this.params = code.attributes.params ? '&' + code.attributes.params : '';
+ this.hasdd = !!WA.Managers.dd;
+ this.zones = {};
+ this.zoneactive = this.code.attributes.startzone ? this.code.attributes.startzone : null;
+
+ this.domNode.style.display = 'none';
+ this.domNodeContainer = document.createElement('div');
+ this.domNodeContainer.id = "domNodeContainer";
+ this.domNodeContainer.style.display = 'none';
+ this.domNodeContainer.style.position = 'absolute';
+ this.domNodeContainer.style.left = '0px';
+ this.domNodeContainer.style.right = '0px';
+ this.domNodeContainer.style.top = '0px';
+ this.domNodeContainer.style.bottom = '0px';
+ this.domNodeContainer.style.backgroundColor = 'transparent';
+ this.domNodeContainer.style.zIndex = '10';
+ document.body.appendChild(this.domNodeContainer);
+
+ this.domNodeModal = document.createElement('div');
+ this.domNodeModal.id = "domNodeModal";
+ this.domNodeModal.style.position = 'absolute';
+ this.domNodeModal.style.left = '0px';
+ this.domNodeModal.style.right = '0px';
+ this.domNodeModal.style.top = '0px';
+ this.domNodeModal.style.bottom = '0px';
+ this.domNodeModal.style.backgroundColor = 'black';
+ this.domNodeModal.style.opacity = '0.6';
+ this.domNodeModal.style.zIndex = '11';
+ this.domNodeContainer.appendChild(this.domNodeModal);
+
+ //this.domNodeModal.onclick = hide;
+
+ start();
+ //this.addEvent('start', start);
+ this.addEvent('stop', stop);
+
+ this.newZone = newZone;
+ function newZone(id, title, classname, style, application, closeable, shortcut, params) {
+ var code = {};
+ code.tag = 'zone';
+ code.attributes = { id: id, title: title, classname: classname, style: style, closeable: closeable, shortcut: shortcut, application: application, params: params };
+ self.app.createTree(self, code);
+ }
+
+ // id is unique id, code are all needed parameters
+ this.createZone = createZone;
+ function createZone(id, code, notify) {
+ var ldomID = WA.parseID(id, self.xdomID);
+ if (!ldomID)
+ throw 'Error: the zone id is not valid in floatingContainer.createZone: id=' + domID;
+ // check the zone does not exists YET !
+ if (self.zones[ldomID[2]])
+ throw 'Error: the zone already exists in floatingContainer.createZone: id=' + ldomID[2];
+
+ // 1. call event precreate, can we create ?
+ if (!self.callEvent('precreate', { id: ldomID[2] }))
+ return null;
+
+ var z = new WA.Containers.floatingContainer.floatingZone(self, ldomID[3], code, notify);
+ self.zones[ldomID[2]] = z;
+ z.start();
+
+ if (!self.zoneactive) {
+ self.zoneactive = ldomID[2];
+ z.show();
+ }
+
+ self.callEvent('postcreate', { id: ldomID[2] });
+ if (self.state == 5) {
+ z.propagate('start');
+ }
+ return z;
+ }
+
+ this.showZone = showZone;
+ function showZone(id) {
+ var ldomID = WA.parseID(id, self.xdomID);
+ if (!ldomID)
+ throw 'Error: the zone id is not valid in floatingContainer.showZone: id=' + id;
+ // check the zone does not exists YET !
+ if (!self.zones[ldomID[2]])
+ throw 'Error: the zone does not exists in floatingContainer.showZone: id=' + ldomID[2];
+ var result = true;
+ result &= self.callEvent('preshow', ldomID[2]);
+ if (self.zoneactive && ldomID[2] !== self.zoneactive)
+ result &= self.callEvent('prehide', self.zones[self.zoneactive].xdomID[2]);
+ if (!result)
+ return;
+
+ // first hide actual
+ if (self.zoneactive && ldomID[2] !== self.zoneactive) {
+ self.zones[self.zoneactive].hide();
+ self.callEvent('posthide', self.zones[self.zoneactive].xdomID[2]);
+ self.zoneactive = null;
+ }
+
+ // then show the specified zone
+ self.zones[ldomID[2]].show();
+ self.zoneactive = ldomID[2];
+ self.callEvent('postshow', ldomID[2]);
+ self.zones[ldomID[2]].propagate('focus');
+ if (self.state == 5) {
+ self.propagate('resize');
+ }
+ }
+
+ this.activateZone = activateZone;
+ function activateZone(id) {
+ self.showZone(id);
+ }
+
+ this.destroyZone = destroyZone;
+ function destroyZone(id) {
+ var ldomID = WA.parseID(id, self.xdomID);
+ if (!ldomID)
+ throw 'Error: the zone id is not valid in floatingContainer.destroyone: id=' + id;
+ // check the zone does not exists YET !
+ if (!self.zones[ldomID[2]])
+ throw 'Error: the zone does not exists in floatingContainer.destroyZone: id=' + ldomID[2];
+
+ // 2. call event predestroy
+ if (!self.callEvent('predestroy', { id: ldomID[2] }))
+ return;
+
+ var available = null;
+ if (ldomID[2] == self.zoneactive) {
+ var next = false;
+ // take next available
+ for (var i in self.zones) {
+ if (i == self.zoneactive && available == null) {
+ next = true;
+ continue;
+ }
+ if (i == self.zoneactive)
+ break;
+ available = i;
+ if (next)
+ break;
+ }
+ }
+
+ self.app.destroyTree(ldomID[2]);
+ delete self.zones[ldomID[2]];
+
+ if (ldomID[2] == self.zoneactive) {
+ self.zoneactive = null;
+ if (available)
+ self.activateZone(available);
+ }
+
+ self.callEvent('postdestroy', { id: ldomID[2] });
+ self.propagate('resize');
+ }
+
+
+ this.start = start;
+ function start() {
+ if (self.hasdd){
+ console.log("floatingcontainer REGISTRANDO GROUPO", self.domNode, self.domNodeContainer);
+ WA.Managers.dd.registerGroup(self.domNode, 'caller', true, self.domNode, null);
+ }
+ }
+
+ function stop() {
+ if (self.hasdd)
+ WA.Managers.dd.unregisterGroup(self.domID);
+ }
+
+ this.destroy = destroy;
+ function destroy(fast) {
+ self.zones = null;
+ self.domNodeContainer = null;
+ WA.Containers.floatingContainer.source.destroy.call(self, fast);
+ self = null;
+ }
+
+ // ===========================================================
+ // PRIVATE FUNCTIONS
+
+ /*
+ // Put each division on original place
+ this.restart = restart;
+ function restart()
+ {
+ for (var i=0, l=self.floatings.length; i < l; i++)
+ {
+ self.floatings[i].restart();
+ }
+ }
+*/
+ this.show = show;
+ function show() {
+ self.domNodeContainer.style.display = 'block';
+ self.resize();
+ }
+
+ this.hide = hide;
+ function hide() {
+ self.domNodeContainer.style.display = 'none';
+ }
+/*
+ // put division on a new position by program
+ this.setPosition = setPosition;
+ function setPosition(id, left, top)
+ {
+ for (var i=0, l=self.floatings.length; i < l; i++)
+ {
+ if (self.floatings[i].getID() == id)
+ {
+ self.floatings[i].setPosition(left, top);
+ }
+ }
+ }
+ */
+/*
+
+ this.getWidth = getWidth;
+ function getWidth()
+ {
+ return self.width;
+ }
+
+ this.getHeight = getHeight;
+ function getHeight()
+ {
+ return self.height;
+ }
+
+ this.selectormouseover = selectormouseover;
+ function selectormouseover(id)
+ {
+ // we create the list of windows
+ // -> [ onclick item of window => window set focus, then close the list ]
+
+ // we attach the list to the container
+
+ // we listen the list: on mouse out ==> close it
+
+
+ }
+*/
+}
+
+// Add basic container code
+WA.extend(WA.Containers.floatingContainer, WA.Managers.wa4gl._container);
+
+WA.Containers.floatingContainer.floatingZone = function (maincontainer, domID, code, notify) {
+ var self = this;
+ WA.Containers.floatingContainer.floatingZone.sourceconstructor.call(this, maincontainer, domID, code, 'div', { classname: 'zone' }, notify);
+ maincontainer.domNodeContainer.appendChild(this.domNode);
+ //self.container = WA.toDOM("main|single|workarea");
+
+ this.left = parseInt(code.attributes.left, 10);
+ this.top = parseInt(code.attributes.top, 10);
+ this.width = parseInt(code.attributes.width, 10);
+ this.height = parseInt(code.attributes.height, 10);
+
+ this.domNode.style.position = "absolute";
+ this.domNode.style.top = this.top + 'px';
+ this.domNode.style.left = this.left + 'px';
+ this.domNode.style.width = this.width + 'px';
+ this.domNode.style.height = this.height + 'px';
+ this.domNode.style.border = "1px solid #99bbe8";
+ this.domNode.style.backgroundColor = "white";
+ this.domNode.style.zIndex = '12';
+
+ //if(this.domNode.id == 'control|single|clientsearchcontainer')
+ addHead(code);
+
+ function addHead(code)
+ {
+ // header division
+ self.domNodeHeader = WA.createDomNode('div', domID+'_header', self.father.classes.classnameheader);
+ self.domNode.insertAdjacentElement('afterbegin', self.domNodeHeader);
+ self.domNodeHeader.style.backgroundColor = "#f5f6f7";
+ self.domNodeHeader.style.border = "1px solid #99bbe8";
+ self.domNodeHeader.style.top = '0px';
+ self.domNodeHeader.style.left = '0px';
+ self.domNodeHeader.style.width = code.attributes.width - 4 + 'px';
+ self.domNodeHeader.style.height = '20px';
+
+ var nodeClose = WA.createDomNode('div', domID+'_header_close', self.father.classes.classnameclose);
+ nodeClose.style.width = '16px';
+ nodeClose.style.height = '16px';
+ nodeClose.style.position = 'absolute';
+ nodeClose.style.right = '10px';
+ nodeClose.style.top = '2px';
+ self.domNodeHeader.appendChild(nodeClose);
+ nodeClose.onclick = self.father.hide;
+
+ setTimeout(()=>{
+ self.domNode.lastChild.style.top = '20px';
+ },400)
+ }
+
+ var top = 0;
+ var bottom = 0;
+ var left = 0;
+ var right = 0;
+ var xCursor = 0;
+ var yCursor = 0;
+
+ this.move = move;
+ function move(order, id1, lineid, zone, metrics)
+ {
+ switch (order) {
+ case 'start':
+ var n = WA.toDOM(self.domNodeHeader.id);
+ n.getAttribute('class');
+ if(/dragged/.exec(n.getAttribute('class')) == null)
+ self.domNodeHeader.className += ' dragged';
+ self.domNode.style.position = 'absolute';
+ self.domNode.style.left = metrics.dragdocumentleft + 'px';
+ self.domNode.style.top = metrics.dragdocumenttop + 'px';
+ self.domNode.style.width = metrics.mainwidth + 'px';
+ self.domNode.style.height = metrics.mainheight + 'px';
+
+ top = WA.browser.getNodeDocumentTop(self.domNode);
+ bottom = WA.browser.getNodeDocumentTop(self.domNode) + WA.browser.getNodeHeight(self.domNode);
+ left = WA.browser.getNodeDocumentLeft(self.domNode);
+ right = WA.browser.getNodeDocumentLeft(self.domNode) + WA.browser.getNodeWidth(self.domNode);
+ break;
+ case 'drag':
+ var l = dragPos(metrics.xmouse, metrics.ymouse);
+ left += l.l;
+ top += l.r;
+ self.domNode.style.left = left + l.l + 'px';
+ self.domNode.style.top = top + l.r + 'px';
+ break;
+ case 'drop':
+ top = 0;
+ bottom = 0;
+ left = 0;
+ right = 0;
+ xCursor = 0;
+ yCursor = 0;
+ break;
+ }
+ }
+
+
+ function dragPos(x, y)
+ {
+ var l = xCursor == 0 ? 1 : x - xCursor;
+ var r = yCursor == 0 ? 1 : y - yCursor;
+
+ if(x < xCursor)
+ l = l * 2 - l;
+
+ if(y < yCursor)
+ r = r * 2 - r;
+
+ xCursor = x;
+ yCursor = y;
+
+ return {l,r};
+ }
+
+
+ this.start = start;
+ function start()
+ {
+ if (self.father.hasdd) {
+ console.log('floatingContainer REGISTEROBJECT')
+ //self.father.domNodeContainer, self.domNode, self.domNode
+ WA.Managers.dd.registerObject(maincontainer.domNode, self.domNodeHeader, self.domNode, move);
+ }
+ }
+
+ /*
+ this.resize = resize;
+ function resize() {
+ console.log("RESIZING ZONE", self.domID, "visible=", self.visible, "running=", self.father.visible, "state=", self.state);
+ // cannot resize if not visible or not running
+ if (!self.visible || !self.father.visible)
+ return;
+ self.domNode.style.height = self.height + 'px';
+
+ // cannot resize if not visible or not running
+ if (self.state != 5)
+ return;
+ // ask for an inner resize
+ self.callEvent('pleaseresize');
+ }
+ */
+
+/*
+
+ this.startdrag = startdrag;
+ function startdrag(e) {
+ if (!self.isok)
+ return false;
+ focus(e);
+ self.statusdd = true;
+ self.clickx = WA.browser.getCursorX(e);
+ self.clicky = WA.browser.getCursorY(e);
+ self.originleft = parseInt(WA.toDOM(self.uid).style.left);
+ self.origintop = parseInt(WA.toDOM(self.uid).style.top);
+
+ // we create a division to drag on top
+ var container = document.createElement('div');
+ container.id = self.uid + '_drag';
+ // take the size of the screen with a minimum size (NS calculates bad the real size for 2 pixels!)
+ container.style.visibility = 'visible';
+ container.style.position = 'absolute';
+ container.style.width = (self.fC.width - (WA.browser.isNS() ? 2 : 0)) + 'px';
+ container.style.height = (self.fC.height - (WA.browser.isNS() ? 2 : 0)) + 'px';
+ container.style.left = '0px';
+ container.style.top = '0px';
+ container.style.border = '2px Solid #FF0000';
+ container.style.backgroundColor = '#EEEE00';
+ container.style.opacity = 0.2;
+ container.style.filter = "alpha(opacity: 20)";
+ container.style.cursor = 'pointer';
+ container.style.overflow = 'hidden';
+ container.style.zIndex = WA.browser.getNextZIndex();
+ container.onmousemove = move;
+ container.onmouseup = stopdrag;
+ self.dragcontainer = container;
+ document.body.appendChild(container);
+ WA.toDOM(self.uid + '_drag').focus();
+
+ return true;
+ }
+
+ this.stopdrag = stopdrag;
+ function stopdrag(e) {
+ if (!self.isok)
+ return false;
+
+ // we destroy the drag division
+ self.dragcontainer.onmousemove = null;
+ self.dragcontainer.onmouseup = null;
+ document.body.removeChild(WA.toDOM(self.uid + '_drag'));
+ self.dragcontainer = null;
+
+ self.originleft = parseInt(WA.toDOM(self.uid).style.left);
+ self.origintop = parseInt(WA.toDOM(self.uid).style.top);
+ self.statusdd = false;
+ if (self.feedback)
+ self.feedback(self);
+
+ return true;
+ }
+
+ this.move = move;
+ function move(e) {
+ if (!self.isok)
+ return false;
+ if (self.statusdd) {
+ WA.toDOM(self.uid).style.left = self.originleft + (WA.browser.getCursorX(e) - self.clickx) + 'px';
+ WA.toDOM(self.uid).style.top = self.origintop + (WA.browser.getCursorY(e) - self.clicky) + 'px';
+ return true;
+ }
+ return false;
+ }
+*/
+/*
+ this.restart = restart;
+ function restart() {
+ if (!self.isok)
+ return false;
+ WA.toDOM(self.uid).style.left = self.systemleft + 'px';
+ WA.toDOM(self.uid).style.top = self.systemtop + 'px';
+ self.originleft = parseInt(WA.toDOM(self.uid).style.left);
+ self.origintop = parseInt(WA.toDOM(self.uid).style.top);
+ if (self.feedback)
+ self.feedback(self);
+ }
+
+ this.focus = focus;
+ function focus(e) {
+ if (!self.isok)
+ return false;
+ WA.toDOM(self.uid).style.zIndex = WA.browser.getNextZIndex();
+ }
+
+ this.setPosition = setPosition;
+ function setPosition(left, top) {
+ if (!self.isok)
+ return false;
+ WA.toDOM(self.uid).style.left = left + 'px';
+ WA.toDOM(self.uid).style.top = top + 'px';
+ }
+*/
+
+}
+
+// Add basic zone code
+WA.extend(WA.Containers.floatingContainer.floatingZone, WA.Managers.wa4gl._zone);
diff --git a/js/containers/floatingContainer.none b/js/containers/floatingContainer.none
deleted file mode 100644
index 29e3c0e..0000000
--- a/js/containers/floatingContainer.none
+++ /dev/null
@@ -1,488 +0,0 @@
-
-/*
- floatingContainer.js, WAJAF, the WebAbility(r) Javascript Application Framework
- Contains container to control moveable zones
- (c) 2008-2010 Philippe Thomassigny
-
- This file is part of WAJAF
-
- WAJAF is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- WAJAF is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with WAJAF. If not, see .
-*/
-
-function floating(id, iddd, feedback, fC)
-{
- // we use a trick for functions since 'this' is caller when it is called from events callbacks and not this real object !
- var self = this;
- this.uid = '';
- this.uiddd = '';
- this.isok = false;
- this.statusdd = false;
- this.systemleft = 0;
- this.systemtop = 0;
- this.originleft = 0;
- this.origintop = 0;
- this.clickx = 0;
- this.clicky = 0;
- this.feedback = feedback;
- this.dragcontainer = null;
- this.fC = fC;
-
- this.getID = getID;
- function getID()
- {
- return this.uid;
- }
-
- this.startdrag = startdrag;
- function startdrag(e)
- {
- if (!self.isok)
- return false;
- focus(e);
- self.statusdd = true;
- self.clickx = WA.browser.getCursorX(e);
- self.clicky = WA.browser.getCursorY(e);
- self.originleft = parseInt(WA.toDOM(self.uid).style.left);
- self.origintop = parseInt(WA.toDOM(self.uid).style.top);
-
- // we create a division to drag on top
- var container = document.createElement('div');
- container.id = self.uid + '_drag';
- // take the size of the screen with a minimum size (NS calculates bad the real size for 2 pixels!)
- container.style.visibility = 'visible';
- container.style.position = 'absolute';
- container.style.width = (self.fC.width - (WA.browser.isNS()?2:0))+'px';
- container.style.height = (self.fC.height - (WA.browser.isNS()?2:0))+'px';
- container.style.left = '0px';
- container.style.top = '0px';
- container.style.border = '2px Solid #FF0000';
- container.style.backgroundColor = '#EEEE00';
- container.style.opacity = 0.2;
- container.style.filter = "alpha(opacity: 20)";
- container.style.cursor = 'pointer';
- container.style.overflow='hidden';
- container.style.zIndex = WA.browser.getNextZIndex();
- container.onmousemove = move;
- container.onmouseup = stopdrag;
- self.dragcontainer = container;
- document.body.appendChild(container);
- WA.toDOM(self.uid+'_drag').focus();
-
- return true;
- }
-
- this.stopdrag = stopdrag;
- function stopdrag(e)
- {
- if (!self.isok)
- return false;
-
- // we destroy the drag division
- self.dragcontainer.onmousemove = null;
- self.dragcontainer.onmouseup = null;
- document.body.removeChild(WA.toDOM(self.uid+'_drag'));
- self.dragcontainer = null;
-
- self.originleft = parseInt(WA.toDOM(self.uid).style.left);
- self.origintop = parseInt(WA.toDOM(self.uid).style.top);
- self.statusdd = false;
- if (self.feedback)
- self.feedback(self);
-
- return true;
- }
-
- this.move = move;
- function move(e)
- {
- if (!self.isok)
- return false;
- if (self.statusdd)
- {
- WA.toDOM(self.uid).style.left = self.originleft+(WA.browser.getCursorX(e)-self.clickx)+'px';
- WA.toDOM(self.uid).style.top = self.origintop+(WA.browser.getCursorY(e)-self.clicky)+'px';
- return true;
- }
- return false;
- }
-
- this.restart = restart;
- function restart()
- {
- if (!self.isok)
- return false;
- WA.toDOM(self.uid).style.left = self.systemleft+'px';
- WA.toDOM(self.uid).style.top = self.systemtop+'px';
- self.originleft = parseInt(WA.toDOM(self.uid).style.left);
- self.origintop = parseInt(WA.toDOM(self.uid).style.top);
- if (self.feedback)
- self.feedback(self);
- }
-
- this.focus = focus;
- function focus(e)
- {
- if (!self.isok)
- return false;
- WA.toDOM(self.uid).style.zIndex = WA.browser.getNextZIndex();
- }
-
- this.setPosition = setPosition;
- function setPosition(left, top)
- {
- if (!self.isok)
- return false;
- WA.toDOM(self.uid).style.left = left+'px';
- WA.toDOM(self.uid).style.top = top+'px';
- }
-
- this.unload = unload;
- function unload()
- {
- // MAYBE WE CAN CALL THE FEEDBACK TO SAY WE ARE UNLOADING ? (to do)
-
- // desactive floating
- self.isok = false;
-
- // unregister anything of the floating
- var interfase = WA.toDOM(self.uiddd);
- if (typeof self.uiddd == 'object')
- {
- for (var i = 0, l = interfase.length; i < l; i++)
- {
- interfase[i].onmousemove = null;
- interfase[i].onmousedown = null;
- interfase[i].onmouseup = null;
- interfase[i].onmouseout = null;
- }
- }
- else
- {
- interfase.onmousemove = null;
- interfase.onmousedown = null;
- interfase.onmouseup = null;
- interfase.onmouseout = null;
- }
- WA.toDOM(self.uid).onmousedown = null;
- if (self.feedback)
- self.feedback = null;
- // remove memory leak
- self = null;
- }
-
- this.uid = id;
- this.uiddd = iddd;
- if (WA.toDOM(this.uid) == null || WA.toDOM(this.uiddd) == null)
- {
- alert('Could not find the element ' + this.uid + ' or ' + this.uiddd);
- return false;
- }
-
- this.systemleft = parseInt(WA.toDOM(this.uid).style.left);
- this.systemtop = parseInt(WA.toDOM(this.uid).style.top);
-
- var interfase = WA.toDOM(this.uiddd);
- if (typeof self.uiddd == 'object')
- {
- for (var i = 0, l = interfase.length; i < l; i++)
- {
- interfase[i].onmousemove = move;
- interfase[i].onmousedown = startdrag;
- interfase[i].onmouseup = stopdrag;
- interfase[i].onmouseout = move;
- }
- }
- else
- {
- interfase.onmousemove = move;
- interfase.onmousedown = startdrag;
- interfase.onmouseup = stopdrag;
- interfase.onmouseout = move;
- }
- WA.toDOM(this.uid).onmousedown = focus;
-
- this.isok = true;
-
- return this;
-}
-
-/* The floating Container is a division-nav-sized that lock windows in it with a overflow: hidden */
-/* The floating Container have a list of windows accesible to switch windows on the left */
-
-function floatingContainer(domID, params, feedback, _4glNode)
-{
- var self = this;
- this.domID = domID;
- this._4glNode = _4glNode;
- this.params = params;
- this.feedback = feedback;
-
- // the zone is the domID itself. id is ignored. params may have 'classname'
- this.createZone = createZone;
- function createZone(id, params)
- {
- if (params['classname'])
- self.domNode.className = params['classname'];
- return self;
- }
-
- // nothing to start
- this.start = start;
- function start()
- {
- }
-
- // nothing explicit to resize
- this.resize = resize;
- function resize()
- {
- }
-
- // nothing to save
- this.getvalues = getvalues;
- function getvalues()
- {
- return null;
- }
-
- // nothing to load
- this.setvalues = setvalues;
- function setvalues(values)
- {
- }
-
- // nothing to stop
- this.stop = stop;
- function stop()
- {
- }
-
- this.destroy = destroy;
- function destroy()
- {
- this.domID = null;
- this._4glNode = null;
- this.params = null;
- this.feedback = null;
- this.domNode = null;
- }
-
-
-
-
-
-
- var self = this;
- this.floatings = new Array();
- this.id = id; // if desktop with id exists, take it and ignore mins, or create a window nav desktop
- this.mode = mode || ''; // mode = "jail" if the floatings cannot go outside, "hide" if can go outside without resize, and "resize" if can go outside and resize the desktop
- this.minwidth = minwidth; // minimum size of desktop
- this.minheight = minheight; // minimum size of desktop
- this.width = 0;
- this.height = 0;
- this.container = null;
- this.selector = selector; // true to use the control planel, false for no
-
- // ===========================================================
- // PRIVATE FUNCTIONS
-
- // ===========================================================
- // PUBLIC FUNCTIONS
-
- // register a division that can be dragged and droped
- // id is the id of the division
- // iddd is the id of the drag-drop zone (td, layer or full division maybe)
- this.register = register;
- function register(id, iddd, feedback)
- {
- var fnode = WA.toDOM(id);
- if (fnode == null || WA.toDOM(iddd) == null) // there is no floating to register !
- return null;
-
- var f = new floating(id, iddd, feedback, self);
- try
- {
- // we keep old father
- f.oldParent = fnode.parentNode;
- // we move to our new container
- self.container.appendChild(WA.toDOM(id));
- self.floatings.push(f);
- }
- catch (e)
- {
- f.unload();
- e.printStackTrace();
- }
-
- // We must put the floating as child of our container !
- return f;
- }
-
- this.unregister = unregister;
- function unregister(id)
- {
- var f = null;
- for (var i=0, l=self.floatings.length; i < l; i++)
- {
- if (self.floatings[i].getID() == id)
- {
- f = self.floatings[i];
- break;
- }
- }
- if (f)
- {
- f.unload();
- f.oldParent.appendChild(WA.toDOM(f.getID()));
- self.floatings.splice(i, 1);
- }
- }
-
- // Put each division on original place
- this.restart = restart;
- function restart()
- {
- for (var i=0, l=self.floatings.length; i < l; i++)
- {
- self.floatings[i].restart();
- }
- }
-
- // put division on a new position by program
- this.setPosition = setPosition;
- function setPosition(id, left, top)
- {
- for (var i=0, l=self.floatings.length; i < l; i++)
- {
- if (self.floatings[i].getID() == id)
- {
- self.floatings[i].setPosition(left, top);
- }
- }
- }
-
- this.getWidth = getWidth;
- function getWidth()
- {
- return self.width;
- }
-
- this.getHeight = getHeight;
- function getHeight()
- {
- return self.height;
- }
-
- this.selectormouseover = selectormouseover;
- function selectormouseover(id)
- {
- // we create the list of windows
- // -> [ onclick item of window => window set focus, then close the list ]
-
- // we attach the list to the container
-
- // we listen the list: on mouse out ==> close it
-
-
- }
-
- // thsi function reserve a slot to be minimized, and send back the coords of the slot
- this.reserveSlot = reserveSlot;
- function reserveSlot(id)
- {
- return [30,200,80,20];
- }
-
- this.resize = resize;
- function resize()
- {
- var w = WA.browser.getClientWidth() - (WA.browser.isNS()?2:0);
- var h = WA.browser.getClientHeight() - (WA.browser.isNS()?2:0);
- w = max(w, minwidth);
- h = max(h, minheight);
- self.width = w;
- self.height = h;
- self.container.style.width = w+'px';
- self.container.style.height = h+'px';
- }
-
- // TEMPORAL
- this.show = show;
- function show(id)
- {
- for (var i=0, l=self.floatings.length; i < l; i++)
- {
- WA.toDOM(id).innerHTML += " "+self.floatings[i].getID();
- }
- }
-
- // search for id:
- var container = WA.toDOM(id);
- if (!container)
- {
- // create a full window container
- container = document.createElement("div");
- container.id = self.id;
-
- // take the size of the screen with a minimum size (NS calculates bad the real size for 2 pixels!)
- var w = WA.browser.getClientWidth() - (WA.browser.isNS()?2:0);
- var h = WA.browser.getClientHeight() - (WA.browser.isNS()?2:0);
- w = max(w, minwidth);
- h = max(h, minheight);
- self.width = w;
- self.height = h;
-
- container.style.visibility = 'hidden';
- container.style.position = 'absolute';
- container.style.width = w+'px';
- container.style.height = h+'px';
- container.style.left = '0px';
- container.style.top = '0px';
- container.style.border = '1px Solid #677788';
- if (this.mode == 'jail' || this.mode == 'hide')
- container.style.overflow='hidden';
- else
- container.style.overflow='scroll';
-
- document.body.appendChild(container);
- window.onresize = this.resize;
- }
-
- this.container = container;
-
- if (self.selector == true)
- {
- // create the left-bottom button and properties
- selector = document.createElement("div");
- selector.id = this.id+'_selector';
- selector.style.position = 'absolute';
- selector.style.width = '13px';
- selector.style.height = '13px';
- selector.style.left = '0px';
- selector.style.top = (h-15)+'px';
- selector.style.border='1px Solid black';
- selector.style.backgroundColor='#880000';
- selector.style.color='white';
- selector.style.visibility='visible';
- selector.style.display='inline';
- selector.style.overflow='hidden';
- selector.style.textAlign='center';
- selector.onmouseover = this.selectormouseover;
- container.appendChild(selector);
- WA.browser.setInnerHTML(selector, '*');
- }
-}
-
-// Needed aliases
-WA.Containers.floatingContainer = floatingContainer;
diff --git a/js/containers/gridContainer.js b/js/containers/gridContainer.js
index 30d51d9..b3f1b6b 100644
--- a/js/containers/gridContainer.js
+++ b/js/containers/gridContainer.js
@@ -32,6 +32,9 @@ WA.Containers.gridContainer = function(fatherNode, domID, code, listener)
classnameheadercolumn:'grid-header-column',
classnameheadercolumntitle:'grid-header-column-title',
classnameheadercolumnsizer:'grid-header-column-sizer',
+ classnameordercolumn:'grid-header-column-order',
+ classnameordercolumnasc:'grid-header-column-order-asc',
+ classnameordercolumndesc:'grid-header-column-order-desc',
classnamebody:'grid-body', classnamebodycontent:'grid-body-content',
classnamebodycolumn: 'grid-body-column',
classnamebodycell:'grid-body-cell',
@@ -41,17 +44,21 @@ WA.Containers.gridContainer = function(fatherNode, domID, code, listener)
this.haslistener = (code.attributes.haslistener==='yes');
this.minload = code.attributes.minload?parseInt(code.attributes.minload, 10):50;
this.params = code.attributes.params?'&'+code.attributes.params:'';
-
+ this.hasdd = !!WA.Managers.dd;
+ this.domNodeDrag = null;
+ this.domNodeDrag1 = null;
+ this.domNodesDrag = [];
+
this.columns = {}; // all the columns (zones)
this.lines = []; // all the lines of data
this.data = null; // all the loaded data
this.total = -1;
this.fullloaded = false;
-
+
this.populatemin = 0;
this.populatemax = this.minload-1;
-
+
this.loading = false;
this.toptoload = 0;
this.lineheight = 0;
@@ -80,11 +87,11 @@ WA.Containers.gridContainer = function(fatherNode, domID, code, listener)
this.domNode.appendChild(this.domNodeFooter);
this.domNodeFooterContent = WA.createDomNode('div', domID+'_footercontent', this.classes.classnamefootercontent);
this.domNodeFooter.appendChild(this.domNodeFooterContent);
-
+
this.footer = new WA.Containers.gridContainer.gridFooter(this, domID+'_footer', this.domNodeFooterContent);
-/*
+ /*
this.selectable = (code.attributes.selectable==='yes');
this.changes = (code.attributes.changes==='deferred'); // true = deferred on user click, false: online changes (if haslistener obviously)
this.isselectable = this.selectable; // global selectable indicator (row or any field selectable)
@@ -102,7 +109,7 @@ WA.Containers.gridContainer = function(fatherNode, domID, code, listener)
classnamecelltitle:'grid-celltitle', classnamecelltitleempty:'grid-celltitleempty',
classnamecelltitleasc:'grid-celltitleasc', classnamecelltitledesc:'grid-celltitledesc', classnamecelltitlefiltered:'grid-celltitlefiltered',
classnameline:'grid-line',classnamelineselected:'grid-lineselected',classnamelinenew:'grid-linenew',
-classnamecellmodified:'grid-cellmodified',
+ classnamecellmodified:'grid-cellmodified',
classnameviewicon:'grid-viewicon', classnameselecticon:'gridselecticon', classnameediticon:'grid-editicon',
classnameselectclear:'grid-selectclear', classnameselectall:'gridselectall', classnameselectinverse:'grid-selectinverse',
classnameeditnew:'grid-editnew', classnameeditsave:'grid-editsave', classnameeditdelete:'grid-editdelete'
@@ -114,22 +121,40 @@ classnamecellmodified:'grid-cellmodified',
this.locali = false;
this.localid = null;
-*/
+ */
this.addEvent('start', start);
this.addEvent('stop', stop);
this.addEvent('resize', resize);
-
+
WA.Managers.event.on('mouseover', self.domNode, findcell, true);
WA.Managers.event.on('click', self.domNode, click, true);
WA.Managers.event.on('scroll', self.domNodeBody, scrollBody, true);
+ var fieldorder = '';
+ var direction = '';
+
+/*
+ function doDrag(e) {
+ nodoTarget.style.width = (startWidth + e.clientX - startX) + 'px';
+ nodoDetalle.style.width = (startWidth + e.clientX - startX) + 'px';
+ //endWidth = parseInt(document.defaultView.getComputedStyle(nodoTarget, "").width, 10);
+ //nodoPadre.style.height = (startHeight + e.clientY - startY) + 'px';
+ }
+
+ function stopDrag(e) {
+ document.documentElement.removeEventListener('mousemove', doDrag, false);
+ document.documentElement.removeEventListener('mouseup', stopDrag, false);
+ }
+*/
+
function sendServer(order, code, feedback)
{
if (!self.haslistener)
return;
+
// send information to server based on mode
- var request = WA.Managers.ajax.createRequest(WA.Managers.wa4gl.url + WA.Managers.wa4gl.prelib + self.app.applicationID + WA.Managers.wa4gl.premethod + self.id + WA.Managers.wa4gl.preformat + WA.Managers.wa4gl.format, 'POST', 'Order='+order+(self.params?'&'+self.params:''), feedback, false);
+ var request = WA.Managers.ajax.createRequest(WA.Managers.wa4gl.url + WA.Managers.wa4gl.prelib + self.app.applicationID + WA.Managers.wa4gl.premethod + self.id + WA.Managers.wa4gl.preformat + WA.Managers.wa4gl.format, 'POST', 'Order='+order+(self.params?'&'+self.params:'')+(direction!=''?'&sort='+direction+'&field='+fieldorder:''), feedback, false);
if (request)
{
@@ -154,12 +179,14 @@ classnamecellmodified:'grid-cellmodified',
if (!code.attributes.id)
throw 'Error: the id is missing in the tree construction of '+domID;
- if (!self.firstfield)
+ if (!self.firstfield)stop
self.firstfield = code.attributes.field;
-
+
// we create the column itself
var c = new WA.Containers.gridContainer.gridColumn(self, domID+'_column', self.domNodeHeaderContent, code, notify);
self.columns[code.attributes.field] = c;
+ c.start();
+
var z = new WA.Containers.gridContainer.gridZone(self, domID, self.domNodeBodyContent, code, notify);
self.zones[code.attributes.field] = z;
@@ -190,7 +217,7 @@ classnamecellmodified:'grid-cellmodified',
self.app.destroyTree(ldomID[2]);
delete self.zones[ldomID[2]];
-
+
self.columns[ldomID[2]].destroy();
delete self.columns[ldomID[2]];
@@ -223,15 +250,23 @@ classnamecellmodified:'grid-cellmodified',
{
}
-
+
function scrollBody(event)
{
if (!self.lineheight)
+ {
+ // this should not happen: when we get the focus for the 1rst time, the height is fixed if it was not
return;
+ }
var pos = self.domNodeBody.scrollTop;
var line = Math.floor(pos / self.lineheight);
self.populatemin = line;
self.populatemax = line + self.minload - 1;
+
+ // Header scroll
+ var nHead = WA.toDOM(self.domNode.id + '_header');
+ nHead.scrollLeft = self.domNodeBody.scrollLeft;
+
fillData();
}
@@ -239,14 +274,14 @@ classnamecellmodified:'grid-cellmodified',
{
self.loading = false;
removeLoading();
-
+
self.countload = 0;
var code = WA.JSON.decode(r.responseText);
- if ((code.row.length || Object.keys(code.row).length) && !self.data)
+ self.total = code.total;
+ if (code.row.length && !self.data)
{
self.data = code.row;
- self.total = code.total;
}
else
{
@@ -259,14 +294,15 @@ classnamecellmodified:'grid-cellmodified',
}
if (self.total > 0)
fillData();
+ else
+ self.footer.populate();
}
function fillData()
{
- // 2 levels: lines and data.
+ // 2 levels: lines and data.
// If lines are not defined, try to define them and fill
// if data is not set, try to load it (delayed)
-
var mintoload = -1;
var maxtoload = -1;
var settoload = [];
@@ -274,19 +310,19 @@ classnamecellmodified:'grid-cellmodified',
for (var i = self.populatemin; i <= self.populatemax; i++)
{
// we are at the end of the total lines, nothing more to do
- if (self.total != -1 && i >= self.total)
+ if (self.total > 0 && i >= self.total)
break;
// If the line has already been populated, nothing to do
if (self.lines[i])
continue;
-
+
// If the data exists, just populate it
if (self.data && self.data[i])
{
createLine(self.data[i], i);
continue;
}
-
+
// creates the array to load
if (mintoload == -1) mintoload = maxtoload = i;
else if (maxtoload == i-1) maxtoload++;
@@ -302,7 +338,7 @@ classnamecellmodified:'grid-cellmodified',
putLoading();
// put "Loading...."
}
-
+
if (mintoload != -1 && !self.loading && self.serverlistener)
{
if (self.countload++ > 3)
@@ -318,7 +354,7 @@ classnamecellmodified:'grid-cellmodified',
adjustHeight();
self.footer.populate();
}
-
+
function createLine(data, index)
{
// desplazar esto
@@ -326,18 +362,17 @@ classnamecellmodified:'grid-cellmodified',
self.domNodeBodyContent.style.width = size + 'px';
// first cell of first line will set lineheight (very important !)
- var line = new WA.Containers.gridContainer.gridLine(self, self.domID+'_l-'+index, data, index);
+ var line = new WA.Containers.gridContainer.gridLine(self, self.domID+'_line_'+index, data, index);
line.start();
self.lines[index] = line;
-
return line;
}
-
+
function adjustHeight()
{
if (!self.lineheight)
return;
-
+
// adjust the height of the container
// based on data.total
// get the height of a row
@@ -354,30 +389,30 @@ classnamecellmodified:'grid-cellmodified',
self.lines[i].destroy();
for (var i in self.zones)
WA.browser.setInnerHTML(self.zones[i].domNode, '');
-// WA.browser.setInnerHTML(self.domNodeBodyContent, '');
+ //WA.browser.setInnerHTML(self.domNodeBodyContent, '');
self.linecount = 0;
self.lines = [];
}
function putLoading()
{
-
+
}
-
+
function removeLoading()
{
-
+
}
-
-
+
+
function findcell(event)
{
// gets the target and hover the things
-
+
var node = event.target;
var column = node.column;
var line = node.line;
-
+
// change class
if (currentcolumn)
{
@@ -405,19 +440,14 @@ classnamecellmodified:'grid-cellmodified',
currentline = line;
}
}
-
+
function click(event)
{
- var node = event.target;
- var column = node.column;
- var line = node.line;
-
- // send data line
- self.propagate('click', {column:column,line:line,data:self.data[line]});
+ return;
}
-
-
-
+
+
+
// ========================================================================================
// system functions, called ONLY BY 4GL
// constructor is called when creating the object.
@@ -429,9 +459,15 @@ classnamecellmodified:'grid-cellmodified',
this.start = start;
function start()
{
+ if (self.hasdd)
+ {
+ console.log("REGISTRANDO GROUPO", self.domID, self.domNodeBody);
+ WA.Managers.dd.registerGroup(self.domID, 'caller', false, self.domID, null);
+ }
+
self.countload = 0;
- fillData();
self.footer.start();
+ fillData();
}
this.reload = reload;
@@ -449,6 +485,22 @@ classnamecellmodified:'grid-cellmodified',
{
if (!WA.Containers.gridContainer.source.resize.call(self))
return;
+
+ if (!self.lineheight && self.lines[0])
+ {
+ self.lineheight = WA.browser.getNodeOuterHeight(self.lines[0].cells[self.firstfield]);
+ // reposition all column heights
+ adjustHeight();
+ // adjust all tops of all existing cells
+ for (var i = 0, l = self.lines.length; i < l; i++)
+ {
+ if (self.lines)
+ {
+ for (var j in self.lines[i].cells)
+ self.lines[i].cells[j].style.top = (i * self.lineheight) + 'px';
+ }
+ }
+ }
// calculate width and height of nodes
var size = 0;
@@ -465,13 +517,15 @@ classnamecellmodified:'grid-cellmodified',
{
height = self.total * WA.browser.getNodeHeight(self.lines[0].cells[self.firstfield]);
}
-
self.domNodeBodyContent.style.height = height + 'px';
}
this.stop = stop;
function stop()
{
+ if (self.hasdd)
+ WA.Managers.dd.unregisterGroup(self.domID);
+
if (self.running != 1 && self.running != 2)
return;
self.running = 4;
@@ -510,13 +564,200 @@ classnamecellmodified:'grid-cellmodified',
self = null;
}
+ function setLineNodeDrag(lineid, m)
+ {
+ var nodes = document.querySelectorAll("[id^='" + lineid + "']");
+ var l = m.dragdocumentleft;
+ for(var i=0; i < nodes.length; i++)
+ {
+ var w = parseInt(/\d+/g.exec(nodes[i].parentElement.style.width)[0]);
+ self.domNodeDrag1 = nodes[i].cloneNode(true);
+ self.domNodeDrag1.className += ' dragged';
+ // we get absolute coords and set them
+ self.domNodeDrag1.style.position = 'absolute';
+ self.domNodeDrag1.style.left = l +'px';
+ self.domNodeDrag1.style.top = m.dragdocumenttop + 'px';;
+ self.domNodeDrag1.style.width = w + 'px';
+ self.domNodeDrag1.style.height = m.mainheight + 'px';
+ self.domNodeDrag1.style.zIndex = 2;
+
+ l += w;
+ // we append to the main document the DOM
+ document.body.appendChild(self.domNodeDrag1);
+
+ //Save reference in array
+ self.domNodesDrag.push(self.domNodeDrag1);
+ }
+ }
+
+ function lineNodeDrag(m)
+ {
+ for(var i=0; ii;i++)
+ {
+ top = WA.browser.getNodeDocumentTop(zone[i]);
+ bottom = WA.browser.getNodeDocumentTop(zone[i]) + WA.browser.getNodeHeight(zone[i]);
+ var left = WA.browser.getNodeDocumentLeft(zone[i]);
+ var right = WA.browser.getNodeDocumentLeft(zone[i]) + WA.browser.getNodeWidth(zone[i]);
+
+ if((ypointer >= top && ypointer <= bottom && xpointer >= left && xpointer <= right))
+ {
+ onzone = zone[i];
+ break;
+ }
+ };
+
+ if (onzone) {
+
+ self.dropmode = 0;
+ if(onzone.id === lineid)
+ {
+ //message = "No se puede mover aquí " + self.domNodeDrag.id;
+ return;
+ }
+
+ onzone.style.backgroundColor = 'red';
+ if (ypointer > top && ypointer < top + (bottom - top) / 1.3) {
+ // before
+ message = "Mover ANTES de " + onzone.id;
+ self.dropmode = 1;
+ }
+
+ if (ypointer > top + (bottom - top) * 2 / 3 && ypointer < bottom) {
+ // after
+ message = "Mover DESPUES de " + onzone.id;
+ self.dropmode = 3;
+ }
+ self.dropid = onzone.id;
+ self.domNodeMessage.innerHTML = message;
+ }
+ if (self.lastonzone && self.lastonzone != onzone) {
+ self.lastonzone.style.backgroundColor = '';
+ }
+ self.lastonzone = onzone;
+ break;
+ case 'drop':
+ // destroy the hover node
+ document.body.removeChild(self.domNodeDrag);
+ destroyDomNodeDrag();
+
+ if (self.lastonzone) {
+ self.lastonzone.style.backgroundColor = '';
+ }
+ // send the order to the server
+ if (self.dropmode > 0) {
+ sendServer('move', { id: lineid, toid: self.dropid, mode: self.dropmode }, moveresponse);
+ }
+ // reload anything
+ self.domNodeMessage = null;
+ self.domNodeDrag = null;
+ self.dropmode = 0;
+ self.dropid = null;
+ self.lastonzone = null;
+ break;
+ }
+ }
+
+ function moveresponse(request) {
+ self.loading = false;
+ removeLoading();
+
+ self.countload = 0;
+ var code = WA.JSON.decode(request.responseText);
+
+ self.total = code.total;
+ if (code.row.length && !self.data)
+ {
+ self.data = code.row;
+ }
+ else
+ {
+ if (!self.data)
+ self.data = [];
+ for (var i in code.row)
+ {
+ self.data[parseInt(i, 10)] = code.row[i];
+ }
+ }
+ if (self.total > 0)
+ fillData();
+ else
+ self.footer.populate();
+ }
+
+/*
+
// ================================================================
// move divisions by program and mouse
this.startdrag = startdrag;
function startdrag(sizerID, size, event, group, object, zone, data)
{
-
self.movingsize = size;
self.movingID = sizerID;
//
@@ -539,6 +780,7 @@ classnamecellmodified:'grid-cellmodified',
self.movingsize = null;
self.movingID = null;
}
+*/
this.resizecolumns = resizecolumns;
function resizecolumns()
@@ -556,19 +798,18 @@ classnamecellmodified:'grid-cellmodified',
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
function scroll(e)
{
var left = WA.browser.getNodeScrollLeft(self.domNodeBody);
@@ -690,12 +931,11 @@ classnamecellmodified:'grid-cellmodified',
function quickSort(lo0, hi0, comp, field)
{
// local ONLY available if full data loaded !
-
var lo = lo0;
var hi = hi0;
var value;
- if ( hi0 > lo0)
+ if ( hi0 > lo0 )
{
value = self.data[ Math.ceil((lo0 + hi0 ) / 2) ][field];
while( lo <= hi )
@@ -724,7 +964,19 @@ classnamecellmodified:'grid-cellmodified',
this.reorder = reorder;
function reorder(field, asc)
{
- for (var i in self.columns)
+ if(self.total<=self.populatemax && asc)
+ {
+ self.unpopulate();
+ self.quickSort(0, self.data.length-1, (asc=='asc'?self.compasc:self.compdesc), field);
+ fillData();
+ }else{
+ fieldorder = field;
+ direction = asc;
+ reload();
+ }
+
+
+ /*for (var i in self.columns)
{
if (self.columns[i].id != field && self.columns[i].order != 0)
{
@@ -732,9 +984,11 @@ classnamecellmodified:'grid-cellmodified',
self.columns[i].setTitle();
}
}
+
self.unpopulate();
self.quickSort(0, self.data.length-1, (asc?self.compasc:self.compdesc), field);
- self.populate();
+ self.populate();*/
+
}
@@ -781,7 +1035,7 @@ classnamecellmodified:'grid-cellmodified',
}
}
-
+
parseTemplates(code);
parseRenders(code);
parseData(code);
@@ -795,20 +1049,19 @@ WA.extend(WA.Containers.gridContainer, WA.Managers.wa4gl._container);
WA.Containers.gridContainer.gridColumn = function(father, domID, container, code, listener)
{
var self = this;
-
this.classname = code.attributes.classname!=undefined?code.attributes.classname:father.classes.classnameheadercolumn;
-
WA.Containers.gridContainer.gridColumn.sourceconstructor.call(this, father, domID, code, 'div', { classname:this.classname }, listener);
// DOM
this.container = container;
container.appendChild(this.domNode);
this.domNode.style.width = (code.attributes.size?code.attributes.size:'300') + 'px';
- this.domNode.style.display = ''; // is visible
-
+ this.domNode.style.display = ''; // is visible
this.classnametitle = code.attributes.classnametitle!=undefined?code.attributes.classnametitle:father.classes.classnameheadercolumntitle;
this.classnamesizer = code.attributes.classnamesizer!=undefined?code.attributes.classnamesizer:father.classes.classnameheadercolumnsizer;
-
+ this.classnameorder = code.attributes.classnameorder!=undefined?code.attributes.classnameorder:father.classes.classnameordercolumn;
+ this.classnameorderasc = code.attributes.classnameorderasc!=undefined?code.attributes.classnameorderasc:father.classes.classnameordercolumnasc;
+ this.classnameorderdesc = code.attributes.classnameorderdesc!=undefined?code.attributes.classnameorderdesc:father.classes.classnameordercolumndesc;
this.field = code.attributes.field;
this.sizemin = code.attributes.sizemin?code.attributes.sizemin:0;
this.sizemax = code.attributes.sizemax?code.attributes.sizemax:undefined;
@@ -822,16 +1075,19 @@ WA.Containers.gridContainer.gridColumn = function(father, domID, container, code
*/
this.size = WA.browser.getNodeWidth(this.domNode);
+ this.resizeable = code.attributes.resizeable == "yes";
+ this.sortable = code.attributes.sortable == "yes";
+ this.domNodeSizer = null;
+ this.startWidth = 0;
// selector, selector pannel, sizer, all hidden
- if (code.attributes.resizeable)
+ if (self.resizeable)
{
- this.domNodeSizer = WA.createDomNode('div', domID+'_sizer', this.classnamesizer);
- this.domNode.appendChild(this.domNodeSizer);
+ self.domNodeSizer = WA.createDomNode('div', domID+'_sizer', self.classnamesizer);
+ self.domNode.appendChild(self.domNodeSizer);
}
- else
- this.domNodeSizer = null;
+ this.orderable = code.attributes.orderable == "yes";
this.domNodeTitle = WA.createDomNode('div', domID+'_titletext', this.classnametitle);
this.domNodeTitle.innerHTML = code.attributes.title;
this.domNode.appendChild(this.domNodeTitle);
@@ -839,21 +1095,19 @@ WA.Containers.gridContainer.gridColumn = function(father, domID, container, code
this.setTitle = setTitle;
function setTitle()
{
- return;
-
- var title = self.code.attributes.title;
- switch(self.order)
- {
- case 1: title = '' + title; break;
- case 2: title = '' + title; break;
- default: title = '' + title; break;
- }
- if (self.filtered)
- {
- title = '' + title;
- }
-
- WA.browser.setInnerHTML(self.domNodeTitle, title);
+ if(self.sortable){
+ var title = self.code.attributes.title;
+ switch(self.order)
+ {
+ case 1: title = title + ''; break;
+ case 2: title = title + ''; break;
+ default: title = title + ''; break;
+ }
+ if (self.filtered)
+ {
+ title = '' + title;
+ }
+ WA.browser.setInnerHTML(self.domNodeTitle, title);}
}
this.sethover = sethover;
@@ -861,13 +1115,13 @@ WA.Containers.gridContainer.gridColumn = function(father, domID, container, code
{
self.domNode.className = self.classname + (flag?' hover':'');
}
-
+
this.setSize = setSize;
function setSize(size)
{
return;
-
-
+
+
if (size < self.sizemin)
size = self.sizemin;
if (self.sizemax != 0 && size > self.sizemax)
@@ -879,23 +1133,56 @@ WA.Containers.gridContainer.gridColumn = function(father, domID, container, code
this.click = click;
function click()
+ {
+ if(self.sortable)
+ {
+ if (self.pleasenoclick)
+ {
+ self.pleasenoclick = false;
+ return;
+ }
+
+ self.order++;
+ if (self.order > 2)
+ self.order = 0;
+
+ var d = null;
+ switch(self.order){
+ case 1:
+ d = 'asc';
+ break;
+ case 2:
+ d = 'desc';
+ break;
+ default:
+ d = null;
+ }
+ self.father.reorder(self.field, d);
+ self.setTitle();
+ }
+ }
+
+ this.reorder = reorder;
+ function reorder(field, asc)
{
return;
- if (self.pleasenoclick)
+
+ for (var i in self.columns)
{
- self.pleasenoclick = false;
- return;
+ if (self.columns[i].id != field && self.columns[i].order != 0)
+ {
+ self.columns[i].order = 0;
+ self.columns[i].setTitle();
+ }
}
- self.order ++;
- if (self.order > 2)
- self.order = 1;
- self.container.reorder(self.id, self.order==1?true:false);
- self.setTitle();
+ self.unpopulate();
+ self.quickSort(0, self.data.length-1, (asc?self.compasc:self.compdesc), field);
+ self.populate();
}
-
+
this.clicksizer = clicksizer;
- function clicksizer()
+ function clicksizer(order, id1, lineid, zone, metrics)
{
return;
@@ -907,40 +1194,51 @@ WA.Containers.gridContainer.gridColumn = function(father, domID, container, code
}
this.move = move;
- function move(type, event, group, object, zone, data)
+ function move(order, id1, lineid, zone, metrics)
{
- return;
+ var xpointer = metrics.dragleft - 172;
+ var node = WA.toDOM(lineid).parentNode;
- if (type == 'start')
- {
- self.pleasenoclick = true;
- var size = WA.browser.getNodeWidth(self.domNode);
- self.container.startdrag(self.id, size, event, group, object, zone, data);
- }
- else if (type == 'drag' || type == 'drop')
- {
- self.container.drag(event, group, object, zone, data);
- }
- if (type == 'drop')
- {
- self.container.drop(event, group, object, zone, data);
- }
+ switch (order) {
+ case 'start':
+ self.domNodeSizer.className += ' dragged';
+ self.domNodeSizer.style.position = 'absolute';
+ self.domNodeSizer.style.left = metrics.dragdocumentleft + 'px';
+ self.domNodeSizer.style.width = metrics.mainwidth + 'px';
+ break;
+ case 'drag':
+ self.domNodeSizer.style.left = xpointer + 'px';
+ node.style.width = xpointer + 1 + 'px';
+ var id = /^([^w]+_\d)/;
+ WA.toDOM(id.exec(self.domNodeSizer.id)[0]).style.width = xpointer + 1 + 'px';
+ break;
+ case 'drop':
+ break;
+ }
}
+
this.start = start;
function start()
{
- return;
-
-
- WA.Managers.event.on('click', self.domNodeTitle, self.click, true);
- WA.Managers.event.on('click', self.domNodeSizer, self.clicksizer, true);
+ if(self.sortable)
+ {
+ self.order = 0;
+ self.setTitle();
+ WA.Managers.event.on('click', self.domNode, self.click, true);
+ }
- if (self.sizeable)
+ // Sizer group and object
+ if(self.resizeable)
{
- WA.Managers.dd.registerGroup(self.domID+'_sizer', 'caller', false, null, self.move);
- WA.Managers.dd.registerObject(self.domID+'_sizer', self.domID+'_sizer', self.domID+'_sizer', null);
+ if (self.father.hasdd) {
+ WA.Managers.dd.registerGroup(self.domNodeSizer, 'caller', true, self.father.domID, move);
+ WA.Managers.dd.registerObject(self.domNodeSizer, self.domNodeSizer, self.domNodeSizer, null);
+ }
}
+
+ return;
+ WA.Managers.event.on('click', self.domNodeSizer, self.clicksizer, true);
}
this.stop = stop;
@@ -988,6 +1286,7 @@ WA.Containers.gridContainer.gridColumn = function(father, domID, container, code
self.domNode = null;
self.domNodeTitle = null;
self.domNodeSizer = null;
+ self.domNodeOrder = null;
self.domNodeContainer = null;
self.code = null;
self.notify = null;
@@ -997,7 +1296,6 @@ WA.Containers.gridContainer.gridColumn = function(father, domID, container, code
self = null;
}
- this.setTitle();
}
WA.extend(WA.Containers.gridContainer.gridColumn, WA.Managers.wa4gl._zone);
@@ -1011,10 +1309,10 @@ WA.Containers.gridContainer.gridZone = function(father, domID, container, code,
var self = this;
this.classname = code.attributes.classname!=undefined?code.attributes.classname:father.classes.classnamebodycolumn;
-
+
WA.Containers.gridContainer.gridZone.sourceconstructor.call(this, father, domID, code, 'div', { classname:this.classname }, listener);
this.domNode.style.position = 'relative';
-
+
this.field = code.attributes.field;
this.classnamecell = father.classes.classnamebodycell;
@@ -1029,7 +1327,7 @@ WA.Containers.gridContainer.gridZone = function(father, domID, container, code,
{
self.domNode.className = self.classname + (flag?' hover':'');
}
-
+
this.setData = setData;
function setData(data)
{
@@ -1082,6 +1380,13 @@ WA.Containers.gridContainer.gridLine = function(father, domID, data, index)
self.cells[i].className = self.father.zones[i].classnamecell + (flag?' hover':'');
}
}
+
+ this.moving = moving;
+ function moving(order, id1, id2, zone, metrics) {
+
+ self.moving = true;
+ self.father.moving(order, id2, metrics);
+ }
function createCell(father, content, data, c)
{
@@ -1090,10 +1395,10 @@ WA.Containers.gridContainer.gridLine = function(father, domID, data, index)
father.domNode.appendChild(domNodeCell);
domNodeCell.column = c;
domNodeCell.line = self.index;
-
+
if (!self.father.lineheight)
self.father.lineheight = WA.browser.getNodeOuterHeight(domNodeCell);
-
+
// top should be index * lineheight
domNodeCell.style.position = 'absolute';
domNodeCell.style.left = '0';
@@ -1101,7 +1406,7 @@ WA.Containers.gridContainer.gridLine = function(father, domID, data, index)
domNodeCell.style.width = '100%';
// Considerar los TEMPLATES tambien
-
+
if (father.render)
{
eval( 'var cdata = ' + father.render+'(father.format, content, data);' );
@@ -1110,6 +1415,14 @@ WA.Containers.gridContainer.gridLine = function(father, domID, data, index)
else
WA.browser.setInnerHTML(domNodeCell, content);
+ cl = self.father.columns[c];
+ if (cl.orderable) {
+ domNodeCell.style.cursor = 'pointer';
+ if (self.father.hasdd) {
+ console.log("REGISTRANDO OBJECT", self.father.domID, domNodeCell);
+ WA.Managers.dd.registerObject(self.father.domID, domNodeCell, domNodeCell, moving, null);
+ }
+ }
return domNodeCell;
}
@@ -1123,15 +1436,15 @@ WA.Containers.gridContainer.gridLine = function(father, domID, data, index)
self.cells[i] = createCell(self.father.zones[i], '', data, i);
}
}
-
-
-
-
+
+
+
+
this.start = start;
function start()
{
return;
-
+
for (var i in self.cells)
WA.Managers.event.on('click', self.cells[i], self.click, true);
self.running = 2;
@@ -1141,7 +1454,7 @@ WA.Containers.gridContainer.gridLine = function(father, domID, data, index)
function stop()
{
return;
-
+
self.running = 0;
for (var i in self.cells)
WA.Managers.event.off('click', self.cells[i], self.click, true);
@@ -1151,7 +1464,7 @@ WA.Containers.gridContainer.gridLine = function(father, domID, data, index)
function select()
{
return;
-
+
if (self.selected)
return;
self.selected = true;
@@ -1162,7 +1475,7 @@ WA.Containers.gridContainer.gridLine = function(father, domID, data, index)
function unselect()
{
return;
-
+
if (!self.selected)
return;
self.selected = false;
@@ -1173,7 +1486,7 @@ WA.Containers.gridContainer.gridLine = function(father, domID, data, index)
function invert()
{
return;
-
+
if (self.selected)
self.unselect();
else
@@ -1237,7 +1550,7 @@ WA.Containers.gridContainer.gridLine = function(father, domID, data, index)
function blur()
{
return;
-
+
var data = self.container.zones[this.column].getData();
self.container.zones[this.column].hide();
@@ -1267,7 +1580,7 @@ WA.Containers.gridContainer.gridLine = function(father, domID, data, index)
self.cells = null;
self = null;
}
-
+
populate();
}
@@ -1288,14 +1601,14 @@ WA.Containers.gridContainer.gridLine = function(father, domID, data, index)
WA.Containers.gridContainer.gridFooter = function(father, domID, container)
{
var self = this;
-
+
this.father = father;
this.container = container;
this.domNodeQuantityTitle = WA.createDomNode('div', domID+'_quantitytitle', 'quantity-title');
this.domNodeQuantityTitle.innerHTML = 'Cantidad: ';
this.container.appendChild(this.domNodeQuantityTitle);
-
+
this.domNodeQuantity = WA.createDomNode('div', domID+'_quantity', 'quantity');
this.container.appendChild(this.domNodeQuantity);
/*
@@ -1465,7 +1778,7 @@ WA.Containers.gridContainer.gridFooter = function(father, domID, container)
{
self.container.saveall();
}
-
+
this.populate = populate;
function populate()
{
diff --git a/js/containers/groupContainer.js b/js/containers/groupContainer.js
index 9b418bb..e26843c 100644
--- a/js/containers/groupContainer.js
+++ b/js/containers/groupContainer.js
@@ -79,10 +79,30 @@
WA.Containers.groupContainer = function(fatherNode, domID, code, listener)
{
var self = this;
- WA.Containers.groupContainer.sourceconstructor.call(this, fatherNode, domID, code, 'form', { classname:'group' }, listener);
+
+ this.maingroup = code.attributes.maingroup ? code.attributes.maingroup : undefined;
+ if (this.maingroup)
+ WA.Containers.groupContainer.sourceconstructor.call(this, fatherNode, domID, code, 'div', { classname: 'group' }, listener);
+ else
+ WA.Containers.groupContainer.sourceconstructor.call(this, fatherNode, domID, code, 'form', { classname:'group' }, listener);
this.domNodeForm = this.domNode;
+
+ this.domNodeTitle = WA.createDomNode('div', domID + '_title', 'title');
+ this.domNodeForm.appendChild(this.domNodeTitle);
+
this.domNode = WA.createDomNode('fieldset', null, null);
this.domNodeForm.appendChild(this.domNode);
+ if (this.maingroup) {
+ this.domNodeRecords = WA.createDomNode('div', null, null);
+ this.domNode.appendChild(this.domNodeRecords);
+ // REGISTER THIS FORM INTO TE PIANEMFORM
+ var group = null;
+ if (this.father.father.code.attributes.type == "groupContainer") {
+ group = this.father.father;
+ group.registerForm(this.xdomID[2], this);
+ }
+ }
+
this.zoneNotify = null;
@@ -108,11 +128,14 @@ WA.Containers.groupContainer = function(fatherNode, domID, code, listener)
this.authmodes[i] = (this.code.attributes.authmodes?this.code.attributes.authmodes.indexOf(''+i)!=-1:true);
}
+ this.subForms = {};
this.actionlistener = null;
this.fields = [];
this.data = {};
this.dataloaded = false;
this.datatemporal = {};
+ this.tempkey = 1;
+ this.template = "";
this.error = null;
this.help = null;
@@ -125,47 +148,48 @@ WA.Containers.groupContainer = function(fatherNode, domID, code, listener)
this.title = ['','Insert','Update','Delete','View'];
this.result = ['','Insert ok','Update ok','Delete ok'];
- for (var i = 0, l = code.children.length; i < l; i++)
+ if (code.children)
{
- if (code.children[i].tag == 'dataset' && code.children[i].data)
+ for (var i = 0, l = code.children.length; i < l; i++)
{
- try
+ if (code.children[i].tag == 'dataset' && code.children[i].data)
{
- self.data = WA.JSON.decode(code.children[i].data);
- if (self.data[self.varkey] == self.currentkey)
- self.dataloaded = true;
- }
- catch (e)
- {
- WA.debug.log('Error on the dataset of groupContainer:', 1);
- WA.debug.log(e, 1);
- // what do we do if there is an error in the dataset ? error ? alert ? debug ?
+ try
+ {
+ self.data = WA.JSON.decode(code.children[i].data);
+ if (self.data[self.varkey] == self.currentkey)
+ self.dataloaded = true;
+ }
+ catch (e)
+ {
+ WA.debug.log('Error on the dataset of groupContainer:', 1);
+ WA.debug.log(e, 1);
+ // what do we do if there is an error in the dataset ? error ? alert ? debug ?
+ }
+ continue;
}
- continue;
- }
- if (code.children[i].tag == 'alertmessage')
- self.mainerroralert = code.children[i].data;
- if (code.children[i].tag == 'servermessage')
- self.servererroralert = code.children[i].data;
- if (code.children[i].tag == 'titleinsert')
- self.title[1] = code.children[i].data;
- if (code.children[i].tag == 'titleupdate')
- self.title[2] = code.children[i].data;
- if (code.children[i].tag == 'titledelete')
- self.title[3] = code.children[i].data;
- if (code.children[i].tag == 'titleview')
- self.title[4] = code.children[i].data;
- if (code.children[i].tag == 'insertok')
- self.result[1] = code.children[i].data;
- if (code.children[i].tag == 'updateok')
- self.result[2] = code.children[i].data;
- if (code.children[i].tag == 'deleteok')
- self.result[3] = code.children[i].data;
- }
-
-
- this.domNodeTitle = WA.createDomNode('div', domID+'_title', 'title');
- this.domNode.appendChild(this.domNodeTitle);
+ if (code.children[i].tag == 'alertmessage')
+ self.mainerroralert = code.children[i].data;
+ if (code.children[i].tag == 'servermessage')
+ self.servererroralert = code.children[i].data;
+ if (code.children[i].tag == 'titleinsert')
+ self.title[1] = code.children[i].data;
+ if (code.children[i].tag == 'titleupdate')
+ self.title[2] = code.children[i].data;
+ if (code.children[i].tag == 'titledelete')
+ self.title[3] = code.children[i].data;
+ if (code.children[i].tag == 'titleview')
+ self.title[4] = code.children[i].data;
+ if (code.children[i].tag == 'insertok')
+ self.result[1] = code.children[i].data;
+ if (code.children[i].tag == 'updateok')
+ self.result[2] = code.children[i].data;
+ if (code.children[i].tag == 'deleteok')
+ self.result[3] = code.children[i].data;
+ if (code.children[i].tag == 'template')
+ self.template = code.children[i].data;
+ }
+ }
this.domNodeMessage = WA.createDomNode('div', domID+'_message', 'message');
this.domNode.appendChild(this.domNodeMessage);
@@ -464,6 +488,17 @@ WA.Containers.groupContainer = function(fatherNode, domID, code, listener)
checkClass();
}
+ this.registerForm = registerForm;
+ function registerForm(id, form) {
+ console.log("REGISTER SUBFORM", id)
+ self.subForms[id] = form;
+ }
+
+ this.unregisterForm = unregisterForm;
+ function unregisterForm(field) {
+ // self.fields.push(field);
+ }
+
this.registerField = registerField;
function registerField(field)
{
@@ -542,6 +577,7 @@ WA.Containers.groupContainer = function(fatherNode, domID, code, listener)
this.doInsert = doInsert;
function doInsert()
{
+ console.log("doInsert", self.lastkey, self.currentkey, self.domID);
// we keep the current key for if we cancel the insert mode
self.lastkey = self.currentkey;
self.currentkey = null;
@@ -678,6 +714,12 @@ WA.Containers.groupContainer = function(fatherNode, domID, code, listener)
stopLoading();
}
+ function fillTemplate(templateString, templateVars) {
+ var tmp = eval("WA.templater`" + templateString + "`;");
+ console.log(templateString, templateVars);
+ return tmp(templateVars);
+ }
+
// basic group options
this.doSubmit = doSubmit;
function doSubmit()
@@ -705,6 +747,38 @@ WA.Containers.groupContainer = function(fatherNode, domID, code, listener)
return;
}
+ // IF we are into sub-group, we only keep the info local until the main group makes the update
+ if (self.maingroup) {
+ var datatemporal = {};
+ for (var i = 0, l = self.fields.length; i < l; i++) {
+ if (self.fields[i].formtype != 'field')
+ continue;
+ if (!self.fields[i].editable || !self.fields[i].edition)
+ continue;
+ var values = self.fields[i].getValues();
+ // if values is an array, please loop !
+ datatemporal[self.fields[i].id] = values;
+ }
+ datatemporal[self.varkey] = self.currentkey;
+ datatemporal[self.varmode] = self.mode;
+ if (!self.currentkey) // new record
+ {
+ self.datatemporal['new|' + self.tempkey] = datatemporal;
+ self.tempkey++;
+ } else {
+ self.datatemporal[self.currentkey] = datatemporal;
+ }
+ // PRINT the saved records
+ text = "";
+ for (var i in self.datatemporal) {
+ text += fillTemplate(self.template, self.datatemporal[i]);
+ }
+ self.domNodeRecords.innerHTML = text;
+
+ console.log("REC saved locally", self.datatemporal);
+ return;
+ }
+
// we put the "loading" stuff
startLoading();
@@ -732,6 +806,19 @@ WA.Containers.groupContainer = function(fatherNode, domID, code, listener)
request.addParameter(self.fields[i].id, values);
self.datatemporal[self.fields[i].id] = values;
}
+ // SUB GROUPS
+ if (self.subForms) {
+ for (var i in self.subForms) {
+ for (var j in self.subForms[i].datatemporal)
+ {
+ for (var k in self.subForms[i].datatemporal[j])
+ {
+ request.addParameter(i + '|' + j + '|' + k, self.subForms[i].datatemporal[j][k]);
+ }
+ }
+ }
+ }
+
if (self.mode != 1)
request.addParameter(self.varkey, self.currentkey);
request.addParameter(self.varmode, self.mode);
@@ -793,14 +880,13 @@ WA.Containers.groupContainer = function(fatherNode, domID, code, listener)
this.setMessages = setMessages;
function setMessages(params)
{
- console.log("setMessages", params);
// 3 ways to put messages:
// 1. is POPUP
// 2. is any error domID
// 3. is any field with its own error
if (!params || !params.messages)
{
- showMessage(self.servererroralert, false);
+ showMessage(self.servererroralert + (params.message?"
"+params.message.text:""), false);
return;
}
var popup = '';
@@ -824,6 +910,20 @@ WA.Containers.groupContainer = function(fatherNode, domID, code, listener)
alert(popup);
}
+ this.getValues = getValues;
+ function getValues()
+ {
+ var values = {};
+ for (var i=0, l=self.fields.length; i < l; i++)
+ {
+ if (self.fields[i].formtype == 'field')
+ {
+ values[self.fields[i].id] = self.fields[i].getValues();
+ }
+ }
+ return values;
+ }
+
this.getFieldValue = getFieldValue;
function getFieldValue(fieldid)
{
diff --git a/js/containers/tabContainer.js b/js/containers/tabContainer.js
index 4cb7a19..3a37f05 100644
--- a/js/containers/tabContainer.js
+++ b/js/containers/tabContainer.js
@@ -379,6 +379,9 @@ WA.Containers.tabContainer = function(domNodeFather, domID, code, listener)
function stop()
{
+ if (self.hasdd)
+ WA.Managers.dd.unregisterGroup(self.domID);
+
WA.Managers.event.off('click', self.domNodeLeft, self.clickleft, true);
WA.Managers.event.off('click', self.domNodeRight, self.clickright, true);
WA.Managers.event.off('click', self.domNodeSelect, self.clickselect, true);
diff --git a/js/containers/treeContainer.js b/js/containers/treeContainer.js
index 4131029..e679609 100644
--- a/js/containers/treeContainer.js
+++ b/js/containers/treeContainer.js
@@ -29,8 +29,15 @@ WA.Containers.treeContainer = function(fatherNode, domID, code, listener)
this.data = null; // all the data rows we can use for this tree
this.loaded = false; // the data has been loaded in first instance
this.countload = 0; // how many time we try to load: >3 throw error
+ this.params = code.attributes.params?'&'+code.attributes.params:'';
+ this.changeorder = this.code.attributes.changeorder ? this.code.attributes.changeorder != "no" : false;
+
+ this.hasdd = !!WA.Managers.dd;
+ this.domNodeDrag = null;
this.addEvent('start', start);
+ this.addEvent('poststart', poststart);
+ this.addEvent('stop', stop);
/* SYSTEM METHODS */
@@ -111,6 +118,18 @@ WA.Containers.treeContainer = function(fatherNode, domID, code, listener)
fillData();
}
+ function poststart() {
+ if (self.hasdd && self.changeorder) {
+ WA.Managers.dd.registerGroup(self.domID, 'caller', false, self.domID, null);
+ }
+ }
+
+ function stop() {
+ if (self.hasdd && self.changeorder) {
+ WA.Managers.dd.unregisterGroup(self.domID);
+ }
+ }
+
this.destroy = destroy;
function destroy(fast)
{
@@ -141,13 +160,18 @@ WA.Containers.treeContainer = function(fatherNode, domID, code, listener)
fillData();
}
- function getData(r)
+ function getDataObject(data)
{
- self.data = WA.JSON.decode(r.responseText);
+ self.data = data;
self.loaded = true;
fillData();
}
+ function getData(r)
+ {
+ getDataObject(WA.JSON.decode(r.responseText));
+ }
+
// any record change should call this
this.fillData = fillData;
function fillData(newdataset)
@@ -161,10 +185,15 @@ WA.Containers.treeContainer = function(fatherNode, domID, code, listener)
}
// ask to the server the data
- var request = WA.Managers.ajax.createRequest(WA.Managers.wa4gl.url + WA.Managers.wa4gl.prelib + self.app.applicationID + WA.Managers.wa4gl.premethod + self.id + WA.Managers.wa4gl.preformat + WA.Managers.wa4gl.format, 'POST', 'Order=get', getData, true);
+ var request = WA.Managers.ajax.createRequest(WA.Managers.wa4gl.url + WA.Managers.wa4gl.prelib + self.app.applicationID + WA.Managers.wa4gl.premethod + self.id + WA.Managers.wa4gl.preformat + WA.Managers.wa4gl.format, 'POST', 'Order=get'+(self.params?'&'+self.params:''), getData, true);
// we put the "loading"
+ return;
+ }
+ else if (!newdataset && !self.loaded)
+ {
+ self.callEvent('get', getDataObject); // ask for children to events (somebody should listen to this)
return;
}
@@ -198,12 +227,19 @@ WA.Containers.treeContainer = function(fatherNode, domID, code, listener)
myt.attributes = {};
myt.attributes.id = dataset[i].id;
myt.attributes.father = dataset[i].father;
+ myt.attributes.moveable = dataset[i].moveable ? 'yes' : 'no';
myt.attributes.closeable = dataset[i].closeable?'yes':'no';
myt.attributes.closed = dataset[i].closed?'yes':'no';
myt.attributes.loadable = dataset[i].loadable?'yes':'no';
myt.attributes.loaded = dataset[i].loaded?'yes':'no';
// create the tree
- self.app.createTree(self, myt);
+ if (self.state = 5) {
+ self.state = 4; // temporary "starting", to build the whole template before calling start event
+ self.app.createTree(self, myt);
+ self.state = 5;
+ } else {
+ self.app.createTree(self, myt);
+ }
}
}
}
@@ -235,6 +271,123 @@ WA.Containers.treeContainer = function(fatherNode, domID, code, listener)
}
+ function moveresponse(request) {
+
+ var data = WA.JSON.decode(request.responseText);
+
+ if (!data || data.message != 'OK')
+ if (data)
+ alert(data.message);
+ else
+ alert(request.responseText);
+ else
+ reload();
+}
+
+ // **************************************************************************
+ // PRIVATE METHODS
+ // **************************************************************************
+ this.moving = moving;
+ function moving(order, zoneid, metrics) {
+
+ if (order == 'start') {
+ // Copy the node to the top
+ node = self.zones[zoneid].domNode;
+ self.domNodeDrag = node.cloneNode(true);
+ self.domNodeDrag.className += ' dragged';
+ // we get absolute coords and set them
+ self.domNodeDrag.style.position = 'absolute';
+ self.domNodeDrag.style.left = metrics.dragdocumentleft + 'px';
+ self.domNodeDrag.style.top = metrics.dragdocumenttop + 'px';
+ self.domNodeDrag.style.width = metrics.mainwidth + 'px';
+ self.domNodeDrag.style.height = metrics.mainheight + 'px';
+ self.domNodeDrag.style.zIndex = 2;
+ // we append to the main document the DOM
+ document.body.appendChild(self.domNodeDrag);
+
+ self.domNodeMessage = WA.createDomNode('div', null, null);
+ self.domNodeMessage.style = "position: absolute; left: 50px; top: 40px; border: 2px solid blue; background-color: white; z-index: 3; padding: 10px; font-size: 2em; color: black;";
+ self.domNodeDrag.appendChild(self.domNodeMessage);
+
+ self.startPos = metrics.maintopstart;
+ self.dropmode = 0;
+ self.dropid = null;
+ }
+ else if (order == 'drag') {
+ // move NODE copied
+ self.domNodeDrag.style.left = metrics.xmouse + 'px';
+ self.domNodeDrag.style.top = metrics.ymouse + 'px';
+ // Search for who is under the pointer, "before", "into", "after"
+
+ var onzone = null;
+ var xpointer = metrics.xmouse;
+ var ypointer = metrics.ymouse;
+ for (var i in self.zones) {
+ var zone = self.zones[i];
+ var top = WA.browser.getNodeDocumentTop(zone.domNode);
+ var bottom = WA.browser.getNodeDocumentTop(zone.domNode) + WA.browser.getNodeHeight(zone.domNode);
+ var left = WA.browser.getNodeDocumentLeft(zone.domNode);
+ var right = WA.browser.getNodeDocumentLeft(zone.domNode) + WA.browser.getNodeWidth(zone.domNode);
+ if (ypointer >= top && ypointer <= bottom && xpointer >= left && xpointer <= right) {
+ onzone = zone;
+ break;
+ }
+ }
+
+ if (onzone) {
+ if (onzone.isMoveable(zoneid)) {
+
+ onzone.hover()
+
+ if (ypointer > top && ypointer < top + (bottom - top) / 3) {
+ // before
+ message = "Mover ANTES de " + zone.domID;
+ self.dropmode = 1;
+ } else if (ypointer > top + (bottom - top) / 3 && ypointer < top + (bottom - top) * 2 / 3) {
+ // into
+ message = "Mover COMO HIJO de " + zone.domID;
+ self.dropmode = 3;
+ } else if (ypointer > top + (bottom - top) * 2 / 3 && ypointer < bottom) {
+ // after
+ message = "Mover DESPUES de " + zone.xdomID[2];
+ self.dropmode = 2;
+ } else {
+ self.dropmode = 0;
+ }
+ self.dropid = zone.xdomID[2];
+ self.domNodeMessage.innerHTML = message;
+ } else {
+ self.domNodeMessage.innerHTML = "No se puede mover aqui";
+ self.dropmode = 0;
+ }
+
+ }
+ if (self.lastonzone && self.lastonzone != onzone) {
+ self.lastonzone.hout()
+ }
+ self.lastonzone = onzone;
+
+ }
+ else if (order == 'drop') {
+ // destroy the hover node
+ document.body.removeChild(self.domNodeDrag);
+ if (self.lastonzone) {
+ self.lastonzone.hout()
+ }
+ // send the order to the server
+ if (self.dropmode > 0) {
+ self.lastonzone.sendServer('move', { id: zoneid, toid: self.dropid, mode: self.dropmode }, moveresponse );
+ }
+
+ self.startpos = 0;
+ self.domNodeMessage = null;
+ self.domNodeDrag = null;
+ self.dropmode = 0;
+ self.dropid = null;
+ self.lastonzone = null;
+ }
+ }
+
this.parseTemplates(code);
this.parseData(code);
}
@@ -251,6 +404,7 @@ WA.Containers.treeContainer.treeZone = function(father, domID, container, code,
this.children = {};
+ this.moveable = (code.attributes.moveable==='yes');
this.closeable = (code.attributes.closeable==='yes');
this.closed = (code.attributes.closed==='yes');
this.loadable = (code.attributes.loadable==='yes');
@@ -292,21 +446,46 @@ WA.Containers.treeContainer.treeZone = function(father, domID, container, code,
this.domNodeMain.appendChild(this.domNodeChildren);
this.addEvent('start', start);
+ this.addEvent('poststart', poststart);
this.addEvent('stop', stop);
+ this.isMoveable = isMoveable;
+ function isMoveable(zoneid)
+ {
+ if (!self.moveable)
+ return false;
+ if (zoneid == self.xdomID[2])
+ return false;
+ // Search if this one is child of moved one
+
+
+ return true
+ }
+
+ this.childrenLoadedObject = childrenLoadedObject;
+ function childrenLoadedObject(data)
+ {
+ self.loaded = true;
+ self.father.fillData(data);
+ }
+
this.childrenLoaded = childrenLoaded;
function childrenLoaded(r)
{
var data = WA.JSON.decode(r.responseText);
- self.loaded = true;
- self.father.fillData(data.row);
+ childrenLoadedObject(data.row);
}
this.loadChildren = loadChildren;
function loadChildren()
{
+ if (!self.father.serverlistener)
+ {
+ self.father.callEvent('getchildren', {id: self.code.attributes.id, listener: childrenLoadedObject}); // ask for children to events (somebody should listen to this)
+ return;
+ }
// start an ajax request
- var request = WA.Managers.ajax.createRequest(WA.Managers.wa4gl.url + WA.Managers.wa4gl.prelib + self.father.app.applicationID + WA.Managers.wa4gl.premethod + self.father.id + WA.Managers.wa4gl.preformat + WA.Managers.wa4gl.format, 'POST', null, childrenLoaded, false);
+ var request = WA.Managers.ajax.createRequest(WA.Managers.wa4gl.url + WA.Managers.wa4gl.prelib + self.father.app.applicationID + WA.Managers.wa4gl.premethod + self.father.id + WA.Managers.wa4gl.preformat + WA.Managers.wa4gl.format, 'POST', (self.params?self.params:''), childrenLoaded, false);
request.addParameter('Order', 'getchildren');
request.addParameter('father', self.code.attributes.id);
request.send();
@@ -318,12 +497,13 @@ WA.Containers.treeContainer.treeZone = function(father, domID, container, code,
}
this.sendServer = sendServer;
- function sendServer(order, code)
+ function sendServer(order, code, response)
{
if (!self.father.serverlistener)
return;
// send information to server based on mode
- var request = WA.Managers.ajax.createRequest(WA.Managers.wa4gl.url + WA.Managers.wa4gl.prelib + self.father.app.applicationID + WA.Managers.wa4gl.premethod + self.father.id + WA.Managers.wa4gl.preformat + WA.Managers.wa4gl.format, 'POST', 'Order='+order, getResponse, false);
+ if (!response) response = getResponse;
+ var request = WA.Managers.ajax.createRequest(WA.Managers.wa4gl.url + WA.Managers.wa4gl.prelib + self.father.app.applicationID + WA.Managers.wa4gl.premethod + self.father.id + WA.Managers.wa4gl.preformat + WA.Managers.wa4gl.format, 'POST', 'Order='+order+(self.params?'&'+self.params:''), response, false);
if (request)
{
for (var i in code)
@@ -364,6 +544,43 @@ WA.Containers.treeContainer.treeZone = function(father, domID, container, code,
return result;
}
+ this.moving = moving;
+ function moving(order, id1, id2, zone, metrics) {
+
+ self.moving = true;
+ self.father.moving(order, self.xdomID[2], metrics);
+ }
+
+ this.hover = hover;
+ function hover() {
+ if (!self.domNodeHover) {
+ self.domNodeHover = WA.createDomNode('div', this.domID + "_hover", null);
+ self.domNodeHover.style = "position: absolute; left: 0px; top: 0px; width: 100%; height: 100%; background-color: white; opacity: 0.4; z-index: 2;";
+ // we append to the main document the DOM
+ self.domNode.appendChild(self.domNodeHover);
+ var n1 = WA.createDomNode('div', this.domID + "_l1", null);
+ n1.style = "position: absolute; left: 0px; top: 0px; width: 80%; height: 33%; background-color: green; border-top: 1px solid black; z-index: 3;";
+ self.domNodeHover.appendChild(n1);
+ n1 = WA.createDomNode('div', this.domID + "_l2", null);
+ n1.style = "position: absolute; left: 0px; top: 33%; width: 80%; height: 33%; background-color: red; border-top: 1px solid black; z-index: 3;";
+ self.domNodeHover.appendChild(n1);
+ n1 = WA.createDomNode('div', this.domID + "_l3", null);
+ n1.style = "position: absolute; left: 0px; top: 66%; width: 80%; height: 34%; background-color: green; border-top: 1px solid black; z-index: 3;";
+ self.domNodeHover.appendChild(n1);
+ n1 = WA.createDomNode('div', this.domID + "_l4", null);
+ n1.style = "position: absolute; left: 0px; bottom: 0px; width: 80%; height: 1px; background-color: black; z-index: 3;";
+ self.domNodeHover.appendChild(n1);
+
+ }
+ }
+
+ this.hout = hout;
+ function hout() {
+ if (self.domNodeHover)
+ self.domNode.removeChild(self.domNodeHover);
+ self.domNodeHover = null;
+ }
+
function start()
{
// link open close
@@ -377,10 +594,24 @@ WA.Containers.treeContainer.treeZone = function(father, domID, container, code,
}
}
+ function poststart() {
+ if (self.father.hasdd && self.father.changeorder && self.moveable) {
+ // Search if there is a node with the class 'move' into the tree of this node
+ var movenode = WA.browser.findNodeByClass(self.domNode, 'move');
+ if (!movenode)
+ movenode = self.domNode;
+ WA.Managers.dd.registerObject(self.father.domID, movenode, self.domNode, moving, null);
+ }
+ }
+
function stop()
{
if (self.closeable)
WA.Managers.event.off('click', self.domNodeOpenClose, self.openclose, true);
+ if (self.father.hasdd && self.father.changeorder && self.moveable) {
+ WA.Managers.dd.unregisterObject(self.father.domID, self.domNode);
+ }
+ console.log("stop node");
}
this.resize = resize;
diff --git a/js/elements/ggraphElement.js b/js/elements/ggraphElement.js
index 2b0edb7..75585cf 100644
--- a/js/elements/ggraphElement.js
+++ b/js/elements/ggraphElement.js
@@ -83,7 +83,6 @@ WA.Elements.ggraphElement = function(fatherNode, domID, code, listener)
//console.log(self.state);
//console.log(self.loaded);
-
if (googleready && self.state == 5 && self.loaded)
{
//console.log(self.data);
@@ -92,9 +91,19 @@ WA.Elements.ggraphElement = function(fatherNode, domID, code, listener)
var data = new google.visualization.DataTable();
for(var i=0; i';
+ fillData();
+ }
+ }
+
+ // funcion para validar la estructura del JSON
+ const validaJson = (txt) => {
+ try {
+ JSON.parse(txt);
+ return true;
+ } catch (error) {
+ console.error("ERROR JSON:", error);
+ return false;
+ }
}
// any record change should call this
this.fillData = fillData;
- function fillData(newdataset)
+ async function fillData(newdataset)
{
//console.log('into filldata ' + self.domID);
//console.log(self.serverlistener);
-
if (!newdataset && !self.loaded && self.serverlistener)
{
if (self.countload++ > 3)
@@ -211,10 +303,11 @@ WA.Elements.ggraphElement = function(fatherNode, domID, code, listener)
// ask to the server the data
var request = WA.Managers.ajax.createRequest(WA.Managers.wa4gl.url + WA.Managers.wa4gl.prelib + self.app.applicationID + WA.Managers.wa4gl.premethod + self.id + WA.Managers.wa4gl.preformat + WA.Managers.wa4gl.format, 'POST', 'Order=get', getData, true);
- WA.toDOM(self.domID).innerHTML = '';
+ //WA.toDOM(self.domID).innerHTML = '';
+
return;
}
-
+
var dataset = null;
if (newdataset)
{
@@ -272,17 +365,6 @@ WA.Elements.ggraphElement = function(fatherNode, domID, code, listener)
start();
}
-
-
-
-
-
-
-
-
-
-
-
this.stop = stop;
function stop()
{
diff --git a/js/elements/lovfieldElement.js b/js/elements/lovfieldElement.js
index 44b9d56..e141613 100644
--- a/js/elements/lovfieldElement.js
+++ b/js/elements/lovfieldElement.js
@@ -56,6 +56,7 @@ WA.Elements.lovfieldElement = function(fatherNode, domID, code, listener)
// validity checks
this.multiselect = (this.code.attributes.multiselect?this.code.attributes.multiselect=='yes':null);
+ this.radiobutton = (this.code.attributes.radiobutton ? this.code.attributes.radiobutton == 'yes' : null);
this.threshold = (this.code.attributes.threshold?this.code.attributes.threshold:3);
this.options = {};
@@ -103,10 +104,17 @@ WA.Elements.lovfieldElement = function(fatherNode, domID, code, listener)
this.domNodeValue = WA.createDomNode('div', domID+'_value', 'value');
this.domNode.appendChild(this.domNodeValue);
- this.domNodeField = WA.createDomNode('select', domID+'_field', 'field');
+ if (!this.radiobutton)
+ {
+ this.domNodeField = WA.createDomNode('select', domID+'_field', 'field');
+ if (this.size)
+ this.domNodeField.style.width = this.size+'px';
+ if (this.multiselect)
+ this.domNodeField.multiple = true;
+ } else {
+ this.domNodeField = WA.createDomNode('div', domID + '_field', 'field');
+ }
this.domNodeField.name = this.id;
- if (this.size)
- this.domNodeField.style.width = this.size+'px';
this.domNode.appendChild(this.domNodeField);
this.domNodeHelp = WA.createDomNode('p', domID+'_help', 'help');
@@ -176,18 +184,33 @@ WA.Elements.lovfieldElement = function(fatherNode, domID, code, listener)
function populate()
{
- var text = '';
- if (!self.notnull[self.mode])
+ if (self.radiobutton)
{
- text += '';
+ if (self.options)
+ {
+ var text = '';
+ for (var i in self.options)
+ {
+ text += ''+self.options[i]+'
';
+ }
+ self.domNodeField.innerHTML = text;
+ }
}
- for (var i in self.options)
+ else
{
- // we intelligent populate based on option, select or search
- // is this the selected option ?
- text += '';
+ var text = '';
+ if (!self.notnull[self.mode])
+ {
+ text += '';
+ }
+ for (var i in self.options)
+ {
+ // we intelligent populate based on option, select or search
+ // is this the selected option ?
+ text += '';
+ }
+ self.domNodeField.innerHTML = text;
}
- self.domNodeField.innerHTML = text;
}
this.checkStatus = checkStatus;
@@ -401,6 +424,38 @@ WA.Elements.lovfieldElement = function(fatherNode, domID, code, listener)
this.getValues = getValues;
function getValues()
{
+ // Case of a multiselect/Radio
+ if (self.radiobutton)
+ {
+ if (self.multiselect)
+ {
+ var values = [];
+ for (var i=0, l=self.domNodeField.childNodes.length; i < l; i++)
+ {
+ if (self.domNodeField.childNodes[i].checked)
+ {
+ values.push(self.domNodeField.childNodes[i].value);
+ }
+ }
+ return values;
+ } else {
+ for (var i = 0, l = self.domNodeField.childNodes.length; i < l; i++) {
+ if (self.domNodeField.childNodes[i].checked) {
+ return self.domNodeField.childNodes[i].value;
+ }
+ }
+ return null;
+ }
+ }
+ if (self.multiselect)
+ {
+ var values = [];
+ var selected = self.domNodeField.selectedOptions;
+ for (var i = 0; i < selected.length; i++) {
+ values.push(selected[i].value);
+ }
+ return values;
+ }
return self.domNodeField.value;
}
@@ -409,10 +464,19 @@ WA.Elements.lovfieldElement = function(fatherNode, domID, code, listener)
{
self.firstview = true;
self.value = self.domNodeField.value = values;
- if (values != undefined && values != null)
- self.domNodeValue.innerHTML = values + (self.options[values]?(' - ' + self.options[values]):'');
- else
- reset();
+ // Case of a multiselect/Radio
+ if (self.radiobutton || self.multiselect)
+ {
+ for (var i=0, l=self.domNodeField.childNodes.length; i < l; i++)
+ {
+ self.domNodeField.childNodes[i].checked = (values.indexOf(self.domNodeField.childNodes[i].value) != -1);
+ }
+ } else {
+ if (values != undefined && values != null)
+ self.domNodeValue.innerHTML = values + (self.options[values] ? (' - ' + self.options[values]) : '');
+ else
+ reset();
+ }
checkAll();
}
@@ -455,26 +519,3 @@ WA.Elements.lovfieldElement = function(fatherNode, domID, code, listener)
WA.extend(WA.Elements.lovfieldElement, WA.Managers.wa4gl._element);
-/*
-
- this.domNode = document.createElement('select');
- if(this.multiselect)
- {
- this.classname = params.attributes.classname?params.attributes.classname:'lovmok';
- this.classnameerror = params.attributes.classnameerror?params.attributes.classnameerror:'lovmerror';
- this.classnamefocus = params.attributes.classnamefocus?params.attributes.classnamefocus:'lovmfocus';
- this.classnamedisabled = params.attributes.classnamedisabled?params.attributes.classnamedisabled:'lovmdisabled';
- this.classnamereadonly = params.attributes.classnamereadonly?params.attributes.classnamereadonly:'lovmreadonly';
- this.classnameselected = params.attributes.classname?params.attributes.classname:'lovmselected';
- this.domNode.setAttribute('multiple','1');
- }
- this.domNode.id = domID;
- this.domNode.name = _4glNode.id;
- if (this.width)
- this.domNode.style.width = this.width+'px';
- if (this.height)
- this.domNode.style.height = this.height+'px';
- domNodefather.appendChild(this.domNode);
- // we link with the group container if needed
-
-*/
diff --git a/js/elements/mmcfieldElement.js b/js/elements/mmcfieldElement.js
index 7c7f4ed..67c986c 100644
--- a/js/elements/mmcfieldElement.js
+++ b/js/elements/mmcfieldElement.js
@@ -36,6 +36,7 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
this.edition = false;
this.focus = false;
+ this.actionlistener = null;
this.mode = 0;
// Behaviour on modes
this.isvisible = [];
@@ -62,8 +63,11 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
this.size = (this.code.attributes.size?this.code.attributes.size:'');
// defaultvalue is the default for insert mode (code from the code, set below)
// value is the value set in this mode by setValues, if we want to undo changes
- this.defaultvalue = this.value = '';
+ this.defaultvalue = '';
+ this.value = this.newvalue = undefined;
this.path = (this.code.attributes.path?this.code.attributes.path:'');
+ this.accept = (this.code.attributes.accept?this.code.attributes.accept:'');
+ this.multifile = !!(this.code.attributes.multifile == "yes");
// errors on checks
this.errorexternal = false; // true when set manually an error
@@ -91,40 +95,63 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
if (self.code.data)
this.domNodeLabel.innerHTML = self.code.data;
- this.domNodeImage = WA.createDomNode('img', domID+'_image', '');
- this.domNodeImage.style = "float: left; max-width: 50; max-height: 50px; margin-right: 10px;";
- this.domNode.appendChild(this.domNodeImage);
-
- this.domNodeValue = WA.createDomNode('div', domID+'_value', 'value');
- this.domNode.appendChild(this.domNodeValue);
-
+ this.domNodeUpload = WA.createDomNode('div', domID+'_upload', 'upload');
+ this.domNodeUpload.style = "float: left; width: "+this.size+"px; text-align: center;";
+ this.domNode.appendChild(this.domNodeUpload);
+ this.domNodeUpload.innerHTML = "
Buscar o soltar un archivo aquí.";
+ this.domNodeUpload.addEventListener("click", clickupload);
+ this.domNodeUpload.addEventListener("dragover", dragover);
+ this.domNodeUpload.addEventListener("dragleave", dragend);
+ this.domNodeUpload.addEventListener("dragend", dragend);
+ this.domNodeUpload.addEventListener("drop", drop);
+
+ this.domNodeUploading = WA.createDomNode('div', domID+'_uploading', 'uploading');
+ this.domNodeUploading.style = "float: left; width: "+this.size+"px;";
+ this.domNode.appendChild(this.domNodeUploading);
+
+ this.domNodeUploadingIcon = WA.createDomNode('img', domID+'_uploadingicon', 'uploading-icon');
+ this.domNodeUploading.appendChild(this.domNodeUploadingIcon);
+ this.domNodeUploadingName = WA.createDomNode('div', domID+'_uploadingname', 'uploading-name');
+ this.domNodeUploading.appendChild(this.domNodeUploadingName);
+ this.domNodeUploadingPerc = WA.createDomNode('div', domID+'_uploadinperc', 'uploading-perc');
+ this.domNodeUploading.appendChild(this.domNodeUploadingPerc);
+ this.domNodeUploadingBar = WA.createDomNode('div', domID+'_uploadingbar', 'uploading-bar');
+ this.domNodeUploading.appendChild(this.domNodeUploadingBar);
+ this.domNodeUploadingProgress = WA.createDomNode('div', domID+'_uploadingprogress', 'uploading-progressbar');
+ this.domNodeUploadingBar.appendChild(this.domNodeUploadingProgress);
+
+ this.domNodeUploaded = buildUploadedTemplate("");
+ this.domNode.appendChild(this.domNodeUploaded);
+ this.domNodeIcon = WA.browser.findNodeByClass(this.domNodeUploaded, 'uploaded-icon');
+ this.domNodeImage = WA.browser.findNodeByClass(this.domNodeUploaded, 'uploaded-image');
+ this.domNodeValue = WA.browser.findNodeByClass(this.domNodeUploaded, 'uploaded-value');
+ this.domNodeDelete = WA.browser.findNodeByClass(this.domNodeUploaded, 'uploaded-delete');
+
+ // the file is the name of the file, already into server
this.domNodeFile = WA.createDomNode('input', domID+'_file', 'field');
this.domNodeFile.type = (this.code.attributes.external?'text':'hidden');
+ this.domNodeFile.style.display = 'none';
this.domNodeFile.name = this.id + '_file';
this.domNode.appendChild(this.domNodeFile);
+ // the download file is the new name of the file if any change (show in upload/modify if external authorized)
+ this.domNodeDownload = WA.createDomNode('input', domID+'_download', 'field');
+ this.domNodeDownload.type = 'text';
+ this.domNodeDownload.style.display = 'none';
+ this.domNodeDownload.name = this.id + '_download';
+ this.domNode.appendChild(this.domNodeDownload);
+
this.domNodeField = WA.createDomNode('input', domID+'_field', 'field');
this.domNodeField.type = 'file';
+ if (this.multifile)
+ this.domNodeField.multiple = true;
+ this.domNodeField.style.display = "none";
this.domNodeField.name = this.id;
- // POR EL MOMENTO ES MONO IMAGE (EXTENDER CON DIV DE LO SUBIDO A MULTI IMAGE)
- // this.domNodeField.multiple = true;
- this.domNodeField.accept = "image/x-png, image/gif, image/jpeg, image/jpg";
+ this.domNodeField.accept = this.accept;
if (this.size)
this.domNodeField.style.width = this.size+'px';
this.domNode.appendChild(this.domNodeField);
- this.domNodeDownload = WA.createDomNode('input', domID+'_download', 'field');
- this.domNodeDownload.type = 'hidden';
- this.domNodeDownload.name = this.id + '_download';
- this.domNode.appendChild(this.domNodeDownload);
-
- var br = WA.createDomNode('br');
- this.domNode.appendChild(br);
-
- this.domNodeDelete = WA.createDomNode('div', domID+'_delete', this.classes.classname + 'delete');
- this.domNodeDelete.innerHTML = (this.code.attributes.deletebutton?this.code.attributes.deletebutton:'[Delete]');
- this.domNode.appendChild(this.domNodeDelete);
-
this.domNodeHelp = WA.createDomNode('p', domID+'_help', 'help');
this.domNode.appendChild(this.domNodeHelp);
if (self.helpmessage)
@@ -133,6 +160,11 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
this.domNodeError = WA.createDomNode('p', domID+'_error', 'error');
this.domNode.appendChild(this.domNodeError);
+ // create multifile list
+ this.domNodeFiles = WA.createDomNode('div', domID + '_files', 'files');
+ this.domNodeFiles.style = "width: " + this.size + "px; position: relative;";
+ this.domNode.appendChild(this.domNodeFiles);
+
// responsive design based on container available size, is '', ' medium' or ' tiny'
// Not activated for now
this.sizemode = '';
@@ -156,6 +188,27 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
this.addEvent('start', start);
this.addEvent('stop', stop);
+ function callListener(action)
+ {
+ if (self.actionlistener)
+ self.actionlistener(action, self.domNodeImage.src, self.domNodeFile.value);
+ }
+
+ function buildUploadedTemplate(id) {
+ var domNodeUploaded = WA.createDomNode('div', domID + '_uploaded' + id, 'uploaded');
+ domNodeUploaded.style = (self.multifile ? "" : "float: left; ") + "width: " + self.size + "px;";
+ var domNodeIcon = WA.createDomNode('img', domID + '_icon', 'uploaded-icon');
+ domNodeUploaded.appendChild(domNodeIcon);
+ var domNodeImage = WA.createDomNode('img', domID + '_image', 'uploaded-image');
+ domNodeUploaded.appendChild(domNodeImage);
+ var domNodeValue = WA.createDomNode('div', domID + '_value', 'uploaded-value');
+ domNodeUploaded.appendChild(domNodeValue);
+ var domNodeDelete = WA.createDomNode('div', domID + '_delete', 'uploaded-delete');
+ domNodeDelete.innerHTML = (self.code.attributes.deletebutton ? self.code.attributes.deletebutton : '[Delete]');
+ domNodeUploaded.appendChild(domNodeDelete);
+ return domNodeUploaded;
+ }
+
function resize()
{
WA.Elements.mmcfieldElement.source.resize.call(self);
@@ -173,6 +226,15 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
*/
}
+ // specific element functions
+ this.addListener = addListener;
+ function addListener(listener)
+ {
+ // Send actions of the group to the listener
+ self.actionlistener = listener;
+ callListener('add');
+ }
+
this.registerSynchronize = registerSynchronize;
function registerSynchronize(element)
{
@@ -196,6 +258,64 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
this.checkStatus = checkStatus;
function checkStatus()
{
+ if (self.newvalue || self.value || self.mode == 3 || self.mode == 4)
+ {
+ self.domNodeUpload.style.display = 'none';
+ self.domNodeUploading.style.display = 'none';
+ self.domNodeUploaded.style.display = 'block';
+
+ if (self.newvalue) {
+ if (self.multifile) {
+ for (var i = 0; i < self.newvalue.temporal.length; i++) {
+ var domNodeUploaded = buildUploadedTemplate(i);
+ self.domNodeFiles.appendChild(domNodeUploaded);
+ console.log("ICONNAME=", self.newvalue.iconname[i])
+
+ var nodeicon = WA.browser.findNodeByClass(domNodeUploaded, 'uploaded-icon');
+ nodeicon.src = self.newvalue.iconname[i];
+ var nodeimage = WA.browser.findNodeByClass(domNodeUploaded, 'uploaded-image');
+ if (self.newvalue.image[i])
+ {
+ nodeimage.src = self.newvalue.image[i];
+ nodeimage.style.display = "block";
+ }
+ var nodevalue = WA.browser.findNodeByClass(domNodeUploaded, 'uploaded-value');
+ nodevalue.innerHTML = self.newvalue.filename[i];
+// var nodedelete = WA.browser.findNodeByClass(domNodeUploaded, 'uploaded-delete');
+ }
+ } else {
+ self.domNodeIcon.src = self.newvalue.iconname;
+ self.domNodeValue.innerHTML = self.newvalue.filename;
+ self.domNodeDownload.value = self.newvalue.temporal;
+ if (self.newvalue.image) {
+ self.domNodeImage.src = self.newvalue.image;
+ self.domNodeImage.style.display = "block";
+ } else {
+ self.domNodeImage.style.display = "none";
+ }
+ }
+ } else if (self.value) {
+ self.domNodeIcon.src = self.value.iconname;
+ self.domNodeValue.innerHTML = self.value.filename;
+ self.domNodeFile.value = self.value.value;
+ if (self.value.image) {
+ self.domNodeImage.src = self.value.image;
+ self.domNodeImage.style.display = "block";
+ } else {
+ self.domNodeImage.style.display = "none";
+ }
+ }
+ if (self.mode == 1 || self.mode == 2)
+ self.domNodeDelete.style.display = 'block';
+ else
+ self.domNodeDelete.style.display = 'none';
+
+ } else {
+ self.domNodeUpload.style.display = 'block';
+ self.domNodeUploading.style.display = 'none';
+ self.domNodeUploaded.style.display = 'none';
+ }
+
for (var i in self.errors)
self.errors[i] = false;
@@ -230,15 +350,14 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
self.domNodeField.disabled == false;
if (self.domNodeField.readOnly == true)
self.domNodeField.readOnly == false;
- var value = self.domNodeFile.value;
- if (self.value != undefined && value == self.value && self.mode != 1)
+ if (self.mode != 1 && (self.newvalue || self.value))
{
self.status = 0;
self.domNodeError.innerHTML = '';
return;
}
self.status = 1;
- if (self.notnull[self.mode] && value == '')
+ if (self.notnull[self.mode] && !self.value && !self.newvalue)
{
self.status = 2;
self.errors.statusnotnull = true;
@@ -249,7 +368,7 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
if (self.code[0] != undefined && self.code[0].tag != undefined && self.code[0].tag == 'check')
eval(self.code[0].data);
- console.log(self.errors);
+ console.log("STATUS=", self.status, self.errors);
}
this.checkClass = checkClass;
@@ -324,9 +443,6 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
function setMode(mode, keep)
{
self.mode = mode;
- console.log('setMODE');
- console.log(mode);
- console.log(keep);
// Set all the data based on the mode
if (!self.isvisible[mode])
@@ -341,12 +457,11 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
if (keep)
self.domNodeValue.innerHTML = self.domNodeFile.value;
- self.domNodeValue.style.display = (self.info[mode]?'':'none');
- self.domNodeFile.style.display = (self.info[mode]?'none':'');
- self.domNodeField.style.display = (self.info[mode]?'none':'');
+ // self.domNodeValue.style.display = (self.info[mode]?'':'none');
+ // self.domNodeFile.style.display = (self.info[mode]?'none':'');
+ // self.domNodeField.style.display = (self.info[mode]?'none':'');
self.domNodeError.style.display = (self.info[mode]?'none':'');
self.domNodeDelete.style.display = (self.info[mode]?'none':'');
-
self.domNodeHelp.style.display = (self.help[mode]?'':'none');
self.edition = !self.info[mode];
@@ -363,20 +478,61 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
return;
if (self.mode == 1)
{
- self.value = self.domNodeField.value = self.domNodeValue.innerHTML = self.defaultvalue;
+ self.newvalue = self.value = null;
}
else if (self.mode == 2 || self.mode == 3)
{
- self.domNodeValue.innerHTML = self.domNodeField.value = self.value;
+ self.newvalue = null;
}
checkAll();
}
+ function clickupload(e)
+ {
+ self.domNodeField.click();
+ }
+
+ function dragover(e)
+ {
+ e.preventDefault();
+ self.domNodeUpload.classList.add('dragover');
+ }
+
+ function dragend(e)
+ {
+ self.domNodeUpload.classList.remove('dragover');
+ }
+
+ function drop(e)
+ {
+ e.preventDefault();
+ if (e.dataTransfer.files.length)
+ {
+ // only 1 to download
+ self.domNodeField.files = e.dataTransfer.files;
+ dragend(e);
+ var event = new Event('change');
+ self.domNodeField.dispatchEvent(event);
+ return;
+ }
+ dragend(e);
+ }
+
function changeImage(e)
{
- console.log('changeImage');
-
+ if (this.files.length == 0)
+ return;
+
+ console.log('changeImage, UPLOADING');
+ self.domNodeUpload.style.display = 'none';
+ self.domNodeUploading.style.display = 'block';
+ self.domNodeUploaded.style.display = 'none';
+
+ self.domNodeUploadingName.innerHTML = this.files[0].name;
+ self.domNodeUploadingPerc.innerHTML = "0.0%";
+ self.domNodeUploadingProgress.style.width = "0";
+
// enviar un POST al group owner
formdata = new FormData();
@@ -387,7 +543,7 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
{
file = this.files[i];
- if (!!file.type.match(/image.*/))
+// if (!!file.type.match(/image.*/) || !!file.type.match(/video.*/))
{
if ( window.FileReader )
{
@@ -400,8 +556,8 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
}
if (formdata)
{
- formdata.append("images[]", file);
- formdata.append(self.group.varorder, "image");
+ formdata.append("file", file);
+ formdata.append(self.group.varorder, "file");
formdata.append(self.group.varkey, self.group.currentkey);
formdata.append(self.group.varfield, self.id);
}
@@ -411,32 +567,47 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
if (formdata)
{
var request = WA.Managers.ajax.createRequest(WA.Managers.wa4gl.url + WA.Managers.wa4gl.prelib + self.app.applicationID + WA.Managers.wa4gl.premethod + self.id + WA.Managers.wa4gl.preformat + WA.Managers.wa4gl.format, 'POST', null, getResult, false);
+ request.setUploadListener(listenUpload);
request.send(formdata);
}
}
-
+
+ function listenUpload(e)
+ {
+ var progress = e.loaded / e.total * 100;
+ self.domNodeUploadingProgress.style.width = "" + progress.toFixed(1) + "%";
+ self.domNodeUploadingPerc.innerHTML = "" + progress.toFixed(1) + "%";
+ }
+
function getResult(response)
{
- console.log(response);
var code = WA.JSON.decode(response.responseText);
- if (code.status != 'OK')
+ if (!code.success)
+ {
alert(code.message);
+ }
else
{
- self.domNodeImage.src = code.tempname;
- self.domNodeDownload.value = code.name;
- self.domNodeFile.value = code.name;
- self.value = '';
+ if (!self.multifile || !self.newvalue)
+ self.newvalue = code;
+ else
+ { // CONCATENATE NEW ARRIVED FILES
+ self.newvalue = code;
+ }
+ callListener('upload');
}
- checkStatus();
+ self.domNodeField.type = '';
+ self.domNodeField.type = 'file';
+ checkAll();
}
function deleteImage(e)
{
- self.value = self.domNodeFile.value = '';
- self.domNodeImage.src = '';
- self.domNodeValue.innerHTML = '';
- self.domNodeDelete.style.display = 'none';
+ if (self.newvalue) {
+ self.newvalue = null;
+ } else {
+ self.value = null;
+ }
checkAll();
}
@@ -475,34 +646,17 @@ WA.Elements.mmcfieldElement = function(fatherNode, domID, code, listener)
this.getValues = getValues;
function getValues()
{
- if (self.domNodeDownload.value)
- return 'temp:'+self.domNodeDownload.value;
- return self.domNodeFile.value;
+ if (self.newvalue)
+ return self.newvalue;
+ return self.value;
}
this.setValues = setValues;
function setValues(values)
{
- console.log('MMCFIELD VALUE = ');
- console.log(values);
self.firstview = true;
- self.value = self.domNodeFile.value = values;
- if (values != undefined && values != null && !!values)
- {
- if (values.substr(0,6) == 'http:/' || values.substr(0,7) == 'https:/')
- {
- // if accept external values, check if starts with http*
- self.domNodeImage.src = values;
- self.domNodeValue.innerHTML = values;
- }
- else
- {
- self.domNodeImage.src = self.path + values;
- self.domNodeValue.innerHTML = values;
- }
- }
- else
- reset();
+ self.value = values;
+ self.newvalue = null;
checkAll();
}
diff --git a/js/elements/searchabletextfieldElement.js b/js/elements/searchabletextfieldElement.js
new file mode 100644
index 0000000..49335e2
--- /dev/null
+++ b/js/elements/searchabletextfieldElement.js
@@ -0,0 +1,677 @@
+
+/*
+ textfieldElement.js, WAJAF, the WebAbility(r) Javascript Application Framework
+ Contains element to control a simple text field
+ (c) 2008-2012 Philippe Thomassigny
+
+ This file is part of WAJAF
+
+ WAJAF is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ WAJAF is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with WAJAF. If not, see .
+*/
+
+WA.Elements.searchabletextfieldElement = function(fatherNode, domID, code, listener)
+{
+ var self = this;
+ WA.Elements.searchabletextfieldElement.sourceconstructor.call(this, fatherNode, domID, code, 'div', { classname:'textfield' }, listener);
+
+ this.id = this.code.attributes.id; // name of field, to use to send to the server
+
+ // by default the field is part of the record, used by container
+ this.formtype = 'field';
+ this.record = (this.code.attributes.record&&this.code.attributes.record=='no'?false:true);
+ this.editable = true; // it's a text field, so yes
+
+ this.status = 0; // 0 = neutral, 1 = ok, 2 = error, 3 = r/o, 4 = disabled
+ this.edition = false;
+ this.focus = false;
+
+ this.mode = 0;
+ // Behaviour on modes
+ this.isvisible = [];
+ this.info = [];
+ this.disabled = [];
+ this.readonly = [];
+ this.notnull = [];
+ this.help = [];
+ for (var i = 1; i < 5; i++)
+ {
+ this.isvisible[i] = (this.code.attributes.visible?this.code.attributes.visible.indexOf(''+i)!=-1:true);
+ this.info[i] = (this.code.attributes.info?this.code.attributes.info.indexOf(''+i)!=-1:false);
+ this.disabled[i] = (this.code.attributes.disabled?this.code.attributes.disabled.indexOf(''+i)!=-1:false);
+ this.readonly[i] = (this.code.attributes.readonly?this.code.attributes.readonly.indexOf(''+i)!=-1:false);
+ this.notnull[i] = (this.code.attributes.notnull?this.code.attributes.notnull.indexOf(''+i)!=-1:false);
+ this.help[i] = (this.code.attributes.helpmode?this.code.attributes.helpmode.indexOf(''+i)!=-1:false);
+ }
+
+ // validity checks
+ // type can be: text, password, integer, float, email
+ this.texttype = (this.code.attributes.texttype?this.code.attributes.texttype:'text');
+ this.format = (this.code.attributes.format?new RegExp(this.code.attributes.format):null);
+ this.min = (this.code.attributes.min?this.code.attributes.min:'');
+ this.max = (this.code.attributes.max?this.code.attributes.max:'');
+ this.minlength = (this.code.attributes.minlength?this.code.attributes.minlength:'');
+ this.maxlength = (this.code.attributes.maxlength?this.code.attributes.maxlength:'');
+ this.size = (this.code.attributes.size?this.code.attributes.size:'');
+ this.minwords = (this.code.attributes.minwords?this.code.attributes.minwords:null);
+ this.maxwords = (this.code.attributes.maxwords?this.code.attributes.maxwords:null);
+ this.auto = (this.code.attributes.auto&&this.code.attributes.auto=='yes'?true:false);
+ // defaultvalue is the default for insert mode (code from the code, set below)
+ // value is the value set in this mode by setValues, if we want to undo changes
+ this.defaultvalue = this.value = '';
+ this.automessage = '';
+
+ // errors on checks
+ this.errorexternal = false; // true when set manually an error
+ this.errors = {};
+ this.errormessages = {};
+ this.firstview = true; // set to false when the field has been touched/modified. Used to know if we put the errors
+
+ if (code.children)
+ {
+ for (var i = 0, l = code.children.length; i < l; i++)
+ {
+ switch (code.children[i].tag)
+ {
+ case 'defaultvalue': this.defaultvalue = code.children[i].data?code.children[i].data:''; break;
+ case 'helpdescription': this.helpmessage = code.children[i].data; break;
+ case 'statusnotnull': this.errormessages.statusnotnull = code.children[i].data; this.errors.statusnotnull = false; break;
+ case 'statusbadformat': this.errormessages.statusbadformat = code.children[i].data; this.errors.statusbadformat = false; break;
+ case 'statustooshort': this.errormessages.statustooshort = code.children[i].data; this.errors.statustooshort = false; break;
+ case 'statustoolong': this.errormessages.statustoolong = code.children[i].data; this.errors.statustoolong = false; break;
+ case 'statustoofewwords': this.errormessages.statustoofewwords = code.children[i].data; this.errors.statustoofewwords = false; break;
+ case 'statustoomanywords': this.errormessages.statustoomanywords = code.children[i].data; this.errors.statustoomanywords = false; break;
+ case 'statustoolow': this.errormessages.statustoolow = code.children[i].data; this.errors.statustoolow = false; break;
+ case 'statustoohigh': this.errormessages.statustoohigh = code.children[i].data; this.errors.statustoohigh = false; break;
+ case 'statuscheck': this.errormessages.statuscheck = code.children[i].data; this.errors.statuscheck = false; break;
+ case 'automessage': this.automessage = code.children[i].data; break;
+ }
+ }
+ }
+ // NODES
+ this.domNodeLabel = WA.createDomNode('label', domID+'_label', this.classes.classname + 'label');
+ this.father.domNode.insertBefore(this.domNodeLabel, this.domNode);
+ if (self.code.data)
+ this.domNodeLabel.innerHTML = self.code.data;
+
+ this.domNodeValue = WA.createDomNode('div', domID+'_value', 'value');
+ this.domNode.appendChild(this.domNodeValue);
+
+ this.domNodeSearch = WA.createDomNode('input', domID + '_search', 'field');
+ this.domNodeSearch.type = this.texttype == 'masked' ? 'password' : 'text';
+ this.domNodeSearch.autocomplete = "off";
+ if (this.maxlength)
+ this.domNodeSearch.maxLength = this.maxlength;
+ if (this.size)
+ this.domNodeSearch.style.width = this.size + 'px';
+ this.domNode.appendChild(this.domNodeSearch);
+
+ this.domNodeList = WA.createDomNode('div', domID + '_list', 'list');
+ this.domNodeList.style = "width: " + this.size + "px;";
+ this.domNode.appendChild(this.domNodeList);
+
+ this.domNodeField = WA.createDomNode('input', domID+'_field', 'selected');
+ this.domNodeField.type = 'text';
+ this.domNodeField.name = this.id;
+ this.domNodeField.readOnly = true;
+ this.domNode.appendChild(this.domNodeField);
+
+ this.domNodeCount = WA.createDomNode('span', domID+'_count', 'count');
+ this.domNode.appendChild(this.domNodeCount);
+
+ this.domNodeHelp = WA.createDomNode('p', domID+'_help', 'help');
+ this.domNode.appendChild(this.domNodeHelp);
+ if (self.helpmessage)
+ this.domNodeHelp.innerHTML = self.helpmessage;
+
+ this.domNodeError = WA.createDomNode('p', domID+'_error', 'error');
+ this.domNode.appendChild(this.domNodeError);
+ this.domNodeResult = WA.createDomNode('div', domID + '_result', 'result');
+ this.domNode.appendChild(this.domNodeResult);
+
+ // responsive design based on container available size, is '', ' medium' or ' tiny'
+ // Not activated for now
+ this.sizemode = '';
+
+ // we link with the group. first father is the zone, second father is the group
+ // *********************************************
+ // NOTE: THIS IS WRONG; THERE MAY BE MORE CONTAINERS INTO THE ZONES ETC
+ // THE GROUP SHOULD BE SEARCH BY ID INTO THE 4GL TREE
+ this.group = null;
+ if (this.father.father.code.attributes.type == "groupContainer")
+ {
+ this.group = this.father.father;
+ this.group.registerField(this);
+ }
+ else
+ {
+ if (this.defaultvalue)
+ this.domNodeField.value = this.defaultvalue;
+ }
+
+ // If we control some other fields
+ this.synchronizer = null;
+ this.synchronizeelements = [];
+
+ this.addEvent('resize', resize);
+ this.addEvent('start', start);
+ this.addEvent('stop', stop);
+
+ function resize()
+ {
+ WA.Elements.searchabletextfieldElement.source.resize.call(self);
+ // size mode for responsive design, not activated for now
+/*
+ var RW = WA.browser.getNodeOuterWidth(self.father.domNode);
+ var W1 = WA.browser.getNodeOuterWidth(self.domNodeField); // should be always fixed by CSS or code. We consider fields as fixed size always
+ if (RW > W1*2 + 180 && self.sizemode != '')
+ self.sizemode = '';
+ else if (RW > W1 + 180 && self.sizemode != ' medium')
+ self.sizemode = ' medium';
+ else if (self.sizemode != ' tiny')
+ self.sizemode = ' tiny';
+ checkClass();
+*/
+ }
+
+ this.registerSynchronize = registerSynchronize;
+ function registerSynchronize(element)
+ {
+ self.synchronizeelements.push(element);
+ }
+
+ this.unregisterSynchronize = unregisterSynchronize;
+ function unregisterSynchronize(element)
+ {
+ for (var i=0, l=self.synchronizeelements.length; i < l; i++)
+ {
+ if (self.synchronizeelements[i] == element)
+ {
+ self.synchronizeelements.splice(i, 1);
+ break;
+ }
+ }
+ return;
+ }
+
+ this.checkStatus = checkStatus;
+ function checkStatus()
+ {
+ for (var i in self.errors)
+ self.errors[i] = false;
+
+ if (self.mode == 0 || !self.edition)
+ {
+ self.status = 0;
+ self.domNodeError.innerHTML = '';
+ self.domNodeCount.innerHTML = '';
+ return;
+ }
+
+ // default = ok, status = 1 (ok), 2 (editing), 3 (error), 4 (r/o), 5 (disabled)
+ if (self.synchronizer)
+ {
+ // we rebuild synchronizer
+ self.synchronizer.checkStatus();
+ self.status = self.synchronizer.status;
+ return;
+ }
+
+ // we check anything based on the attributes of the field
+ if (self.disabled[self.mode])
+ {
+ self.status = 4;
+ return;
+ }
+ if (self.readonly[self.mode])
+ {
+ self.status = 3;
+ return;
+ }
+ if (self.domNodeField.disabled == true)
+ self.domNodeField.disabled == false;
+ if (self.domNodeField.readOnly == true)
+ self.domNodeField.readOnly == false;
+ var value = self.domNodeField.value;
+ if (self.value != undefined && value == self.value && self.mode != 1)
+ {
+ self.status = 0;
+ self.domNodeError.innerHTML = '';
+ self.domNodeCount.innerHTML = '';
+ return;
+ }
+ if (self.mode == 1 && self.auto)
+ {
+ self.status = 0;
+ return;
+ }
+
+ self.status = 1;
+ if (self.notnull[self.mode] && value == '')
+ {
+ self.status = 2;
+ self.errors.statusnotnull = true;
+ }
+
+ if (self.format && value.match(self.format) == null)
+ {
+ self.status = 2;
+ self.errors.statusbadformat = true;
+ }
+ if (self.texttype == "integer")
+ {
+ nv = parseInt(value, 10)
+ min = parseInt(self.min, 10)
+ max = parseInt(self.max, 10)
+ if (min != max && nv < min)
+ {
+ self.status = 2;
+ self.errors.statustoolow = true;
+ }
+ if (min != max && nv > max)
+ {
+ self.status = 2;
+ self.errors.statustoohigh = true;
+ }
+ }
+ if (self.texttype == "float")
+ {
+ nv = parseFloat(value)
+ min = parseFloat(self.min)
+ max = parseFloat(self.max)
+ if (min != max && nv < min)
+ {
+ self.status = 2;
+ self.errors.statustoolow = true;
+ }
+ if (min != max && nv > max)
+ {
+ self.status = 2;
+ self.errors.statustoohigh = true;
+ }
+ }
+ if (self.texttype == "text" || self.texttype == "masked")
+ {
+ if (self.minlength && value.length < self.minlength)
+ {
+ self.status = 2;
+ self.errors.statustooshort = true;
+ }
+ if (self.maxlength && value.length > self.maxlength)
+ {
+ self.status = 2;
+ self.errors.statustoolong = true;
+ }
+ var text = value;
+ text = text.replace(/[\n\t\r]+/g, " ");
+ text = text.replace(/^[ ]+/, "");
+ text = text.replace(/[ ]+$/, "");
+ text = text.replace(/[ ]+/g, " ");
+ var numpalabras = (text.length > 0 ? text.split(" ").length : 0);
+ if (self.maxwords || self.minwords)
+ {
+ if (numpalabras < self.minwords)
+ {
+ self.status = 2;
+ self.errors.statustoofewwords = true;
+ }
+ if (numpalabras > self.maxwords)
+ {
+ self.status = 2;
+ self.errors.statustoomanywords = true;
+ }
+ }
+ self.domNodeCount.innerHTML = numpalabras + '/' + value.length;
+ }
+ if (self.errorexternal)
+ self.status = 2;
+ // user own checks
+ if (self.code[0] != undefined && self.code[0].tag != undefined && self.code[0].tag == 'check')
+ eval(self.code[0].data);
+ }
+
+ this.checkClass = checkClass;
+ function checkClass()
+ {
+ var extras = '';
+ switch (self.status)
+ {
+ case 4: extras += ' disabled'; self.domNodeField.disabled = true; break;
+ case 3: extras += ' readonly'; self.domNodeField.readOnly = true; break;
+ case 2: extras += ' error'; if (self.group) self.father.setStatus(self.focus?1:(self.firstview?0:3)); break;
+ case 1: extras += ' ok'; if (self.group) self.father.setStatus(self.focus?1:(self.firstview?0:2)); break;
+ default: if (self.group) self.father.setStatus(self.focus?1:0); break;
+ }
+ if (self.focus)
+ extras += ' edition';
+ self.domNodeLabel.className = self.classes.classname + 'label' + extras + self.sizemode;
+ self.domNode.className = self.classes.classname + extras + self.sizemode;
+ }
+
+ this.checkChildren = checkChildren;
+ function checkChildren(onlylocal)
+ {
+ if (!onlylocal)
+ {
+ for (var i=0, l=self.synchronizeelements.length; i < l; i++)
+ {
+ self.synchronizeelements[i].status = self.status;
+ self.synchronizeelements[i].checkClass();
+ self.synchronizeelements[i].checkChildren();
+ }
+ }
+ }
+
+ this.checkAll = checkAll;
+ function checkAll(notifygroup)
+ {
+ self.checkStatus();
+ self.checkClass();
+ self.checkChildren(false);
+
+ if (!self.firstview)
+ {
+ if (!self.errorexternal)
+ {
+ var text = '';
+ for (var i in self.errors)
+ {
+ if (self.errors[i])
+ text += self.errormessages[i] + '
';
+ }
+ self.domNodeError.innerHTML = text;
+ }
+ }
+ else
+ self.domNodeError.innerHTML = '';
+ if (self.group && notifygroup)
+ {
+ self.group.pleaseCheck();
+ }
+ }
+
+ this.setError = setError;
+ function setError(values)
+ {
+ self.domNodeError.innerHTML = values;
+ self.errorexternal = true;
+ checkAll();
+ }
+
+ this.setMode = setMode;
+ function setMode(mode, keep)
+ {
+ self.mode = mode;
+
+ // Set all the data based on the mode
+ if (!self.isvisible[mode])
+ {
+ if (self.group)
+ self.father.hide();
+ return;
+ }
+ if (self.group)
+ self.father.show();
+
+ if (keep)
+ self.domNodeValue.innerHTML = self.domNodeField.value;
+ if (mode == 1 && self.auto)
+ {
+ self.domNodeValue.style.display = '';
+ self.domNodeField.style.display = 'none';
+ }
+ else
+ {
+ self.domNodeValue.style.display = (self.info[mode]?'':'none');
+ self.domNodeField.style.display = (self.info[mode]?'none':'');
+ }
+
+ self.domNodeHelp.style.display = (self.help[mode]?'':'none');
+ self.domNodeCount.style.display = (self.info[mode]?'none':'');
+ self.domNodeError.style.display = (self.info[mode]?'none':'');
+ self.edition = !self.info[mode];
+ if (mode == 1)
+ {
+ reset();
+ }
+ else
+ checkAll();
+ }
+
+ function filllist(list) {
+ self.domNodeList.innerHTML = "";
+ for (var i in list) {
+ var item = WA.createDomNode('div', self.id + '_list_' + i, 'item');
+ item.innerHTML = i + " / " + list[i];
+ item.value = list[i];
+ item.key = i;
+ item.onclick = function() {
+ console.log("CLICK", this.key);
+ self.domNodeSearch.value = this.value;
+ self.domNodeField.value = this.key;
+ self.domNodeList.style.display = 'none';
+ self.haslist = false;
+ self.showlist = false;
+ checkAll(true); // check and notify group
+ search();
+ }
+ item.onmouseover = function () {
+ this.className = 'item selected';
+ self.itemover = true;
+ }
+ item.onmouseout = function () {
+ this.className = 'item';
+ self.itemover = false;
+ }
+ self.domNodeList.appendChild(item);
+ }
+ self.haslist = true;
+ self.showlist = true;
+ self.domNodeList.style.display = 'block';
+ }
+
+ function getResponse(request) {
+
+ var code = WA.JSON.decode(request.responseText);
+ if (code.status != 1)
+ {
+ self.status = 2;
+ self.errors.statusnotnull = true;
+ }
+ else
+ self.status = 1;
+ self.checkClass();
+
+ self.domNodeField.value = code.key;
+ self.domNodeResult.innerHTML = code.message;
+
+ if (code.list && !code.key) {
+ // Fill in the list
+ filllist(code.list);
+ } else {
+ self.haslist = false;
+ self.showlist = false;
+ self.domNodeList.style.display = 'none';
+ if (code.value)
+ self.domNodeSearch.value = code.value;
+ }
+
+ checkAll(true);
+ }
+
+ this.sendServer = sendServer;
+ function sendServer(order, code, response) {
+ // send information to server based on mode
+ if (!response) response = getResponse;
+ var request = WA.Managers.ajax.createRequest(WA.Managers.wa4gl.url + WA.Managers.wa4gl.prelib + self.app.applicationID + WA.Managers.wa4gl.premethod + self.id + WA.Managers.wa4gl.preformat + WA.Managers.wa4gl.format, 'POST', 'Order=' + order + (self.params ? '&' + self.params : ''), response, false);
+ if (request) {
+ for (var i in code) {
+ request.addParameter(i, code[i]);
+ }
+ request.send();
+ }
+ }
+
+ this.reset = reset;
+ function reset()
+ {
+ if (!self.edition)
+ return;
+ if (self.mode == 1)
+ {
+ self.value = self.domNodeField.value = self.domNodeSearch.value = self.defaultvalue;
+ self.domNodeValue.innerHTML = self.auto?self.automessage:self.defaultvalue;
+ }
+ else if (self.mode == 2 || self.mode == 3)
+ {
+ self.domNodeValue.innerHTML = self.domNodeField.value = self.domNodeSearch.value = self.value;
+ }
+ checkAll();
+ }
+
+ this.search = search;
+ function search()
+ {
+ // if ENTER, send
+ self.sendServer('search', { id: self.code.attributes.id, key: self.domNodeField.value, q: self.domNodeSearch.value });
+ }
+
+ function onkeyup(e)
+ {
+ console.log("KEY UP", e, self.id);
+ self.firstview = false;
+ self.errorexternal = false;
+ if ((self.value == undefined || self.value == null || self.value == '') && self.domNodeSearch.value == '')
+ self.firstview = true;
+ else if (self.value != undefined && self.value != null && self.domNodeSearch.value == self.value)
+ self.firstview = true;
+ setTimeout( function() { checkAll(true); }, 0); // check and notify group
+ setTimeout( function() { self.callEvent('keyup'); }, 0); // call event key up
+ self.domNodeField.value = "";
+ search();
+ }
+
+ function onblur(e)
+ {
+ self.focus = false;
+ setTimeout(function() {
+ if (self.haslist && !self.itemover) {
+ self.domNodeList.style.display = 'none';
+ self.showlist = false;
+ }
+ }, 1);
+ if (!self.haslist)
+ {
+ checkAll(true); // check and notify group
+ self.callEvent('blur');
+ search();
+ }
+}
+
+ function onfocus(e)
+ {
+ self.focus = true;
+ if (self.haslist) {
+ console.log("FOCUS")
+ self.domNodeList.style.display = 'block';
+ self.showlist = true;
+ }
+ checkAll(true); // check and notify group
+ if (self.group)
+ self.father.setStatus(1);
+ self.callEvent('focus');
+ }
+
+ function start()
+ {
+ console.log("START", self.id, self.domNodeSearch);
+
+ WA.Managers.event.on('keyup', self.domNodeSearch, onkeyup, true);
+ WA.Managers.event.on('focus', self.domNodeSearch, onfocus, true);
+ WA.Managers.event.on('blur', self.domNodeSearch, onblur, true);
+
+ // If we are controled by another field
+ if (self.code.attributes.synchronizer)
+ {
+ self.synchronizer = WA.$N(self.code.attributes.synchronizer);
+ if (self.synchronizer)
+ self.synchronizer.registerSynchronize(self);
+ }
+ // we do not check, there is still no value. the setMode will do the job
+ }
+
+ this.getValues = getValues;
+ function getValues()
+ {
+ return self.domNodeField.value;
+ }
+
+ this.setValues = setValues;
+ function setValues(values)
+ {
+ if (self.group)
+ {
+ self.firstview = true;
+ self.value = self.domNodeField.value = self.domNodeSearch.value = values;
+ if (values != undefined && values != null)
+ self.domNodeValue.innerHTML = values;
+ else
+ reset();
+ checkAll();
+ }
+ else
+ {
+ self.domNodeField.value = values;
+ self.domNodeSearch.value = values;
+ }
+ }
+
+ this.stop = stop;
+ function stop()
+ {
+ if (self.group)
+ self.group.unregisterField(self);
+ WA.Managers.event.off('keyup', self.domNodeSearch, onkeyup, true);
+ WA.Managers.event.off('focus', self.domNodeSearch, onfocus, true);
+ WA.Managers.event.off('blur', self.domNodeSearch, onblur, true);
+ }
+
+ this.destroy = destroy;
+ function destroy(fast)
+ {
+ WA.Elements.searchabletextfieldElement.source.destroy.call(self, fast);
+
+ self.synchronizer = null;
+ self.synchronizeelements = [];
+ self.group = null;
+ self.domNodeError = null;
+ self.domNodeHelp = null;
+ self.domNodeValue = null;
+ self.domNodeSearch = null;
+ self.domNodeCount = null;
+ self.domNodeField = null;
+ self.domNodeLabel = null;
+ self.errormessages = null;
+ self.errors = null;
+ self.isvisible = null;
+ self.info = null;
+ self.disabled = null;
+ self.readonly = null;
+ self.notnull = null;
+ self.help = null;
+ self = null;
+ }
+}
+
+// Add basic element code
+WA.extend(WA.Elements.searchabletextfieldElement, WA.Managers.wa4gl._element);
diff --git a/js/elements/textareafieldElement.js b/js/elements/textareafieldElement.js
index 5d9d3f2..4103cbe 100644
--- a/js/elements/textareafieldElement.js
+++ b/js/elements/textareafieldElement.js
@@ -230,14 +230,14 @@ WA.Elements.textareafieldElement = function(fatherNode, domID, code, listener)
self.status = 2;
self.errors.statustoolong = true;
}
+ var text = value;
+ text = text.replace(/^[ ]+/, "");
+ text = text.replace(/[ ]+$/, "");
+ text = text.replace(/[ ]+/g, " ");
+ text = text.replace(/[\n]+/g, " ");
+ var numpalabras = (text.length > 0 ? text.split(" ").length : 0);
if (self.maxwords || self.minwords)
{
- var text = value;
- text = text.replace(/^[ ]+/, "");
- text = text.replace(/[ ]+$/, "");
- text = text.replace(/[ ]+/g, " ");
- text = text.replace(/[\n]+/g, " ");
- var numpalabras = (text.length>0?text.split(" ").length:0);
if (numpalabras < self.minwords)
{
self.status = 2;
@@ -248,8 +248,8 @@ WA.Elements.textareafieldElement = function(fatherNode, domID, code, listener)
self.status = 2;
self.errors.statustoomanywords = true;
}
- self.domNodeCount.innerHTML = numpalabras + '/' + value.length;
}
+ self.domNodeCount.innerHTML = numpalabras + '/' + value.length;
// user own checks
if (self.code[0] != undefined && self.code[0].tag != undefined && self.code[0].tag == 'check')
eval(self.code[0].data);
diff --git a/js/elements/textfieldElement.js b/js/elements/textfieldElement.js
index fbd00eb..ced8e7d 100644
--- a/js/elements/textfieldElement.js
+++ b/js/elements/textfieldElement.js
@@ -300,14 +300,14 @@ WA.Elements.textfieldElement = function(fatherNode, domID, code, listener)
self.status = 2;
self.errors.statustoolong = true;
}
+ var text = value;
+ text = text.replace(/[\n\t\r]+/g, " ");
+ text = text.replace(/^[ ]+/, "");
+ text = text.replace(/[ ]+$/, "");
+ text = text.replace(/[ ]+/g, " ");
+ var numpalabras = (text.length > 0 ? text.split(" ").length : 0);
if (self.maxwords || self.minwords)
{
- var text = value;
- text = text.replace(/[\n\t\r]+/g, " ");
- text = text.replace(/^[ ]+/, "");
- text = text.replace(/[ ]+$/, "");
- text = text.replace(/[ ]+/g, " ");
- var numpalabras = (text.length>0?text.split(" ").length:0);
if (numpalabras < self.minwords)
{
self.status = 2;
@@ -318,8 +318,8 @@ WA.Elements.textfieldElement = function(fatherNode, domID, code, listener)
self.status = 2;
self.errors.statustoomanywords = true;
}
- self.domNodeCount.innerHTML = numpalabras + '/' + value.length;
}
+ self.domNodeCount.innerHTML = numpalabras + '/' + value.length;
}
if (self.errorexternal)
self.status = 2;
diff --git a/js/managers/ajaxManager.js b/js/managers/ajaxManager.js
index 37a9912..a7462d6 100644
--- a/js/managers/ajaxManager.js
+++ b/js/managers/ajaxManager.js
@@ -61,10 +61,7 @@ WA.Managers.ajax = new function()
{
callNotify('create');
var r = new WA.Managers.ajax.Request(url, method, data, feedback, dosend, self.listener, self.statefeedback, self.timeoutabort);
- if (r)
- {
- self.requests.push(r);
- }
+ self.requests.push(r);
return r;
}
@@ -151,6 +148,7 @@ WA.Managers.ajax.Request = function(url, method, data, feedback, autosend, liste
this.timerabort = null;
this.state = 0; // 0 = nothing, 1 = sent and waiting, 2 = finished, 3 = error
this.listener = listener;
+ this.uploadlistener = null;
try { this.request = new XMLHttpRequest(); }
catch(e)
@@ -173,6 +171,12 @@ WA.Managers.ajax.Request = function(url, method, data, feedback, autosend, liste
}
}
+ this.setUploadListener = setUploadListener;
+ function setUploadListener(listener)
+ {
+ self.uploadlistener = listener;
+ }
+
// Special parameters
this.setPeriodic = setPeriodic;
function setPeriodic(period, times)
@@ -259,6 +263,9 @@ WA.Managers.ajax.Request = function(url, method, data, feedback, autosend, liste
return;
self.request.onreadystatechange = process;
+ if (self.uploadlistener) {
+ self.request.upload.addEventListener("progress", self.uploadlistener);
+ }
if (self.timeoutabort)
self.timerabort = setTimeout( function() { timeabort(); }, self.timeoutabort );
try
@@ -278,9 +285,7 @@ WA.Managers.ajax.Request = function(url, method, data, feedback, autosend, liste
if (self.method == 'POST')
{
if (!!form)
- {
self.request.send(form);
- }
else
{
var parameters = buildParametersPost();
diff --git a/js/managers/wa4glManager.js b/js/managers/wa4glManager.js
index 058179b..5a8c08d 100644
--- a/js/managers/wa4glManager.js
+++ b/js/managers/wa4glManager.js
@@ -598,6 +598,8 @@ WA.Managers.wa4gl = new function()
if (app.domNode == null)
throw 'Error, the application could not be launched.';
+ fatherNode.application = app;
+
self.applications[applicationID+'|'+instanceID] = app;
app.start(params);
diff --git a/js/system/core.js b/js/system/core.js
index 7e8fd97..21b4f17 100644
--- a/js/system/core.js
+++ b/js/system/core.js
@@ -23,7 +23,7 @@
// --------------------------------------------------------------------------------------------------------
// WA is the main WAJAF Object that will contain anything else (except for the native JS object prototypes)
// --------------------------------------------------------------------------------------------------------
-var WA = { version: '0.3.0',
+var WA = { version: '0.1.4',
running: false };
// Main WAJAF Object definition
diff --git a/js/system/corebrowser.js b/js/system/corebrowser.js
index a4aa3df..cfc4b50 100644
--- a/js/system/corebrowser.js
+++ b/js/system/corebrowser.js
@@ -145,12 +145,37 @@ WA.browser.getScrollHeight = function()
return WA.browser.getDocumentHeight();
}
+WA.browser.findNodeByClass = function(rootnode, className)
+{
+ // Check if the current node has the desired class
+ if (rootnode.classList && rootnode.classList.contains(className)) {
+ return rootnode;
+ }
+
+ // Iterate over the children of the current node
+ for (let i = 0; i < rootnode.childNodes.length; i++) {
+ const childNode = rootnode.childNodes[i];
+
+ // Recursively call to search the child node tree
+ const foundNode = WA.browser.findNodeByClass(childNode, className);
+
+ // If the node with the desired class is found, return it
+ if (foundNode) {
+ return foundNode;
+ }
+ }
+
+ // If no node with the desired class is found in this subtree, return null
+ return null;
+}
+
+
// get the left of a DOM element into the document
WA.browser.getNodeDocumentLeft = function(node)
{
var l = node.offsetLeft;
if (node.offsetParent != null)
- l += WA.browser.getNodeDocumentLeft(node.offsetParent) + WA.browser.getNodeBorderLeftWidth(node.offsetParent) + WA.browser.getNodeMarginLeftWidth(node.offsetParent);
+ l += WA.browser.getNodeDocumentLeft(node.offsetParent) - WA.browser.getNodeScrollLeft(node.offsetParent);
return l;
}
@@ -159,7 +184,7 @@ WA.browser.getNodeDocumentTop = function(node)
{
var t = node.offsetTop;
if (node.offsetParent != null)
- t += WA.browser.getNodeDocumentTop(node.offsetParent) + WA.browser.getNodeBorderTopHeight(node.offsetParent) + WA.browser.getNodeMarginTopHeight(node.offsetParent);
+ t += WA.browser.getNodeDocumentTop(node.offsetParent) - WA.browser.getNodeScrollTop(node.offsetParent);
return t;
}
diff --git a/js/system/coretemplate.js b/js/system/coretemplate.js
index e69de29..00d4e75 100644
--- a/js/system/coretemplate.js
+++ b/js/system/coretemplate.js
@@ -0,0 +1,143 @@
+
+WA.templates = {};
+WA.templatesstrings = {};
+WA.codes = {};
+
+WA.templater = function (strings, ...keys) {
+ function searchdata(data, key) {
+ if ((pos = key.indexOf(">")) != -1) {
+ first = key.substr(0, pos);
+ val = data[first];
+ if (WA.isArray(val) || WA.isObject(val) || WA.isFunction(val))
+ return searchdata(val, key.substr(pos + 1))
+ return undefined;
+ }
+ if (data)
+ return data[key];
+ return null;
+ }
+ function searchdatapile(datapile, key) {
+ if (!key)
+ return '';
+ for (var i = datapile.length - 1; i >= 0; i--) {
+ var val = searchdata(datapile[i], key);
+ if (val !== undefined)
+ return val;
+ }
+ return '';
+ }
+ function loop(templates, datapile, data, template) {
+ if (!templates)
+ templates = WA.templates;
+ if (!data || !WA.isArray(data) || data.length == 0) {
+ if (templates[template + ".none"])
+ return templates[template + ".none"](datapile, templates);
+ return "";
+ }
+ txt = "";
+ for (var i = 0; i < data.length; i++) {
+ datapile.push(data[i]);
+ if (templates[template + ".key." + i])
+ txt += templates[template + ".key." + i](datapile, templates);
+ else if (i == 0 && templates[template + ".first"])
+ txt += templates[template + ".first"](datapile, templates);
+ else if (i == data.length - 1 && templates[template + ".last"])
+ txt += templates[template + ".last"](datapile, templates);
+ else if (i % 2 == 0 && templates[template + ".even"])
+ txt += templates[template + ".even"](datapile, templates);
+ else if (templates[template])
+ txt += templates[template](datapile, templates);
+ else
+ txt += "";
+ datapile.pop();
+ }
+ return txt;
+ }
+ function cond(templates, field, template, datapile) {
+ if (!templates)
+ templates = WA.templates;
+
+ val = searchdatapile(datapile, field);
+ var pushed = false;
+ if (val != null && (WA.isArray(val) || WA.isObject(val) || WA.isFunction(val))) {
+ pushed = true;
+ datapile.push(val);
+ }
+ if (!val && templates[template + ".none"])
+ text = templates[template + ".none"](datapile, templates);
+ else if (val && templates[template + "." + val])
+ text = templates[template + "." + val](datapile, templates);
+ else if (templates[template])
+ text = templates[template](datapile, templates);
+ else
+ text = "";
+ if (pushed)
+ datapile.pop();
+
+ return text;
+ }
+ function call(templates, template, data) {
+ if (!templates)
+ templates = WA.templates;
+ if (templates[template])
+ return templates[template](data, templates);
+ return "";
+ }
+
+ return function (data, templates) {
+ let temp = strings.slice();
+ let datapile = data
+ if (!WA.isArray(data))
+ datapile = [data];
+ keys.forEach((key, i) => {
+ if (Array.isArray(key)) {
+ switch (key[0]) {
+ case "eval":
+ temp[i] = temp[i] + eval(key[1]);
+ break;
+ case "loop":
+ val = searchdatapile(datapile, key[1]);
+ if (!WA.isArray(val))
+ val = undefined;
+ temp[i] = temp[i] + loop(templates, datapile, val, key[2] ? key[2] : key[1]);
+ break;
+ case "cond":
+ temp[i] = temp[i] + cond(templates, key[1], key[2], datapile);
+ break;
+ case "call":
+ if (key[3]) {
+ template = key[3] + searchdatapile(datapile, key[2]);
+ temp[i] = temp[i] + call(templates, template, datapile);
+ }
+ else {
+ val = searchdatapile(datapile, key[2]);
+ var pushed = false;
+ if (WA.isArray(val) || WA.isObject(val) || WA.isFunction(val)) {
+ pushed = true;
+ datapile.push(val);
+ }
+ temp[i] = temp[i] + call(templates, key[1], datapile);
+ if (pushed)
+ datapile.pop();
+ }
+ break;
+ default:
+ temp[i] = temp[i] + "";
+ }
+ }
+ else {
+ temp[i] = temp[i] + searchdatapile(datapile, key);
+ }
+ });
+ return temp.join('');
+ }
+};
+
+WA.XTemplate = function (temps) {
+
+ var templates = temps
+
+ return function run(data) {
+ return templates.main(data, templates);
+ }
+}
diff --git a/lovfieldelement.go b/lovfieldelement.go
index 9553205..0f94627 100644
--- a/lovfieldelement.go
+++ b/lovfieldelement.go
@@ -8,7 +8,7 @@ func NewLOVFieldElement(id string) LOVFieldElement {
e.SetID(id)
e.RegisterKnownAttributes([]string{"display", "style", "classname", "left", "width", "right", "top", "height", "bottom",
- "size", "visible", "info", "disabled", "readonly", "notnull", "helpmode"})
+ "size", "visible", "info", "disabled", "readonly", "notnull", "helpmode", "multiselect", "radiobutton"})
// e.RegisterKnownMessages([]string{"defaultvalue", "helpdescription", "statusnotnull", "statuscheck"})
e.RegisterKnownChildren([]string{"options", "code"})
diff --git a/mmcfieldelement.go b/mmcfieldelement.go
index 69dbc49..2459b7b 100644
--- a/mmcfieldelement.go
+++ b/mmcfieldelement.go
@@ -7,7 +7,9 @@ func NewMMCFieldElement(id string) MMCFieldElement {
e := NewNode("element", "mmcfieldElement")
e.SetID(id)
- e.RegisterKnownAttributes([]string{"display", "style", "classname", "left", "width", "right", "top", "height", "bottom"})
-
+ e.RegisterKnownAttributes([]string{"display", "style", "classname", "left", "width", "right", "top", "height", "bottom", "size",
+ "visible", "info", "disabled", "readonly", "notnull", "helpmode",
+ "path", "external", "deletebutton", "loading", "accept", "multifile"})
+ // e.RegisterKnownMessages([]string{"defaultvalue", "helpdescription", "statusnotnull"} )
return e
}
diff --git a/searchabletextfieldelement.go b/searchabletextfieldelement.go
new file mode 100644
index 0000000..0e1e613
--- /dev/null
+++ b/searchabletextfieldelement.go
@@ -0,0 +1,16 @@
+package wajaf
+
+type SearchableTextFieldElement NodeDef
+
+func NewSearchableTextFieldElement(id string) SearchableTextFieldElement {
+
+ e := NewNode("element", "searchabletextfieldElement")
+ e.SetID(id)
+
+ e.RegisterKnownAttributes([]string{"display", "style", "classname", "left", "width", "right", "top", "height", "bottom",
+ "size", "texttype", "minlength", "maxlength", "minwords", "maxwords", "min", "max", "format", "visible", "info",
+ "disabled", "readonly", "notnull", "helpmode", "auto"})
+ // e.RegisterKnownMessages([]string{"defaultvalue", "helpdescription", "statusnotnull", "statusbadformat", "statustooshort", "statustoolong", "statustoofewwords", "statustoomanywords", "statuscheck"})
+
+ return e
+}
diff --git a/wajaf.go b/wajaf.go
index 18e0182..184a085 100644
--- a/wajaf.go
+++ b/wajaf.go
@@ -7,7 +7,7 @@
package wajaf
// VERSION is the used version nombre of the XCore library.
-const VERSION = "0.1.3"
+const VERSION = "0.3.0"
// LOG is the flag to activate logging on the library.
// if LOG is set to TRUE, LOG indicates to the XCore libraries to log a trace of functions called, with most important parameters.