diff -r 058bb3dc685f -r 0b59724cb3f2 web/data/cubicweb.edition.js --- 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