Files
alfresco-community-repo/source/web/scripts/ajax/xforms.js
Ariel Backenroth 253a51f5e4 - getting error reporting to work on IE
- modifications to error reporting based on conversation with linton this morning.  we'll do something more sophisticated for preview II (or the release), but for now, something clean and clear (enumerate all errors above the form and change the label to be red).

- fixed some bugs with radios.  need to list them vertically, otherwise the ones with long labels don't show up.

- indicating getValue consistently, important for deciding which elements aren't ready for submit.

TODO: repeats are still not indicating required values correctly or providing submit errors properly.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@4085 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
2006-10-10 01:06:36 +00:00

1614 lines
58 KiB
JavaScript

dojo.require("dojo.widget.DebugConsole");
dojo.require("dojo.widget.DatePicker");
dojo.require("dojo.widget.Button");
dojo.require("dojo.widget.validate");
dojo.require("dojo.widget.Spinner");
dojo.require("dojo.lfx.html");
dojo.hostenv.writeIncludes();
var XFORMS_NS = "http://www.w3.org/2002/xforms";
var XFORMS_NS_PREFIX = "xforms";
var XHTML_NS = "http://www.w3.org/1999/xhtml";
var XHTML_NS_PREFIX = "xhtml";
var CHIBA_NS = "http://chiba.sourceforge.net/xforms";
var CHIBA_NS_PREFIX = "chiba";
function _xforms_init()
{
document.xform = new alfresco.xforms.XForm();
}
dojo.addOnLoad(_xforms_init);
tinyMCE.init({
theme: "advanced",
mode: "exact",
width: -1,
auto_resize: false,
force_p_newlines: false,
encoding: null,
save_callback: "document.xform.setXFormsValue",
add_unload_trigger: false,
add_form_submit_trigger: false,
theme_advanced_toolbar_location: "top",
theme_advanced_toolbar_align: "left",
theme_advanced_buttons1: "bold,italic,underline,strikethrough,separator,fontselect,fontsizeselect",
theme_advanced_buttons2: "link,unlink,image,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,bulllist,numlist,separator,undo,redo,separator,forecolor,backcolor",
theme_advanced_buttons3: ""
});
dojo.declare("alfresco.xforms.Widget",
null,
{
initializer: function(xform, node)
{
this.xform = xform;
this.node = node;
//XXXarielb this has to come back
// this.node.widget = this;
this.id = this.node.getAttribute("id");
this.modified = false;
this.valid = true;
},
node: null,
labelNode: null,
parent: null,
domContainer: null,
_getBinding: function()
{
return this.xform.getBinding(this.node);
},
setModified: function(b)
{
this.modified = b;
this._updateDisplay();
this.hideAlert();
},
setValid: function(b)
{
this.valid = b;
this._updateDisplay();
this.hideAlert();
},
setRequired: function(b)
{
this.required = b;
this._updateDisplay();
},
isValidForSubmit: function()
{
var result = true;
if (!this.valid)
return false;
if (!this.modified && this.isRequired() && this.getInitialValue() == null)
return false;
if (this.isRequired() && this.getValue() == null)
return false;
return true;
},
getDepth: function()
{
var result = 1;
var p = this.parent;
while (p)
{
result++;
p = p.parent;
}
return result;
},
isRequired: function()
{
var binding = this._getBinding();
var required = binding && binding.required == "true()";
return required;
},
getInitialValue: function()
{
var chibaData = _getElementsByTagNameNS(this.node,
CHIBA_NS,
CHIBA_NS_PREFIX,
"data");
if (chibaData.length == 0)
return null;
chibaData = chibaData[chibaData.length - 1];
var xpath = chibaData.getAttribute("chiba:xpath");
var d = this.node.ownerDocument;
var contextNode = this.xform.getInstance();
dojo.debug("locating " + xpath +
" from " + chibaData.nodeName +
" in " + contextNode.nodeName);
var result = _evaluateXPath("/" + xpath,
this.xform.getInstance(),
XPathResult.FIRST_ORDERED_NODE_TYPE);
result = (result.nodeType == dojo.dom.ELEMENT_NODE
? dojo.dom.textContent(result)
: result.nodeValue);
dojo.debug("resolved xpath " + xpath + " to " + result);
return result;
},
_getLabelNode: function()
{
var labels = _getElementsByTagNameNS(this.node, XFORMS_NS, XFORMS_NS_PREFIX, "label");
for (var i = 0; i < labels.length; i++)
{
dojo.debug("parent " + labels[i].parentNode.nodeName +
" o " + this.node.nodeName);
if (labels[i].parentNode == this.node)
return labels[i];
}
return null;
},
_getAlertNode: function()
{
var labels = _getElementsByTagNameNS(this.node, XFORMS_NS, XFORMS_NS_PREFIX, "alert");
for (var i = 0; i < labels.length; i++)
{
dojo.debug("parent " + labels[i].parentNode.nodeName +
" o " + this.node.nodeName);
if (labels[i].parentNode == this.node)
return labels[i];
}
return null;
},
getLabel: function()
{
var node = this._getLabelNode();
return node ? dojo.dom.textContent(node) : "";
},
getAlert: function()
{
var node = this._getAlertNode();
return node ? dojo.dom.textContent(node) : "";
},
showAlert: function()
{
if (this.labelNode._backupColor != "red")
this.labelNode._backupColor = this.labelNode.style.color;
this.labelNode.style.color = "red";
},
hideAlert: function()
{
if (this.labelNode.style.color == "red")
this.labelNode.style.color = this.labelNode._backupColor;
},
_updateDisplay: function()
{
// this.domContainer.style.backgroundColor =
// (!this.valid ? "yellow" : this.modified ? "lightgreen" : "white");
},
_destroy: function()
{
dojo.debug("destroying " + this.id);
}
});
dojo.declare("alfresco.xforms.DatePicker",
alfresco.xforms.Widget,
{
initializer: function(xform, node)
{
this.inherited("initializer", [ xform, node ]);
},
render: function(attach_point)
{
var initial_value = this.getInitialValue() || "";
this.domNode = document.createElement("div");
attach_point.appendChild(this.domNode);
this.widget = document.createElement("input");
this.widget.setAttribute("id", this.id + "-widget");
this.widget.setAttribute("type", "text");
this.widget.setAttribute("value", initial_value);
this.domNode.appendChild(this.widget);
dojo.event.connect(this.widget, "onfocus", this, this._dateTextBox_focusHandler);
var datePickerDiv = document.createElement("div");
attach_point.appendChild(datePickerDiv);
var dp_initial_value = (initial_value
? initial_value
: dojo.widget.DatePicker.util.toRfcDate(new Date()));
this.widget.picker = dojo.widget.createWidget("DatePicker",
{
isHidden: true,
storedDate: dp_initial_value
},
datePickerDiv);
this.widget.picker.hide();
dojo.event.connect(this.widget.picker,
"onSetDate",
this,
this._datePicker_setDateHandler);
},
getValue: function()
{
return (this.widget.value == null || this.widget.value.length == 0
? null
: this.widget.value);
},
_dateTextBox_focusHandler: function(event)
{
dojo.style.hide(this.widget);
this.widget.picker.show();
this.domContainer.style.height =
this.widget.picker.domNode.offsetHeight + "px";
},
_datePicker_setDateHandler: function(event)
{
this.widget.picker.hide();
dojo.style.show(this.widget);
this.domContainer.style.height =
Math.max(this.widget.offsetHeight, 20) + "px";
this.widget.value = dojo.widget.DatePicker.util.toRfcDate(this.widget.picker.date);
this.xform.setXFormsValue(this.id, this.getValue());
}
});
dojo.declare("alfresco.xforms.TextField",
alfresco.xforms.Widget,
{
initializer: function(xform, node)
{
this.inherited("initializer", [ xform, node ]);
},
render: function(attach_point)
{
var initial_value = this.getInitialValue() || "";
this.domNode = document.createElement("div");
this.domNode.setAttribute("id", this.id + "-domNode");
attach_point.appendChild(this.domNode);
this.widget = document.createElement("input");
this.widget.setAttribute("type", "text");
this.widget.setAttribute("id", this.id + "-widget");
this.widget.setAttribute("value", initial_value);
this.domNode.appendChild(this.widget);
// this.widget = dojo.widget.createWidget("ValidationTextBox",
// {
// widgetId: this.id + "-widget",
// required: this.isRequired(),
// value: initial_value
// },
// this.domNode);
dojo.event.connect(this.widget, "onkeyup", this, this._widget_keyUpHandler);
},
getValue: function()
{
var result = this.widget.value;
if (result != null && result.length == 0)
result = null;
return result;
},
_widget_keyUpHandler: function(event)
{
this.xform.setXFormsValue(this.id, this.getValue());
}
});
dojo.declare("alfresco.xforms.TextArea",
alfresco.xforms.Widget,
{
initializer: function(xform, node)
{
this.inherited("initializer", [ xform, node ]);
},
render: function(attach_point)
{
this.domNode = document.createElement("div");
attach_point.appendChild(this.domNode);
this.domNode.setAttribute("id", this.id);
this.domNode.style.height = "200px";
this.domNode.innerHTML = this.getInitialValue() || "";
tinyMCE.addMCEControl(this.domNode, this.id);
this.widget = this.domNode;
},
getValue: function()
{
return tinyMCE.getContent(this.id);
},
_destroy: function()
{
this.inherited("_destroy", []);
dojo.debug("removing mce control " + this.id);
tinyMCE.removeMCEControl(this.id);
}
});
dojo.declare("alfresco.xforms.AbstractSelectWidget",
alfresco.xforms.Widget,
{
initializer: function(xform, node)
{
this.inherited("initializer", [ xform, node ]);
},
getValues: function()
{
var binding = this._getBinding();
var values = _getElementsByTagNameNS(this.node, XFORMS_NS, XFORMS_NS_PREFIX, "item");
var result = [];
for (var v = 0; v < values.length; v++)
{
var label = _getElementsByTagNameNS(values[v], XFORMS_NS, XFORMS_NS_PREFIX, "label")[0];
var value = _getElementsByTagNameNS(values[v], XFORMS_NS, XFORMS_NS_PREFIX, "value")[0];
var valid = true;
if (binding.constraint)
{
dojo.debug("testing " + binding.constraint +
" on " + dojo.dom.textContent(value));
valid = _evaluateXPath(binding.constraint, value, XPathResult.BOOLEAN_TYPE);
}
dojo.debug("valid " + dojo.dom.textContent(value) + "? " + valid);
if (valid)
{
result.push({
id: value.getAttribute("id"),
label: dojo.dom.textContent(label),
value: dojo.dom.textContent(value)
});
}
}
return result;
}
});
dojo.declare("alfresco.xforms.Select",
alfresco.xforms.AbstractSelectWidget,
{
initializer: function(xform, node)
{
this.inherited("initializer", [ xform, node ]);
},
render: function(attach_point)
{
var values = this.getValues();
for (var i in values)
{
dojo.debug("values["+ i + "] = " + values[i].id +
", " + values[i].label + ", " + values[i].value);
}
var initial_value = this.getInitialValue();
if (values.length <= 5)
{
for (var i = 0; i < values.length; i++)
{
this.widget = document.createElement("span");
attach_point.appendChild(this.widget);
var checkbox = document.createElement("input");
checkbox.setAttribute("id", this.id + "_" + i + "-widget");
checkbox.setAttribute("name", this.id + "_" + i + "-widget");
checkbox.setAttribute("type", "checkbox");
checkbox.setAttribute("value", values[i].value);
if (initial_value.indexOf(values[i].value))
{
this._selectedValues.push(values[i].value);
checkbox.setAttribute("checked", "true");
}
dojo.event.connect(checkbox, "onclick", this, this._checkbox_clickHandler);
this.widget.appendChild(checkbox);
this.widget.appendChild(document.createTextNode(values[i].label));
}
}
else
{
initial_value = initial_value ? initial_value.split(' ') : [];
this.widget = document.createElement("select");
this.widget.setAttribute("id", this.id + "-widget");
this.widget.setAttribute("multiple", true);
attach_point.appendChild(this.widget);
for (var i = 0; i < values.length; i++)
{
var option = document.createElement("option");
option.appendChild(document.createTextNode(values[i].label));
option.setAttribute("value", values[i].value);
if (initial_value.indexOf(values[i].value) != -1)
{
this._selectedValues.push(values[i].value);
option.setAttribute("selected", "true");
}
this.widget.appendChild(option);
}
dojo.event.connect(this.widget, "onchange", this, this._list_changeHandler);
}
},
getValue: function()
{
return this._selectedValues.join(" ");
},
_list_changeHandler: function(event)
{
this._selectedValues = [];
for (var i = 0; i < event.target.options.length; i++)
{
if (event.target.options[i].selected)
this._selectedValues.push(event.target.options[i].value);
}
this.xform.setXFormsValue(this.id, this._selectedValues.join(" "));
},
_checkbox_clickHandler: function(event)
{
this._selectedValues = [];
for (var i = 0; i < 5; i++)
{
var checkbox = document.getElementById(this.id + "_" + i + "-widget");
if (checkbox && checkbox.checked)
this._selectedValues.push(checkbox.value);
}
this.xform.setXFormsValue(this.id, this._selectedValues.join(" "));
}
});
dojo.declare("alfresco.xforms.Select1",
alfresco.xforms.AbstractSelectWidget,
{
initializer: function(xform, node)
{
this.inherited("initializer", [ xform, node ]);
},
render: function(attach_point)
{
var values = this.getValues();
for (var i in values)
{
dojo.debug("values["+ i + "] = " + values[i].id +
", " + values[i].label + ", " + values[i].value);
}
var initial_value = this.getInitialValue();
if (values.length <= 5)
{
this.widget = document.createElement("div");
this.widget.style.width = "100%";
attach_point.appendChild(this.widget);
for (var i = 0; i < values.length; i++)
{
var radio_div = document.createElement("div");
radio_div.style.lineHeight = "16px";
this.widget.appendChild(radio_div);
var radio = document.createElement("input");
radio.setAttribute("id", this.id + "-widget");
radio.setAttribute("name", this.id + "-widget");
radio.setAttribute("type", "radio");
radio_div.appendChild(radio);
radio_div.appendChild(document.createTextNode(values[i].label));
radio.setAttribute("value", values[i].value);
if (values[i].value == initial_value)
{
this._selectedValue = initial_value;
radio.setAttribute("checked", "true");
}
dojo.event.connect(radio, "onclick", this, this._radio_clickHandler);
}
this.widget.style.height = this.widget.offsetHeight + "px";
}
else
{
this.widget = document.createElement("select");
this.widget.setAttribute("id", this.id + "-widget");
attach_point.appendChild(this.widget);
for (var i = 0; i < values.length; i++)
{
var option = document.createElement("option");
this.widget.appendChild(option);
option.appendChild(document.createTextNode(values[i].label));
option.setAttribute("value", values[i].value);
if (values[i].value == initial_value)
{
this._selectedValue = initial_value;
option.setAttribute("selected", "true");
}
}
dojo.event.connect(this.widget, "onchange", this, this._combobox_changeHandler);
}
},
getValue: function()
{
return this._selectedValue;
},
_combobox_changeHandler: function(event)
{
this._selectedValue = event.target.options[event.target.selectedIndex].value;
this.xform.setXFormsValue(this.id, this._selectedValue);
},
_radio_clickHandler: function(event)
{
if (!event.target.checked)
{
var all_radios = this.widget.getElementsByTagName("input");
for (var i = 0; i < all_radios.length; i++)
{
if (all_radios[i].name == event.target.name)
all_radios[i].checked = event.target == all_radios[i];
}
}
this._selectedValue = event.target.value;
this.xform.setXFormsValue(this.id, event.target.value);
}
});
dojo.declare("alfresco.xforms.Checkbox",
alfresco.xforms.Widget,
{
initializer: function(xform, node)
{
this.inherited("initializer", [ xform, node ]);
},
render: function(attach_point)
{
var initial_value = this.getInitialValue() == "true";
this.widget = document.createElement("input");
this.widget.setAttribute("type", "checkbox");
this.widget.setAttribute("id", this.id + "-widget");
attach_point.appendChild(this.widget);
if (initial_value)
this.widget.setAttribute("checked", true);
dojo.event.connect(this.widget, "onclick", this, this._checkbox_clickHandler);
},
getValue: function()
{
return this.widget.checked;
},
_checkbox_clickHandler: function(event)
{
this.xform.setXFormsValue(this.id, this.widget.checked);
}
});
dojo.declare("alfresco.xforms.Group",
alfresco.xforms.Widget,
{
initializer: function(xform, node)
{
this.inherited("initializer", [ xform, node ]);
this.children = [];
},
children: null,
getWidgetsInvalidForSubmit: function()
{
var result = [];
for (var i = 0; i < this.children.length; i++)
{
if (this.children[i] instanceof alfresco.xforms.Group)
result = result.concat(this.children[i].getWidgetsInvalidForSubmit());
else if (!this.children[i].isValidForSubmit())
result.push(this.children[i]);
}
return result;
},
getChildAt: function(index)
{
return index < this.children.length ? this.children[index] : null;
},
getChildIndex: function(child)
{
for (var i = 0; i < this.children.length; i++)
{
dojo.debug(this.id + "[" + i + "]: " +
" is " + this.children[i].id + " the same as " + child.id + "?");
if (this.children[i] == child)
return i;
}
return -1;
},
domNode: null,
addChild: function(child)
{
return this.insertChildAt(child, this.children.length);
},
insertChildAt: function(child, position)
{
dojo.debug(this.id + ".insertChildAt(" + child.id + ", " + position + ")");
child.parent = this;
child.domContainer = document.createElement("div");
child.domContainer.setAttribute("id", child.id + "-domContainer");
child.domContainer.style.marginTop = "2px";
child.domContainer.style.marginBottom = "2px";
child.domContainer.style.position = "relative";
child.domContainer.style.left = "0px";
child.domContainer.style.top = "0px";
child.domContainer.style.width = "100%";
if (this.parent && this.parent.domNode)
child.domContainer.style.top = this.parent.domNode.style.bottom;
if (position == this.children.length)
{
this.domNode.appendChild(child.domContainer);
this.children.push(child);
}
else
{
this.domNode.insertBefore(child.domContainer,
this.getChildAt(position).domContainer);
this.children.splice(position, 0, child);
}
if (!(child instanceof alfresco.xforms.Group))
{
var requiredImage = document.createElement("img");
requiredImage.setAttribute("src", WEBAPP_CONTEXT + "/images/icons/required_field.gif");
requiredImage.style.marginLeft = "5px";
requiredImage.style.marginRight = "5px";
child.domContainer.appendChild(requiredImage);
if (!child.isRequired())
requiredImage.style.visibility = "hidden";
var label = child._getLabelNode();
if (label)
{
child.labelNode = document.createElement("span");
child.domContainer.appendChild(child.labelNode);
child.labelNode.appendChild(document.createTextNode(dojo.dom.textContent(label)));
}
}
var contentDiv = document.createElement("div");
contentDiv.setAttribute("id", child.id + "-content");
child.domContainer.appendChild(contentDiv);
contentDiv.style.position = "relative";
contentDiv.style.left = (child instanceof alfresco.xforms.Group
? "0px"
: "30%");
if (!(child instanceof alfresco.xforms.Group))
{
contentDiv.style.width = (child.domContainer.offsetWidth * .55) + "px";
// contentDiv.style.width = ((child.domContainer.offsetWidth - contentDiv.offsetLeft) - 10) + "px";
}
child.render(contentDiv);
if (!(child instanceof alfresco.xforms.Group))
{
child.domContainer.style.height = Math.max(contentDiv.offsetHeight, 20) + "px";
child.domContainer.style.lineHeight = child.domContainer.style.height;
}
dojo.debug(contentDiv.getAttribute("id") + " offsetTop is " + contentDiv.offsetTop);
contentDiv.style.top = "-" + contentDiv.offsetTop + "px";
contentDiv.widget = child;
this._updateDisplay();
return child.domContainer;
},
removeChildAt: function(position)
{
var child = this.getChildAt(position);
if (!child)
throw new Error("unable to find child at " + position);
this.children.splice(position, 1);
child.domContainer.group = this;
var anim = dojo.lfx.html.fadeOut(child.domContainer, 500);
anim.onEnd = function()
{
child.domContainer.style.display = "none";
child._destroy();
dojo.dom.removeChildren(child.domContainer);
dojo.dom.removeNode(child.domContainer);
child.domContainer.group._updateDisplay();
};
anim.play();
},
_destroy: function()
{
this.inherited("_destroy", []);
for (var i = 0; i < this.children.length; i++)
{
this.children[i]._destroy();
}
},
isIndented: function()
{
return false && this.parent != null;
},
render: function(attach_point)
{
this.domNode = document.createElement("div");
this.domNode.setAttribute("id", this.id + "-domNode");
this.domNode.widget = this;
attach_point.appendChild(this.domNode);
this.domNode.setAttribute("style", "border: 0px solid blue;");
this.domNode.style.position = "relative";
this.domNode.style.top = "0px";
this.domNode.style.left = "0px";
this.domNode.style.width = "100%";
if (this.isIndented())
this.domNode.style.marginLeft = "10px";
return this.domNode;
},
_updateDisplay: function()
{
for (var i = 0; i < this.children.length; i++)
{
this.children[i]._updateDisplay();
}
},
showAlert: function()
{
for (var i = 0; i < this.children.length; i++)
{
this.children[i].showAlert();
}
},
hideAlert: function()
{
for (var i = 0; i < this.children.length; i++)
{
this.children[i].hideAlert();
}
}
});
dojo.declare("alfresco.xforms.Repeat",
alfresco.xforms.Group,
{
initializer: function(xform, node)
{
this.inherited("initializer", [ xform, node ]);
},
_selectedIndex: -1,
insertChildAt: function(child, position)
{
var result = this.inherited("insertChildAt", [ child, position ]);
child.repeat = this;
dojo.event.connect(result, "onclick", function(event)
{
child.repeat.setFocusedChild(child);
});
var controls = document.createElement("div");
result.appendChild(controls);
controls.style.position = "absolute";
controls.style.right = "5px";
controls.style.bottom = "0px";
var images = [
{ src: "plus", action: this._insertRepeatItemAfter_handler },
{ src: "arrow_up", action: this._moveRepeatItemUp_handler },
{ src: "arrow_down", action: this._moveRepeatItemDown_handler },
{ src: "minus", action: this._removeRepeatItem_handler }
];
for (var i = 0; i < images.length; i++)
{
var img = document.createElement("img");
img.setAttribute("src", (WEBAPP_CONTEXT + "/images/icons/" +
images[i].src + ".gif"));
img.style.width = "16px";
img.style.height = "16px";
img.style.marginRight = "4px";
img.repeatItem = child;
img.repeat = this;
controls.appendChild(img);
dojo.event.connect(img, "onclick", this, images[i].action);
}
return result;
},
getSelectedIndex: function()
{
this._selectedIndex = Math.min(this.children.length - 1, this._selectedIndex);
if (this.children.length == 0)
this._selectedIndex = -1;
return this._selectedIndex;
},
_updateDisplay: function()
{
this.inherited("_updateDisplay", []);
for (var i = 0; i < this.children.length; i++)
{
this.children[i].domContainer.style.backgroundColor =
i % 2 ? "#f0f0ee" : "#ffffff";
}
},
_insertRepeatItemAfter_handler: function(event)
{
dojo.event.browser.stopEvent(event);
this.setFocusedChild(event.target.repeatItem);
if (!this.insertRepeatItemAfterTrigger)
this.insertRepeatItemAfterTrigger =
_findElementById(this.node.parentNode, this.id + "-insert_after");
this.xform.fireAction(this.insertRepeatItemAfterTrigger.getAttribute("id"));
},
_insertRepeatItemBefore_handler: function(event)
{
dojo.event.browser.stopEvent(event);
this.setFocusedChild(event.target.repeatItem);
if (!this.insertRepeatItemBeforeTrigger)
this.insertRepeatItemBeforeTrigger =
_findElementById(this.node.parentNode, this.id + "-insert_before");
this.xform.fireAction(this.insertRepeatItemBeforeTrigger.getAttribute("id"));
},
_removeRepeatItem_handler: function(event)
{
dojo.event.browser.stopEvent(event);
this.setFocusedChild(event.target.repeatItem);
if (!this.removeRepeatItemTrigger)
this.removeRepeatItemTrigger = _findElementById(this.node.parentNode,
this.id + "-delete");
this.xform.fireAction(this.removeRepeatItemTrigger.getAttribute("id"));
},
_moveRepeatItemUp_handler: function(event)
{
dojo.event.browser.stopEvent(event);
var r = event.target.repeat;
var index = r.getChildIndex(event.target.repeatItem);
if (index == 0 || r.children.length == 1)
return;
event.target.repeat.swapChildren(index, index - 1);
},
_moveRepeatItemDown_handler: function(event)
{
dojo.event.browser.stopEvent(event);
var r = event.target.repeat;
var index = r.getChildIndex(event.target.repeatItem);
if (index == r.children.length - 1 || r.children.length == 1)
return;
event.target.repeat.swapChildren(index, index + 1);
},
swapChildren: function(fromIndex, toIndex)
{
dojo.debug(this.id + ".swapChildren(" + fromIndex +
", " + toIndex + ")");
var fromChild = this.getChildAt(fromIndex);
var toChild = this.getChildAt(toIndex);
// var toChildCoords = dojo.style.getAbsolutePosition(toChild.domContainer);
// toChildCoords = [ toChildCoords.x, toChildCoords.y ];
// alert("to coords [ " + toChildCoords[0] + ", " + toChildCoords[0] + "]");
// var fromChildCoords = dojo.style.getAbsolutePosition(fromChild.domContainer);
// fromChildCoords = [ fromChildCoords.x, fromChildCoords.y ];
// alert("from coords [ " + fromChildCoords[0] + ", " + fromChildCoords[0] + "]");
// dojo.lfx.html.slideTo(fromChild.domContainer, 5000, toChildCoords);
// dojo.lfx.html.slideTo(toChild.domContainer, 5000, fromChildCoords);
var swapNode = document.createElement("div");
// dojo.dom.removeNode(toChild.domContainer);
// dojo.dom.removeNode(fromChild.domContainer);
this.domNode.replaceChild(swapNode, fromChild.domContainer);
this.domNode.replaceChild(fromChild.domContainer, toChild.domContainer);
this.domNode.replaceChild(toChild.domContainer, swapNode);
this.children[fromIndex] = toChild;
this.children[toIndex] = fromChild;
this._selectedIndex = toIndex;
this._updateDisplay();
},
setFocusedChild: function(child)
{
if (!child)
this.xform.setRepeatIndex(this.id, 0);
else
{
var index = this.getChildIndex(child);
if (index < 0)
throw new Error("unable to find child " + child.id + " in " + this.id);
// chiba thinks indexes are initialized to 1 so just
// highlight the thing
if (this.getSelectedIndex() == -1 && index == 0)
this.handleIndexChanged(0);
else
// xforms repeat indexes are 1-based
this.xform.setRepeatIndex(this.id, index + 1);
}
},
isIndented: function()
{
return false;
},
render: function(attach_point)
{
this.domNode = this.inherited("render", [ attach_point ]);
this.domNode.style.borderColor = "black";
this.domNode.style.borderWidth = "1px";
var d = document.createElement("div");
d.repeat = this;
this.domNode.appendChild(d);
d.style.position = "relative";
d.style.top = "0px";
d.style.left = "0px";
d.style.height = "20px";
d.style.lineHeight = "20px";
d.style.backgroundColor = "#cddbe8";
d.style.fontWeight = "bold";
d.style.width = "100%";
dojo.event.connect(d, "onclick", function(event)
{
if (event.target == event.currentTarget)
event.currentTarget.repeat.setFocusedChild(null);
});
//used only for positioning the label accurately
var requiredImage = document.createElement("img");
requiredImage.setAttribute("src", WEBAPP_CONTEXT + "/images/icons/required_field.gif");
requiredImage.style.marginLeft = "5px";
requiredImage.style.marginRight = "5px";
d.appendChild(requiredImage);
// requiredImage.style.position = "relative";
// requiredImage.style.top = "0px";
// requiredImage.style.left = "0px";
requiredImage.style.visibility = "hidden";
var labelElement = document.createTextNode(this.parent.getLabel());//document.createElement("span");
d.appendChild(labelElement);
var addElement = document.createElement("img");
d.appendChild(addElement);
addElement.setAttribute("src", WEBAPP_CONTEXT + "/images/icons/plus.gif");
addElement.style.width = "16px";
addElement.style.height = "16px";
addElement.style.position = "absolute";
addElement.style.top = "0px";
addElement.style.right = 5 + (16 * 4) + "px";
dojo.event.connect(addElement, "onclick", this, this._insertRepeatItemBefore_handler);
return this.domNode;
},
handleIndexChanged: function(index)
{
dojo.debug(this.id + ".handleIndexChanged(" + index + ")");
this._selectedIndex = index;
this._updateDisplay();
},
handlePrototypeCloned: function(prototypeId)
{
dojo.debug(this.id + ".handlePrototypeCloned("+ prototypeId +")");
var chibaData = _getElementsByTagNameNS(this.node, CHIBA_NS, CHIBA_NS_PREFIX, "data");
chibaData = chibaData[chibaData.length - 1];
dojo.debug("chiba:data == " + dojo.dom.innerXML(chibaData));
var prototypeToClone = dojo.dom.firstElement(chibaData);
if (prototypeToClone.getAttribute("id") != prototypeId)
throw new Error("unable to locate " + prototypeId +
" in " + this.id);
return prototypeToClone.cloneNode(true);
},
handleItemInserted: function(clonedPrototype, position)
{
dojo.debug(this.id + ".handleItemInserted(" + clonedPrototype.nodeName +
", " + position + ")");
var w = this.xform.createWidget(clonedPrototype);
this.insertChildAt(w, position);
this.xform.loadWidgets(w.node, w);
},
handleItemDeleted: function(position)
{
dojo.debug(this.id + ".handleItemDeleted(" + position + ")");
this.removeChildAt(position);
}
});
dojo.declare("alfresco.xforms.Trigger",
alfresco.xforms.Widget,
{
initializer: function(xform, node)
{
this.inherited("initializer", [ xform, node ]);
},
render: function(attach_point)
{
var nodeRef = document.createElement("div");
attach_point.appendChild(nodeRef);
this.widget = dojo.widget.createWidget("Button",
{
widgetId: this.id + "-widget",
caption: this.getLabel() + " " + this.id
},
nodeRef);
dojo.event.connect(this.widget, "onClick", this, this._clickHandler);
this.domContainer.style.display = "none";
},
_clickHandler: function(event)
{
this.xform.fireAction(this.id);
}
});
dojo.declare("alfresco.xforms.Submit",
alfresco.xforms.Trigger,
{
initializer: function(xform, node)
{
this.inherited("initializer", [ xform, node ]);
var submit_buttons = _xforms_getSubmitButtons();
for (var i = 0; i < submit_buttons.length; i++)
{
dojo.debug("adding submit handler for " + submit_buttons[i].getAttribute('id'));
submit_buttons[i].xform = this.xform;
dojo.event.browser.addListener(submit_buttons[i], "onclick", function(event)
{
var xform = event.target.xform;
if (!xform.submitWidget.done)
{
dojo.debug("triggering submit from handler " + event.target.id);
dojo.event.browser.stopEvent(event);
tinyMCE.triggerSave(true, false);
_hide_errors();
xform.submitWidget.currentButton = event.target;
xform.submitWidget.widget.buttonClick();
return false;
}
else
{
dojo.debug("done - doing base click on " + xform.submitWidget.currentButton.id);
xform.submitWidget.currentButton = null;
return true;
}
});
}
},
render: function(attach_point)
{
this.inherited("render", [ attach_point ]);
this.xform.submitWidget = this;
},
_clickHandler: function(event)
{
this.done = false;
_hide_errors();
this.xform.fireAction(this.id);
}
});
dojo.declare("alfresco.xforms.XFormsEvent",
null,
{
initializer: function(node)
{
this.type = node.nodeName;
this.targetId = node.getAttribute("targetId");
this.targetName = node.getAttribute("targetName");
this.properties = {};
for (var i = 0; i < node.childNodes.length; i++)
{
if (node.childNodes[i].nodeType == dojo.dom.ELEMENT_NODE)
this.properties[node.childNodes[i].getAttribute("name")] =
node.childNodes[i].getAttribute("value");
}
},
getTarget: function()
{
var targetDomNode = document.getElementById(this.targetId + "-content");
if (!targetDomNode)
throw new Error("unable to find node " + this.targetId + "-content");
return targetDomNode.widget;
}
});
dojo.declare("alfresco.xforms.XForm",
null,
{
initializer: function()
{
send_ajax_request(create_ajax_request(this,
"getXForm",
{},
function(type, data, evt)
{
this.xform._loadHandler(data);
}));
},
_loadHandler: function(xformDocument)
{
this.xformDocument = xformDocument;
this.node = xformDocument.documentElement;
this._bindings = this._loadBindings(this.getModel());
var bindings = this.getBindings();
for (var i in bindings)
{
dojo.debug("bindings[" + i + "]=" + bindings[i].id +
", parent = " + (bindings[i].parent
? bindings[i].parent.id
: 'null'));
}
var alfUI = document.getElementById("alf-ui");
alfUI.style.width = "100%";
this.rootWidget = new alfresco.xforms.Group(this, alfUI);
this.rootWidget.render(alfUI);
this.loadWidgets(this.getBody(), this.rootWidget);
this.rootWidget._updateDisplay();
},
createWidget: function(node)
{
dojo.debug("creating node for " + node.nodeName.toLowerCase());
switch (node.nodeName.toLowerCase())
{
case "xforms:group":
return new alfresco.xforms.Group(this, node);
case "xforms:repeat":
return new alfresco.xforms.Repeat(this, node);
case "xforms:textarea":
return new alfresco.xforms.TextArea(this, node);
case "xforms:input":
var type = this.getType(node);
switch (type)
{
case "date":
return new alfresco.xforms.DatePicker(this, node);
case "byte":
case "double":
case "float":
case "int":
case "integer":
case "long":
case "negativeInteger":
case "nonNegativeInteger":
case "nonPositiveInteger":
case "short":
case "unsignedByte":
case "unsignedInt":
case "unsignedLong":
case "unsignedShort":
case "positiveInteger":
case "string":
default:
return new alfresco.xforms.TextField(this, node);
}
case "xforms:select":
return new alfresco.xforms.Select(this, node);
case "xforms:select1":
return (this.getType(node) == "boolean"
? new alfresco.xforms.Checkbox(this, node)
: new alfresco.xforms.Select1(this, node));
case "xforms:submit":
return new alfresco.xforms.Submit(this, node);
case "xforms:trigger":
return new alfresco.xforms.Trigger(this, node);
case "chiba:data":
case "xforms:label":
case "xforms:alert":
return null;
default:
throw new Error("unknown type " + node.nodeName);
}
},
loadWidgets: function(modelNode, parentWidget)
{
for (var i = 0; i < modelNode.childNodes.length; i++)
{
if (modelNode.childNodes[i].nodeType == dojo.dom.ELEMENT_NODE)
{
dojo.debug("loading " + modelNode.childNodes[i] +
" nodeName " + modelNode.childNodes[i].nodeName +
" into " + parentWidget.id);
var w = this.createWidget(modelNode.childNodes[i]);
if (w != null)
{
dojo.debug("created " + w.id + " for " + modelNode.childNodes[i].nodeName);
parentWidget.addChild(w);
if (w instanceof alfresco.xforms.Group)
this.loadWidgets(modelNode.childNodes[i], w);
}
}
}
},
getModel: function()
{
return _getElementsByTagNameNS(this.node,
XFORMS_NS,
XFORMS_NS_PREFIX,
"model")[0];
},
getInstance: function()
{
var model = this.getModel();
return _getElementsByTagNameNS(model,
XFORMS_NS,
XFORMS_NS_PREFIX,
"instance")[0];
},
getBody: function()
{
var b = _getElementsByTagNameNS(this.node,
XHTML_NS,
XHTML_NS_PREFIX,
"body");
return b[b.length - 1];
},
getType: function(node)
{
return this.getBinding(node).type;
},
getBinding: function(node)
{
return this._bindings[node.getAttribute("xforms:bind")];
},
getBindings: function()
{
return this._bindings;
},
_loadBindings: function(bind, parent, result)
{
result = result || [];
dojo.debug("loading bindings for " + bind.nodeName);
for (var i = 0; i < bind.childNodes.length; i++)
{
if (bind.childNodes[i].nodeName.toLowerCase() == "xforms:bind")
{
var id = bind.childNodes[i].getAttribute("id");
dojo.debug("loading binding " + id);
result[id] = {
id: bind.childNodes[i].getAttribute("id"),
required: bind.childNodes[i].getAttribute("xforms:required"),
nodeset: bind.childNodes[i].getAttribute("xforms:nodeset"),
type: bind.childNodes[i].getAttribute("xforms:type"),
constraint: bind.childNodes[i].getAttribute("xforms:constraint"),
parent: parent
};
this._loadBindings(bind.childNodes[i], result[id], result);
}
}
return result;
},
setRepeatIndex: function(id, index)
{
dojo.debug("setting repeat index " + index + " on " + id);
var req = create_ajax_request(this,
"setRepeatIndex",
{ id: id, index: index },
function(type, data, evt)
{
this.xform._handleEventLog(data.documentElement);
});
send_ajax_request(req);
},
fireAction: function(id)
{
var req = create_ajax_request(this,
"fireAction",
{ id: id },
function(type, data, evt)
{
dojo.debug("fireAction." + type);
this.xform._handleEventLog(data.documentElement);
});
send_ajax_request(req);
},
setXFormsValue: function(id, value)
{
value = value == null ? "" : value;
dojo.debug("setting value " + id + " = " + value);
var req = create_ajax_request(this,
"setXFormsValue",
{ id: id, value: value },
function(type, data, evt)
{
this.xform._handleEventLog(data.documentElement);
});
send_ajax_request(req);
},
_handleEventLog: function(events)
{
var prototypeClones = [];
for (var i = 0; i < events.childNodes.length; i++)
{
if (events.childNodes[i].nodeType == dojo.dom.ELEMENT_NODE)
{
var xfe = new alfresco.xforms.XFormsEvent(events.childNodes[i]);
dojo.debug("parsing " + xfe.type +
"(" + xfe.targetId + ", " + xfe.targetName + ")");
switch (xfe.type)
{
case "chiba-index-changed":
{
var index = Number(xfe.properties["index"]) - 1;
xfe.getTarget().handleIndexChanged(index);
break;
}
case "chiba-state-changed":
{
var valid = xfe.properties["valid"] == "true";
xfe.getTarget().setValid(valid);
xfe.getTarget().setModified(true);
break;
}
case "chiba-prototype-cloned":
{
var prototypeId = xfe.properties["prototypeId"];
var clone = xfe.getTarget().handlePrototypeCloned(prototypeId);
prototypeClones.push(clone);
break;
}
case "chiba-id-generated":
{
var originalId = xfe.properties["originalId"];
dojo.debug("handleIdGenerated(" + xfe.targetId + ", " + originalId + ")");
var clone = prototypeClones[prototypeClones.length - 1];
var node = _findElementById(clone, originalId);
if (node)
{
dojo.debug("applying id " + xfe.targetId +
" to " + node.nodeName + "(" + originalId + ")");
node.setAttribute("id", xfe.targetId);
}
else
throw new Error("unable to find " + originalId +
" in clone " + dojo.dom.innerXML(clone));
break;
}
case "chiba-item-inserted":
{
var position = Number(xfe.properties["position"]) - 1;
var clone = prototypeClones.pop();
xfe.getTarget().handleItemInserted(clone, position);
break;
}
case "chiba-item-deleted":
{
var position = Number(xfe.properties["position"]) - 1;
xfe.getTarget().handleItemDeleted(position);
break;
}
case "chiba-replace-all":
if (this.submitWidget)
{
this.submitWidget.done = true;
this.submitWidget.currentButton.click();
}
break;
case "xforms-valid":
xfe.getTarget().setValid(true);
xfe.getTarget().setModified(true);
break;
case "xforms-invalid":
xfe.getTarget().setValid(false);
xfe.getTarget().setModified(true);
break;
case "xforms-required":
xfe.getTarget().setRequired(true);
break;
case "xforms-optional":
xfe.getTarget().setRequired(false);
break;
case "xforms-submit-error":
var invalid = this.rootWidget.getWidgetsInvalidForSubmit();
_show_error(document.createTextNode("Please provide values for all required fields."));
var error_list = document.createElement("ul");
for (var j = 0; j < invalid.length; j++)
{
var error_item = document.createElement("li");
error_item.appendChild(document.createTextNode(invalid[j].getAlert()));
error_list.appendChild(error_item);
invalid[j].showAlert();
}
_show_error(error_list);
break;
default:
{
dojo.debug("unhandled event " + events.childNodes[i].nodeName);
}
}
}
}
}
});
function _findElementById(node, id)
{
dojo.debug("looking for " + id +
" in " + node.nodeName +
"(" + node.getAttribute("id") + ")");
if (node.getAttribute("id") == id)
return node;
for (var i = 0; i < node.childNodes.length; i++)
{
if (node.childNodes[i].nodeType == dojo.dom.ELEMENT_NODE)
{
var n = _findElementById(node.childNodes[i], id);
if (n)
return n;
}
}
return null;
}
function create_ajax_request(xform, serverMethod, methodArgs, load, error)
{
var result = new dojo.io.Request(WEBAPP_CONTEXT + "/ajax/invoke/XFormsBean." + serverMethod, "text/xml");
result.xform = xform;
result.content = methodArgs;
result.load = load;
dojo.event.connect(result, "load", function(type, data, evt)
{
// _hide_errors();
ajax_request_load_handler(this);
});
result.error = error || function(type, e)
{
dojo.debug("error [" + type + "] " + e.message);
_show_error(document.createTextNode(e.message));
ajax_request_load_handler(this);
};
return result;
}
function _hide_errors()
{
var errorDiv = document.getElementById("alf-xforms-error");
if (errorDiv)
{
dojo.dom.removeChildren(errorDiv);
errorDiv.style.display = "none";
}
}
function _show_error(msg)
{
var errorDiv = document.getElementById("alf-xforms-error");
if (!errorDiv)
{
errorDiv = document.createElement("div");
errorDiv.setAttribute("id", "alf-xforms-error");
errorDiv.setAttribute(document.all ? "className" : "class", "infoText statusErrorText");
errorDiv.style.padding = "2px";
errorDiv.style.borderColor = "#003366";
errorDiv.style.borderWidth = "1px";
errorDiv.style.borderStyle = "solid";
var alfUI = document.getElementById("alf-ui");
dojo.dom.prependChild(errorDiv, alfUI);
}
if (errorDiv.style.display == "block")
errorDiv.appendChild(document.createElement("br"));
else
errorDiv.style.display = "block";
errorDiv.appendChild(msg);
}
function send_ajax_request(req)
{
ajax_request_send_handler(req);
dojo.io.queueBind(req);
}
function _get_ajax_loader_element()
{
var result = document.getElementById("alf-ajax-loader");
if (result)
return result;
result = document.createElement("div");
result.setAttribute("id", "alf-ajax-loader");
result.style.position = "absolute";
result.style.right = "0px";
result.style.top = "0px";
result.style.color = "white";
result.style.backgroundColor = "red";
dojo.style.hide(result);
document.body.appendChild(result);
return result;
}
var _ajax_requests = [];
function ajax_request_send_handler(req)
{
_ajax_requests.push(req);
ajax_loader_update_display();
}
function ajax_loader_update_display()
{
var ajaxLoader = _get_ajax_loader_element();
ajaxLoader.innerHTML = (_ajax_requests.length == 0
? "Idle"
: "Loading" + (_ajax_requests.length > 1
? " (" + _ajax_requests.length + ")"
: "..."));
dojo.debug(ajaxLoader.innerHTML);
if (/* djConfig.isDebug && */ _ajax_requests.length != 0)
{
dojo.style.show(ajaxLoader);
}
else
{
dojo.style.hide(ajaxLoader);
}
}
function ajax_request_load_handler(req)
{
var ajaxLoader = _get_ajax_loader_element();
var index = -1;
for (var i = 0; i < _ajax_requests.length; i++)
{
if (_ajax_requests[i] == req)
{
index = i;
break;
}
}
if (index == -1)
_ajax_requests.splice(index, 1);
else
throw new Error("unable to find " + req.url);
ajax_loader_update_display();
}
function _getElementsByTagNameNS(parentNode, ns, nsPrefix, tagName)
{
return (parentNode.getElementsByTagNameNS
? parentNode.getElementsByTagNameNS(ns, tagName)
: parentNode.getElementsByTagName(nsPrefix + ":" + tagName));
}
function _evaluateXPath(xpath, contextNode, result_type)
{
var xmlDocument = contextNode.ownerDocument;
dojo.debug("evaluating xpath " + xpath + " on node " + contextNode.nodeName +
" in document " + xmlDocument);
var result = null;
if (xmlDocument.evaluate)
{
var nsResolver = (xmlDocument.createNSResolver
? xmlDocument.createNSResolver(xmlDocument.documentElement) :
null);
result = xmlDocument.evaluate(xpath,
contextNode,
nsResolver,
result_type,
null);
if (result)
{
switch (result_type)
{
case XPathResult.FIRST_ORDERED_NODE_TYPE:
result = result.singleNodeValue;
break;
case XPathResult.BOOLEAN_TYPE:
result = result.booleanValue;
break;
case XPathResult.STRING_TYPE:
result = result.stringValue;
break;
}
}
}
else
{
xmlDocument.setProperty("SelectionLanguage", "XPath");
var namespaces = [];
for (var i = 0; i < xmlDocument.documentElement.attributes.length; i++)
{
var attr = xmlDocument.documentElement.attributes[i];
if (attr.nodeName.match(/^xmlns:/))
namespaces.push(attr.nodeName + "=\'" + attr.nodeValue + "\'");
}
dojo.debug("using namespaces " + namespaces.join(","));
xmlDocument.setProperty("SelectionNamespaces", namespaces.join(' '));
if (result_type == XPathResult.FIRST_ORDERED_NODE_TYPE)
result = xmlDocument.selectSingleNode(xpath);
else if (result_type == XPathResult.BOOLEAN_TYPE)
result = true;
}
dojo.debug("resolved xpath " + xpath + " to " + result);
return result;
}
if (!XPathResult)
{
var XPathResult = {};
XPathResult.ANY_TYPE = 0;
XPathResult.NUMBER_TYPE = 1;
XPathResult.STRING_TYPE = 2;
XPathResult.BOOEAN_TYPE = 3;
XPathResult.FIRST_ORDERED_NODE_TYPE = 9;
}
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(o)
{
for (var i = 0; i < this.length; i++)
{
if (this[i] == o)
return i;
}
return -1;
}
}