--- a/web/data/cubicweb.edition.js Mon Jan 04 18:40:30 2016 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,579 +0,0 @@
-/**
- * Functions dedicated to edition.
- *
- * :organization: Logilab
- * :copyright: 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
- * :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
- *
- */
-
-//============= Eproperty form functions =====================================//
-/**
- * .. function:: setPropValueWidget(varname, tabindex)
- *
- * called on CWProperty key selection:
- * - get the selected value
- * - get a widget according to the key by a sync query to the server
- * - fill associated div with the returned html
- *
- * * `varname`, the name of the variable as used in the original creation form
- * * `tabindex`, the tabindex that should be set on the widget
- */
-
-function setPropValueWidget(varname, tabindex) {
- var key = firstSelected(document.getElementById('pkey-subject:' + varname));
- if (key) {
- var args = {
- fname: 'prop_widget',
- pageid: pageid,
- arg: $.map([key.value, varname, tabindex], JSON.stringify)
- };
- cw.jqNode('div:value-subject:' + varname).loadxhtml(AJAX_BASE_URL, args, 'post');
- }
-}
-
-// *** EDITION FUNCTIONS ****************************************** //
-/**
- * .. function:: reorderTabindex(start, formid)
- *
- * this function is called when an AJAX form was generated to
- * make sure tabindex remains consistent
- */
-function reorderTabindex(start, formid) {
- var form = cw.getNode(formid || 'entityForm');
- var inputTypes = ['INPUT', 'SELECT', 'TEXTAREA'];
- var tabindex = (start == null) ? 15: start;
- cw.utils.nodeWalkDepthFirst(form, function(elem) {
- var tagName = elem.tagName.toUpperCase();
- if (jQuery.inArray(tagName, inputTypes) != -1) {
- if (jQuery(elem).attr('tabindex') != null) {
- tabindex += 1;
- jQuery(elem).attr('tabindex', tabindex);
- }
- return null;
- }
- return jQuery.grep(elem.childNodes, isElementNode);
- });
-}
-
-function showMatchingSelect(selectedValue, eid) {
- if (selectedValue) {
- var divId = 'div' + selectedValue + '_' + eid;
- var divNode = jQuery('#' + divId);
- if (!divNode.length) {
- var args = {
- vid: 'unrelateddivs',
- relation: selectedValue,
- rql: rql_for_eid(eid),
- '__notemplate': 1
- };
- var d = jQuery('#unrelatedDivs_' + eid).loadxhtml(BASE_URL + 'view', args, 'post', 'append');
- d.addCallback(function() {
- _showMatchingSelect(eid, jQuery('#' + divId));
- });
- } else {
- _showMatchingSelect(eid, divNode);
- }
- } else {
- _showMatchingSelect(eid, null);
- }
-}
-
-/**
- * .. function:: _showMatchingSelect(eid, divNode)
- *
- * * `divNode`, a jQuery selection
- */
-function _showMatchingSelect(eid, divNode) {
- // hide all divs, and then show the matching one
- // (would actually be better to directly hide the displayed one)
- jQuery('#unrelatedDivs_' + eid).children().hide();
- // divNode not found means 'no relation selected' (i.e. first blank item)
- if (divNode && divNode.length) {
- divNode.show();
- }
-}
-
-/**
- * .. function:: buildPendingInsertHandle(elementId, element_name, selectNodeId, eid)
- *
- * this function builds a Handle to cancel pending insertion
- */
-function buildPendingInsertHandle(elementId, element_name, selectNodeId, eid) {
- jscall = "javascript: cancelPendingInsert('" + [elementId, element_name, selectNodeId, eid].join("', '") + "')";
- return A({
- 'class': 'handle',
- 'href': jscall,
- 'title': _("cancel this insert")
- },
- '[x]');
-}
-
-function buildEntityLine(relationName, selectedOptionNode, comboId, eid) {
- // textContent doesn't seem to work on selectedOptionNode
- var content = selectedOptionNode.firstChild.nodeValue;
- var handle = buildPendingInsertHandle(selectedOptionNode.id, 'tr', comboId, eid);
- var link = A({
- 'href': 'view?rql=' + selectedOptionNode.value,
- 'class': 'editionPending',
- 'id': 'a' + selectedOptionNode.id
- },
- content);
- var tr = TR({
- 'id': 'tr' + selectedOptionNode.id
- },
- [TH(null, relationName), TD(null, [handle, link])]);
- try {
- var separator = cw.getNode('relationSelectorRow_' + eid);
- //dump('relationSelectorRow_' + eid) XXX warn dump is not implemented in konqueror (at least)
- // XXX Warning: separator.parentNode is not (always ?) the
- // table itself, but an intermediate node (TableSectionElement)
- var tableBody = separator.parentNode;
- tableBody.insertBefore(tr, separator);
- } catch(ex) {
- log("got exception(2)!" + ex);
- }
-}
-
-function buildEntityCell(relationName, selectedOptionNode, comboId, eid) {
- var handle = buildPendingInsertHandle(selectedOptionNode.id, 'div_insert_', comboId, eid);
- var link = A({
- 'href': 'view?rql=' + selectedOptionNode.value,
- 'class': 'editionPending',
- 'id': 'a' + selectedOptionNode.id
- },
- content);
- var div = DIV({
- 'id': 'div_insert_' + selectedOptionNode.id
- },
- [handle, link]);
- try {
- var td = jQuery('#cell' + relationName + '_' + eid);
- td.appendChild(div);
- } catch(ex) {
- alert("got exception(3)!" + ex);
- }
-}
-
-function addPendingInsert(optionNode, eid, cell, relname) {
- var value = jQuery(optionNode).attr('value');
- if (!value) {
- // occurs when the first element in the box is selected (which is not
- // an entity but the combobox title)
- return;
- }
- // 2nd special case
- if (value.indexOf('http') == 0) {
- document.location = value;
- return;
- }
- // add hidden parameter
- var entityForm = jQuery('#entityForm');
- var oid = optionNode.id.substring(2); // option id is prefixed by "id"
- loadRemote(AJAX_BASE_URL, ajaxFuncArgs('add_pending_inserts', null,
- [oid.split(':')]), 'POST', true);
- var selectNode = optionNode.parentNode;
- // remove option node
- selectNode.removeChild(optionNode);
- // add line in table
- if (cell) {
- // new relation as a cell in multiple edit
- // var relation_name = relationSelected.getAttribute('value');
- // relation_name = relation_name.slice(0, relation_name.lastIndexOf('_'));
- buildEntityCell(relname, optionNode, selectNode.id, eid);
- }
- else {
- var relationSelector = cw.getNode('relationSelector_' + eid);
- var relationSelected = relationSelector.options[relationSelector.selectedIndex];
- // new relation as a line in simple edit
- buildEntityLine(relationSelected.text, optionNode, selectNode.id, eid);
- }
-}
-
-function cancelPendingInsert(elementId, element_name, comboId, eid) {
- // remove matching insert element
- var entityView = cw.jqNode('a' + elementId).text();
- cw.jqNode(element_name + elementId).remove();
- if (comboId) {
- // re-insert option in combobox if it was taken from there
- var selectNode = cw.getNode(comboId);
- // XXX what on object relation
- if (selectNode) {
- var options = selectNode.options;
- var node_id = elementId.substring(0, elementId.indexOf(':'));
- options[options.length] = OPTION({
- 'id': elementId,
- 'value': node_id
- },
- entityView);
- }
- }
- elementId = elementId.substring(2, elementId.length);
- loadRemote(AJAX_BASE_URL, ajaxFuncArgs('remove_pending_insert', null,
- elementId.split(':')), 'GET', true);
-}
-
-/**
- * .. function:: buildPendingDeleteHandle(elementId, eid)
- *
- * this function builds a Handle to cancel pending insertion
- */
-function buildPendingDeleteHandle(elementId, eid) {
- var jscall = "javascript: addPendingDelete('" + elementId + ', ' + eid + "');";
- return A({
- 'href': jscall,
- 'class': 'pendingDeleteHandle',
- 'title': _("delete this relation")
- },
- '[x]');
-}
-
-/**
- * .. function:: addPendingDelete(nodeId, eid)
- *
- * * `nodeId`, eid_from:r_type:eid_to
- */
-function addPendingDelete(nodeId, eid) {
- var d = loadRemote(AJAX_BASE_URL, ajaxFuncArgs('add_pending_delete', null, nodeId.split(':')));
- d.addCallback(function() {
- // and strike entity view
- cw.jqNode('span' + nodeId).addClass('pendingDelete');
- // replace handle text
- cw.jqNode('handle' + nodeId).text('+');
- });
-}
-
-/**
- * .. function:: cancelPendingDelete(nodeId, eid)
- *
- * * `nodeId`, eid_from:r_type:eid_to
- */
-function cancelPendingDelete(nodeId, eid) {
- var d = loadRemote(AJAX_BASE_URL, ajaxFuncArgs('remove_pending_delete', null, nodeId.split(':')));
- d.addCallback(function() {
- // reset link's CSS class
- cw.jqNode('span' + nodeId).removeClass('pendingDelete');
- // replace handle text
- cw.jqNode('handle' + nodeId).text('x');
- });
-}
-
-/**
- * .. function:: togglePendingDelete(nodeId, eid)
- *
- * * `nodeId`, eid_from:r_type:eid_to
- */
-function togglePendingDelete(nodeId, eid) {
- // node found means we should cancel deletion
- if (jQuery(cw.getNode('span' + nodeId)).hasClass('pendingDelete')) {
- cancelPendingDelete(nodeId, eid);
- } else {
- addPendingDelete(nodeId, eid);
- }
-}
-
-function selectForAssociation(tripletIdsString, originalEid) {
- var tripletlist = $.map(tripletIdsString.split('-'),
- function(x) { return [x.split(':')] ;});
- var d = loadRemote(AJAX_BASE_URL, ajaxFuncArgs('add_pending_inserts', null, tripletlist));
- d.addCallback(function() {
- var args = {
- vid: 'edition',
- __mode: 'normal',
- rql: rql_for_eid(originalEid)
- };
- document.location = 'view?' + asURL(args);
- });
-
-}
-
-function updateInlinedEntitiesCounters(rtype, role) {
- jQuery('div.inline-' + rtype + '-' + role + '-slot span.icounter').each(function(i) {
- this.innerHTML = i + 1;
- });
-}
-
-/**
- * .. function:: addInlineCreationForm(peid, petype, ttype, rtype, role, i18nctx, insertBefore)
- *
- * makes an AJAX request to get an inline-creation view's content
- * * `peid`, the parent entity eid
- *
- * * `petype`, the parent entity type
- *
- * * `ttype`, the target (inlined) entity type
- *
- * * `rtype`, the relation type between both entities
- */
-function addInlineCreationForm(peid, petype, ttype, rtype, role, i18nctx, insertBefore) {
- insertBefore = insertBefore || cw.getNode('add' + rtype + ':' + peid + 'link').parentNode;
- var args = ajaxFuncArgs('inline_creation_form', null, peid, petype, ttype, rtype, role, i18nctx);
- var d = loadRemote(AJAX_BASE_URL, args);
- d.addCallback(function(response) {
- var dom = getDomFromResponse(response);
- loadAjaxHtmlHead(dom);
- var form = jQuery(dom);
- form.css('display', 'none');
- form.insertBefore(insertBefore).slideDown('fast');
- updateInlinedEntitiesCounters(rtype, role);
- reorderTabindex(null, $(insertBefore).closest('form')[0]);
- jQuery(cw).trigger('inlinedform-added', form);
- // if the inlined form contains a file input, we must force
- // the form enctype to multipart/form-data
- if (form.find('input:file').length) {
- // NOTE: IE doesn't support dynamic enctype modification, we have
- // to set encoding too.
- form.closest('form').attr('enctype', 'multipart/form-data').attr('encoding', 'multipart/form-data');
- }
- _postAjaxLoad(dom);
- });
- d.addErrback(function(xxx) {
- cw.log('xxx =', xxx);
- });
-}
-
-/**
- * .. function:: removeInlineForm(peid, rtype, role, eid, showaddnewlink)
- *
- * removes the part of the form used to edit an inlined entity
- */
-function removeInlineForm(peid, rtype, role, eid, showaddnewlink) {
- cw.jqNode(['div', peid, rtype, eid].join('-')).slideUp('fast', function() {
- $(this).remove();
- updateInlinedEntitiesCounters(rtype, role);
- });
- if (showaddnewlink) {
- toggleVisibility(showaddnewlink);
- }
-}
-
-/**
- * .. function:: removeInlinedEntity(peid, rtype, eid)
- *
- * alternatively adds or removes the hidden input that make the
- * edition of the relation `rtype` possible between `peid` and `eid`
- * * `peid`, the parent entity eid
- *
- * * `rtype`, the relation type between both entities
- *
- * * `eid`, the inlined entity eid
- */
-function removeInlinedEntity(peid, rtype, eid) {
- // XXX work around the eid_param thing (eid + ':' + eid) for #471746
- var nodeid = ['rel', peid, rtype, eid + ':' + eid].join('-');
- var node = cw.jqNode(nodeid);
- if (!node.attr('cubicweb:type')) {
- node.attr('cubicweb:type', node.val());
- node.val('');
- var divid = ['div', peid, rtype, eid].join('-');
- cw.jqNode(divid).fadeTo('fast', 0.5);
- var noticeid = ['notice', peid, rtype, eid].join('-');
- cw.jqNode(noticeid).fadeIn('fast');
- }
-}
-
-function restoreInlinedEntity(peid, rtype, eid) {
- // XXX work around the eid_param thing (eid + ':' + eid) for #471746
- var nodeid = ['rel', peid, rtype, eid + ':' + eid].join('-');
- var node = cw.jqNode(nodeid);
- if (node.attr('cubicweb:type')) {
- node.val(node.attr('cubicweb:type'));
- node.attr('cubicweb:type', '');
- cw.jqNode(['fs', peid, rtype, eid].join('-')).append(node);
- var divid = ['div', peid, rtype, eid].join('-');
- cw.jqNode(divid).fadeTo('fast', 1);
- var noticeid = ['notice', peid, rtype, eid].join('-');
- cw.jqNode(noticeid).hide();
- }
-}
-
-function _clearPreviousErrors(formid) {
- // on some case (eg max request size exceeded, we don't know the formid
- if (formid) {
- jQuery('#' + formid + 'ErrorMessage').remove();
- jQuery('#' + formid + ' span.errorMsg').remove();
- jQuery('#' + formid + ' .error').removeClass('error');
- } else {
- jQuery('span.errorMsg').remove();
- jQuery('.error').removeClass('error');
- }
-}
-
-function _displayValidationerrors(formid, eid, errors) {
- var globalerrors = [];
- var firsterrfield = null;
- for (fieldname in errors) {
- var errmsg = errors[fieldname];
- if (!fieldname) {
- globalerrors.push(errmsg);
- } else {
- var fieldid = fieldname + ':' + eid;
- var suffixes = ['', '-subject', '-object'];
- var found = false;
- // XXX remove suffixes at some point
- for (var i = 0, length = suffixes.length; i < length; i++) {
- var field = cw.jqNode(fieldname + suffixes[i] + ':' + eid);
- if (field && jQuery(field).attr('type') != 'hidden') {
- if (!firsterrfield) {
- firsterrfield = 'err-' + fieldid;
- }
- jQuery(field).addClass('error');
- var span = SPAN({
- 'id': 'err-' + fieldid,
- 'class': "errorMsg"
- },
- errmsg);
- field.before(span);
- found = true;
- break;
- }
- }
- if (!found) {
- firsterrfield = formid;
- globalerrors.push(_(fieldname) + ' : ' + errmsg);
- }
- }
- }
- if (globalerrors.length) {
- if (globalerrors.length == 1) {
- var innernode = SPAN(null, globalerrors[0]);
- } else {
- var linodes =[];
- for(var i=0; i<globalerrors.length; i++){
- linodes.push(LI(null, globalerrors[i]));
- }
- var innernode = UL(null, linodes);
- }
- // insert DIV and innernode before the form
- var div = DIV({
- 'class': "errorMessage",
- 'id': formid + 'ErrorMessage'
- });
- div.appendChild(innernode);
- jQuery('#' + formid).before(div);
- }
- return firsterrfield || formid;
-}
-
-function handleFormValidationResponse(formid, onsuccess, onfailure, result, cbargs) {
- // Success
- if (result[0]) {
- if (onsuccess) {
- onsuccess(result, formid, cbargs);
- } else {
- document.location.href = result[1];
- }
- return true;
- }
- if (onfailure && ! onfailure(result, formid, cbargs)) {
- return false;
- }
- unfreezeFormButtons(formid);
- // Failures
- _clearPreviousErrors(formid);
- var descr = result[1];
- var errmsg;
- // Unknown structure
- if ( !cw.utils.isArrayLike(descr) || descr.length != 2 ) {
- errmsg = descr;
- } else {
- _displayValidationerrors(formid, descr[0], descr[1]);
- errmsg = _("please correct errors below");
- }
- updateMessage(errmsg);
- // ensure the browser does not scroll down
- document.location.hash = '#header';
- return false;
-}
-
-/**
- * .. function:: unfreezeFormButtons(formid)
- *
- * unfreeze form buttons when the validation process is over
- */
-function unfreezeFormButtons(formid) {
- jQuery('#progress').hide();
- // on some case (eg max request size exceeded, we don't know the formid
- if (formid) {
- jQuery('#' + formid + ' .validateButton').removeAttr('disabled');
- } else {
- jQuery('.validateButton').removeAttr('disabled');
- }
- return true;
-}
-
-/**
- * .. function:: freezeFormButtons(formid)
- *
- * disable form buttons while the validation is being done
- */
-function freezeFormButtons(formid) {
- jQuery('#progress').show();
- jQuery('#' + formid + ' .validateButton').attr('disabled', 'disabled');
- return true;
-}
-
-/**
- * .. function:: postForm(bname, bvalue, formid)
- *
- * used by additional submit buttons to remember which button was clicked
- */
-function postForm(bname, bvalue, formid) {
- var form = cw.getNode(formid);
- if (bname) {
- var child = form.appendChild(INPUT({
- type: 'hidden',
- name: bname,
- value: bvalue
- }));
- }
- var onsubmit = form.onsubmit;
- if (!onsubmit || (onsubmit && onsubmit())) {
- form.submit();
- }
- if (bname) {
- jQuery(child).remove();
- }
-}
-
-/**
- * Cancel the operations done on the given form.
- *
- */
-$(function () {
- $(document).on('click', '.cwjs-edition-cancel', function (evt) {
- var $mynode = $(evt.currentTarget),
- $form = $mynode.closest('form'),
- $error = $form.find(':input[name="__errorurl"]'),
- errorurl = $error.attr('value'),
- args = ajaxFuncArgs('cancel_edition', null, errorurl);
- loadRemote(AJAX_BASE_URL, args, 'POST', true);
- history.back();
- return false;
- });
-});
-
-
-/**
- * .. function:: validateForm(formid, action, onsuccess, onfailure)
- *
- * called on traditionnal form submission : the idea is to try
- * to post the form. If the post is successful, `validateForm` redirects
- * to the appropriate URL. Otherwise, the validation errors are displayed
- * around the corresponding input fields.
- */
-function validateForm(formid, action, onsuccess, onfailure) {
- freezeFormButtons(formid);
- try {
- var zipped = cw.utils.formContents(formid);
- var args = ajaxFuncArgs('validate_form', null, action, zipped[0], zipped[1]);
- var d = loadRemote(AJAX_BASE_URL, args, 'POST');
- } catch(ex) {
- cw.log('got exception', ex);
- return false;
- }
- d.addCallback(function(result, req) {
- handleFormValidationResponse(formid, onsuccess, onfailure, result);
- });
- return false;
-}