author | Sylvain Thénault <sylvain.thenault@logilab.fr> |
Fri, 09 Oct 2009 15:10:17 +0200 | |
branch | stable |
changeset 3625 | f03b55a18c43 |
parent 3545 | 242b07b6d820 |
child 3742 | 20f429eb5f46 |
permissions | -rw-r--r-- |
0 | 1 |
/* |
2 |
* :organization: Logilab |
|
1419 | 3 |
* :copyright: 2003-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
0 | 4 |
* :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
5 |
*/ |
|
6 |
||
7 |
CubicWeb.require('python.js'); |
|
8 |
CubicWeb.require('htmlhelpers.js'); |
|
9 |
CubicWeb.require('ajax.js'); |
|
10 |
||
11 |
||
12 |
//============= Eproperty form functions =====================================// |
|
13 |
||
14 |
/* called on Eproperty key selection: |
|
15 |
* - get the selected value |
|
16 |
* - get a widget according to the key by a sync query to the server |
|
17 |
* - fill associated div with the returned html |
|
18 |
* |
|
19 |
* @param varname the name of the variable as used in the original creation form |
|
20 |
* @param tabindex the tabindex that should be set on the widget |
|
21 |
*/ |
|
22 |
function setPropValueWidget(varname, tabindex) { |
|
1314
dc5499bff1a9
fix primary edition of eproperty (weird js pb remaining though)
sylvain.thenault@logilab.fr
parents:
1292
diff
changeset
|
23 |
var key = firstSelected(document.getElementById('pkey:'+varname)); |
0 | 24 |
if (key) { |
1419 | 25 |
var args = {fname: 'prop_widget', pageid: pageid, |
26 |
arg: map(jQuery.toJSON, [key, varname, tabindex])}; |
|
1314
dc5499bff1a9
fix primary edition of eproperty (weird js pb remaining though)
sylvain.thenault@logilab.fr
parents:
1292
diff
changeset
|
27 |
jqNode('div:value:'+varname).loadxhtml(JSON_BASE_URL, args, 'post'); |
0 | 28 |
} |
29 |
} |
|
30 |
||
31 |
||
32 |
// *** EDITION FUNCTIONS ****************************************** // |
|
33 |
||
34 |
/* |
|
35 |
* this function is called when an AJAX form was generated to |
|
36 |
* make sure tabindex remains consistent |
|
37 |
*/ |
|
38 |
function reorderTabindex(start) { |
|
39 |
var form = getNode('entityForm'); |
|
40 |
var inputTypes = ['INPUT', 'SELECT', 'TEXTAREA']; |
|
41 |
var tabindex = (start==null)?15:start; |
|
42 |
nodeWalkDepthFirst(form, function(elem) { |
|
43 |
var tagName = elem.tagName.toUpperCase(); |
|
44 |
if (inputTypes.contains(tagName)) { |
|
45 |
if (getNodeAttribute(elem, 'tabindex') != null) { |
|
46 |
tabindex += 1; |
|
47 |
elem.setAttribute('tabindex', tabindex); |
|
48 |
} |
|
49 |
return null; |
|
50 |
} |
|
51 |
return filter(isElementNode, elem.childNodes); |
|
52 |
}); |
|
53 |
} |
|
54 |
||
1419 | 55 |
|
0 | 56 |
function showMatchingSelect(selectedValue, eid) { |
57 |
if (selectedValue) { |
|
58 |
divId = 'div' + selectedValue + '_' + eid; |
|
59 |
var divNode = jQuery('#' + divId); |
|
60 |
if (!divNode.length) { |
|
61 |
var args = {vid: 'unrelateddivs', relation: selectedValue, |
|
1419 | 62 |
rql: rql_for_eid(eid), '__notemplate': 1, |
3100
b0a583156d6d
fix reledit validation error handling for relations #345477
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2859
diff
changeset
|
63 |
callback: function() {_showMatchingSelect(eid, jQuery('#' + divId));}}; |
1419 | 64 |
jQuery('#unrelatedDivs_' + eid).loadxhtml(baseuri() + 'view', args, 'post', 'append'); |
0 | 65 |
} else { |
66 |
_showMatchingSelect(eid, divNode); |
|
67 |
} |
|
1419 | 68 |
} else { |
0 | 69 |
_showMatchingSelect(eid, null); |
70 |
} |
|
71 |
} |
|
72 |
||
73 |
||
74 |
// @param divNode is a jQuery selection |
|
75 |
function _showMatchingSelect(eid, divNode) { |
|
76 |
// hide all divs, and then show the matching one |
|
77 |
// (would actually be better to directly hide the displayed one) |
|
78 |
jQuery('#unrelatedDivs_' + eid).children().hide(); |
|
79 |
// divNode not found means 'no relation selected' (i.e. first blank item) |
|
80 |
if (divNode && divNode.length) { |
|
81 |
divNode.show(); |
|
82 |
} |
|
83 |
} |
|
84 |
||
85 |
// this function builds a Handle to cancel pending insertion |
|
86 |
function buildPendingInsertHandle(elementId, element_name, selectNodeId, eid) { |
|
87 |
jscall = "javascript: cancelPendingInsert('" + [elementId, element_name, selectNodeId, eid].join("', '") + "')"; |
|
88 |
return A({'class' : 'handle', 'href' : jscall, |
|
89 |
'title' : _("cancel this insert")}, '[x]'); |
|
90 |
} |
|
91 |
||
92 |
function buildEntityLine(relationName, selectedOptionNode, comboId, eid) { |
|
93 |
// textContent doesn't seem to work on selectedOptionNode |
|
94 |
var content = selectedOptionNode.firstChild.nodeValue; |
|
95 |
var handle = buildPendingInsertHandle(selectedOptionNode.id, 'tr', comboId, eid); |
|
96 |
var link = A({'href' : 'view?rql=' + selectedOptionNode.value, |
|
97 |
'class' : 'editionPending', 'id' : 'a' + selectedOptionNode.id}, |
|
98 |
content); |
|
99 |
var tr = TR({'id' : 'tr' + selectedOptionNode.id}, [ TH(null, relationName), |
|
100 |
TD(null, [handle, link]) |
|
101 |
]); |
|
102 |
try { |
|
103 |
var separator = getNode('relationSelectorRow_' + eid); |
|
104 |
//dump('relationSelectorRow_' + eid) XXX warn dump is not implemented in konqueror (at least) |
|
105 |
// XXX Warning: separator.parentNode is not (always ?) the |
|
106 |
// table itself, but an intermediate node (TableSectionElement) |
|
107 |
var tableBody = separator.parentNode; |
|
108 |
tableBody.insertBefore(tr, separator); |
|
109 |
} catch(ex) { |
|
110 |
log("got exception(2)!" + ex); |
|
111 |
} |
|
112 |
} |
|
113 |
||
114 |
function buildEntityCell(relationName, selectedOptionNode, comboId, eid) { |
|
115 |
var handle = buildPendingInsertHandle(selectedOptionNode.id, 'div_insert_', comboId, eid); |
|
116 |
var link = A({'href' : 'view?rql=' + selectedOptionNode.value, |
|
117 |
'class' : 'editionPending', 'id' : 'a' + selectedOptionNode.id}, |
|
118 |
content); |
|
119 |
var div = DIV({'id' : 'div_insert_' + selectedOptionNode.id}, [handle, link]); |
|
120 |
try { |
|
121 |
var td = jQuery('#cell'+ relationName +'_'+eid); |
|
122 |
td.appendChild(div); |
|
123 |
} catch(ex) { |
|
124 |
alert("got exception(3)!" + ex); |
|
125 |
} |
|
126 |
} |
|
127 |
||
128 |
function addPendingInsert(optionNode, eid, cell, relname) { |
|
129 |
var value = getNodeAttribute(optionNode, 'value'); |
|
130 |
if (!value) { |
|
131 |
// occurs when the first element in the box is selected (which is not |
|
132 |
// an entity but the combobox title) |
|
133 |
return; |
|
134 |
} |
|
135 |
// 2nd special case |
|
136 |
if (value.indexOf('http') == 0) { |
|
137 |
document.location = value; |
|
138 |
return; |
|
139 |
} |
|
140 |
// add hidden parameter |
|
141 |
var entityForm = jQuery('#entityForm'); |
|
142 |
var oid = optionNode.id.substring(2); // option id is prefixed by "id" |
|
1419 | 143 |
remoteExec('add_pending_inserts', [oid.split(':')]); |
0 | 144 |
var selectNode = optionNode.parentNode; |
145 |
// remove option node |
|
146 |
selectNode.removeChild(optionNode); |
|
147 |
// add line in table |
|
148 |
if (cell) { |
|
149 |
// new relation as a cell in multiple edit |
|
150 |
// var relation_name = relationSelected.getAttribute('value'); |
|
151 |
// relation_name = relation_name.slice(0, relation_name.lastIndexOf('_')); |
|
152 |
buildEntityCell(relname, optionNode, selectNode.id, eid); |
|
153 |
} |
|
154 |
else { |
|
155 |
var relationSelector = getNode('relationSelector_'+eid); |
|
156 |
var relationSelected = relationSelector.options[relationSelector.selectedIndex]; |
|
157 |
// new relation as a line in simple edit |
|
158 |
buildEntityLine(relationSelected.text, optionNode, selectNode.id, eid); |
|
159 |
} |
|
160 |
} |
|
161 |
||
162 |
function cancelPendingInsert(elementId, element_name, comboId, eid) { |
|
163 |
// remove matching insert element |
|
164 |
var entityView = jqNode('a' + elementId).text(); |
|
165 |
jqNode(element_name + elementId).remove(); |
|
166 |
if (comboId) { |
|
167 |
// re-insert option in combobox if it was taken from there |
|
168 |
var selectNode = getNode(comboId); |
|
1713
d817f23439ba
bix a bug: correct the sended parameter 'no need for id in the string parameter name'
Graziella Toutoungis <graziella.toutoungis@logilab.fr>
parents:
1419
diff
changeset
|
169 |
// XXX what on object relation |
0 | 170 |
if (selectNode){ |
171 |
var options = selectNode.options; |
|
172 |
var node_id = elementId.substring(0, elementId.indexOf(':')); |
|
173 |
options[options.length] = OPTION({'id' : elementId, 'value' : node_id}, entityView); |
|
174 |
} |
|
175 |
} |
|
1713
d817f23439ba
bix a bug: correct the sended parameter 'no need for id in the string parameter name'
Graziella Toutoungis <graziella.toutoungis@logilab.fr>
parents:
1419
diff
changeset
|
176 |
elementId = elementId.substring(2, elementId.length); |
1419 | 177 |
remoteExec('remove_pending_insert', elementId.split(':')); |
0 | 178 |
} |
179 |
||
180 |
// this function builds a Handle to cancel pending insertion |
|
181 |
function buildPendingDeleteHandle(elementId, eid) { |
|
182 |
var jscall = "javascript: addPendingDelete('" + elementId + ', ' + eid + "');"; |
|
183 |
return A({'href' : jscall, 'class' : 'pendingDeleteHandle', |
|
184 |
'title' : _("delete this relation")}, '[x]'); |
|
185 |
} |
|
186 |
||
187 |
// @param nodeId eid_from:r_type:eid_to |
|
188 |
function addPendingDelete(nodeId, eid) { |
|
1419 | 189 |
var d = asyncRemoteExec('add_pending_delete', nodeId.split(':')); |
0 | 190 |
d.addCallback(function () { |
191 |
// and strike entity view |
|
192 |
jqNode('span' + nodeId).addClass('pendingDelete'); |
|
193 |
// replace handle text |
|
194 |
jqNode('handle' + nodeId).text('+'); |
|
195 |
}); |
|
196 |
} |
|
197 |
||
198 |
// @param nodeId eid_from:r_type:eid_to |
|
199 |
function cancelPendingDelete(nodeId, eid) { |
|
1419 | 200 |
var d = asyncRemoteExec('remove_pending_delete', nodeId.split(':')); |
0 | 201 |
d.addCallback(function () { |
202 |
// reset link's CSS class |
|
203 |
jqNode('span' + nodeId).removeClass('pendingDelete'); |
|
204 |
// replace handle text |
|
205 |
jqNode('handle' + nodeId).text('x'); |
|
206 |
}); |
|
207 |
} |
|
208 |
||
209 |
// @param nodeId eid_from:r_type:eid_to |
|
210 |
function togglePendingDelete(nodeId, eid) { |
|
211 |
// node found means we should cancel deletion |
|
212 |
if ( hasElementClass(getNode('span' + nodeId), 'pendingDelete') ) { |
|
213 |
cancelPendingDelete(nodeId, eid); |
|
214 |
} else { |
|
215 |
addPendingDelete(nodeId, eid); |
|
216 |
} |
|
217 |
} |
|
218 |
||
219 |
||
220 |
function selectForAssociation(tripletIdsString, originalEid) { |
|
221 |
var tripletlist = map(function (x) { return x.split(':'); }, |
|
222 |
tripletIdsString.split('-')); |
|
1419 | 223 |
var d = asyncRemoteExec('add_pending_inserts', tripletlist); |
0 | 224 |
d.addCallback(function () { |
225 |
var args = {vid: 'edition', __mode: 'normal', |
|
226 |
rql: rql_for_eid(originalEid)}; |
|
1419 | 227 |
document.location = 'view?' + asURL(args); |
0 | 228 |
}); |
229 |
||
230 |
} |
|
231 |
||
232 |
||
233 |
function updateInlinedEntitiesCounters(rtype) { |
|
234 |
jQuery('#inline' + rtype + 'slot span.icounter').each(function (i) { |
|
235 |
this.innerHTML = i+1; |
|
236 |
}); |
|
237 |
} |
|
238 |
||
1419 | 239 |
|
0 | 240 |
/* |
241 |
* makes an AJAX request to get an inline-creation view's content |
|
242 |
* @param peid : the parent entity eid |
|
243 |
* @param ttype : the target (inlined) entity type |
|
244 |
* @param rtype : the relation type between both entities |
|
245 |
*/ |
|
3327
44efba78afac
fix/enhance i18n context usage for inlined forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3294
diff
changeset
|
246 |
function addInlineCreationForm(peid, ttype, rtype, role, i18nctx, insertBefore) { |
2859
822258915ff0
[javascript] allow customization of inlineCreationForm insertion point
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2852
diff
changeset
|
247 |
insertBefore = insertBefore || getNode('add' + rtype + ':' + peid + 'link').parentNode; |
3327
44efba78afac
fix/enhance i18n context usage for inlined forms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3294
diff
changeset
|
248 |
var d = asyncRemoteExec('inline_creation_form', peid, ttype, rtype, role, i18nctx); |
0 | 249 |
d.addCallback(function (response) { |
992
d5fe2626695b
call postAjaxLoad in addInlineCreationForm javascript function in order to call buildWysiwygEditors when a section of the page is reloaded
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents:
977
diff
changeset
|
250 |
var dom = getDomFromResponse(response); |
2859
822258915ff0
[javascript] allow customization of inlineCreationForm insertion point
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2852
diff
changeset
|
251 |
preprocessAjaxLoad(null, dom); |
822258915ff0
[javascript] allow customization of inlineCreationForm insertion point
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2852
diff
changeset
|
252 |
var form = jQuery(dom); |
822258915ff0
[javascript] allow customization of inlineCreationForm insertion point
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2852
diff
changeset
|
253 |
form.css('display', 'none'); |
822258915ff0
[javascript] allow customization of inlineCreationForm insertion point
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2852
diff
changeset
|
254 |
form.insertBefore(insertBefore).slideDown('fast'); |
822258915ff0
[javascript] allow customization of inlineCreationForm insertion point
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2852
diff
changeset
|
255 |
updateInlinedEntitiesCounters(rtype); |
822258915ff0
[javascript] allow customization of inlineCreationForm insertion point
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2852
diff
changeset
|
256 |
reorderTabindex(); |
3342
8b30ae9c4e67
[javascript] make inlinedform-added event bindable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3327
diff
changeset
|
257 |
jQuery(CubicWeb).trigger('inlinedform-added', form); |
3124
c929360212ca
[forms] fix form enctype handling with inlined forms
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2859
diff
changeset
|
258 |
// if the inlined form contains a file input, we must force |
c929360212ca
[forms] fix form enctype handling with inlined forms
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2859
diff
changeset
|
259 |
// the form enctype to multipart/form-data |
c929360212ca
[forms] fix form enctype handling with inlined forms
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2859
diff
changeset
|
260 |
if (form.find('input:file').length) { |
c929360212ca
[forms] fix form enctype handling with inlined forms
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2859
diff
changeset
|
261 |
form.closest('form').attr('enctype', 'multipart/form-data'); |
c929360212ca
[forms] fix form enctype handling with inlined forms
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2859
diff
changeset
|
262 |
} |
992
d5fe2626695b
call postAjaxLoad in addInlineCreationForm javascript function in order to call buildWysiwygEditors when a section of the page is reloaded
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents:
977
diff
changeset
|
263 |
postAjaxLoad(dom); |
0 | 264 |
}); |
265 |
d.addErrback(function (xxx) { |
|
2859
822258915ff0
[javascript] allow customization of inlineCreationForm insertion point
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2852
diff
changeset
|
266 |
log('xxx =', xxx); |
0 | 267 |
}); |
268 |
} |
|
269 |
||
270 |
/* |
|
271 |
* removes the part of the form used to edit an inlined entity |
|
272 |
*/ |
|
273 |
function removeInlineForm(peid, rtype, eid) { |
|
274 |
jqNode(['div', peid, rtype, eid].join('-')).slideUp('fast', function() { |
|
275 |
$(this).remove(); |
|
276 |
updateInlinedEntitiesCounters(rtype); |
|
277 |
}); |
|
278 |
} |
|
279 |
||
280 |
/* |
|
281 |
* alternatively adds or removes the hidden input that make the |
|
282 |
* edition of the relation `rtype` possible between `peid` and `eid` |
|
283 |
* @param peid : the parent entity eid |
|
284 |
* @param rtype : the relation type between both entities |
|
285 |
* @param eid : the inlined entity eid |
|
286 |
*/ |
|
287 |
function removeInlinedEntity(peid, rtype, eid) { |
|
3544
188d86631c45
fix #471746
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3343
diff
changeset
|
288 |
// XXX work around the eid_param thing (eid + ':' + eid) for #471746 |
188d86631c45
fix #471746
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3343
diff
changeset
|
289 |
var nodeid = ['rel', peid, rtype, eid + ':' + eid].join('-'); |
0 | 290 |
var node = jqNode(nodeid); |
3545
242b07b6d820
fix remove/do not remove action sequence (using a temp attribute instead of setting a wrong value in the resurrected hidden input)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3544
diff
changeset
|
291 |
if (! node.attr('cubicweb:type')) { |
242b07b6d820
fix remove/do not remove action sequence (using a temp attribute instead of setting a wrong value in the resurrected hidden input)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3544
diff
changeset
|
292 |
node.attr('cubicweb:type', node.val()); |
242b07b6d820
fix remove/do not remove action sequence (using a temp attribute instead of setting a wrong value in the resurrected hidden input)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3544
diff
changeset
|
293 |
node.val(''); |
1419 | 294 |
var divid = ['div', peid, rtype, eid].join('-'); |
0 | 295 |
jqNode(divid).fadeTo('fast', 0.5); |
1419 | 296 |
var noticeid = ['notice', peid, rtype, eid].join('-'); |
0 | 297 |
jqNode(noticeid).fadeIn('fast'); |
298 |
} |
|
299 |
} |
|
300 |
||
301 |
function restoreInlinedEntity(peid, rtype, eid) { |
|
3544
188d86631c45
fix #471746
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3343
diff
changeset
|
302 |
// XXX work around the eid_param thing (eid + ':' + eid) for #471746 |
188d86631c45
fix #471746
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3343
diff
changeset
|
303 |
var nodeid = ['rel', peid, rtype, eid + ':' + eid].join('-'); |
0 | 304 |
var node = jqNode(nodeid); |
3545
242b07b6d820
fix remove/do not remove action sequence (using a temp attribute instead of setting a wrong value in the resurrected hidden input)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3544
diff
changeset
|
305 |
if (node.attr('cubicweb:type')) { |
242b07b6d820
fix remove/do not remove action sequence (using a temp attribute instead of setting a wrong value in the resurrected hidden input)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3544
diff
changeset
|
306 |
node.val(node.attr('cubicweb:type')); |
242b07b6d820
fix remove/do not remove action sequence (using a temp attribute instead of setting a wrong value in the resurrected hidden input)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3544
diff
changeset
|
307 |
node.attr('cubicweb:type', ''); |
0 | 308 |
jqNode(['fs', peid, rtype, eid].join('-')).append(node); |
3544
188d86631c45
fix #471746
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3343
diff
changeset
|
309 |
var divid = ['div', peid, rtype, eid].join('-'); |
0 | 310 |
jqNode(divid).fadeTo('fast', 1); |
3544
188d86631c45
fix #471746
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3343
diff
changeset
|
311 |
var noticeid = ['notice', peid, rtype, eid].join('-'); |
0 | 312 |
jqNode(noticeid).hide(); |
313 |
} |
|
314 |
} |
|
315 |
||
316 |
function _clearPreviousErrors(formid) { |
|
2246
e89c15221a8a
remove error class from fields as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2242
diff
changeset
|
317 |
jQuery('#' + formid + 'ErrorMessage').remove(); |
0 | 318 |
jQuery('#' + formid + ' span.error').remove(); |
2246
e89c15221a8a
remove error class from fields as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2242
diff
changeset
|
319 |
jQuery('#' + formid + ' .error').removeClass('error'); |
0 | 320 |
} |
321 |
||
322 |
function _displayValidationerrors(formid, eid, errors) { |
|
323 |
var globalerrors = []; |
|
324 |
var firsterrfield = null; |
|
325 |
for (fieldname in errors) { |
|
326 |
var errmsg = errors[fieldname]; |
|
327 |
var fieldid = fieldname + ':' + eid; |
|
328 |
var field = jqNode(fieldname + ':' + eid); |
|
329 |
if (field && getNodeAttribute(field, 'type') != 'hidden') { |
|
330 |
if ( !firsterrfield ) { |
|
331 |
firsterrfield = 'err-' + fieldid; |
|
332 |
} |
|
333 |
addElementClass(field, 'error'); |
|
334 |
var span = SPAN({'id': 'err-' + fieldid, 'class': "error"}, errmsg); |
|
335 |
field.before(span); |
|
336 |
} else { |
|
337 |
firsterrfield = formid; |
|
2242
6772f8e859c2
translate not found fields, also clear global errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1971
diff
changeset
|
338 |
globalerrors.push(_(fieldname) + ' : ' + errmsg); |
0 | 339 |
} |
340 |
} |
|
341 |
if (globalerrors.length) { |
|
342 |
if (globalerrors.length == 1) { |
|
343 |
var innernode = SPAN(null, globalerrors[0]); |
|
344 |
} else { |
|
345 |
var innernode = UL(null, map(LI, globalerrors)); |
|
346 |
} |
|
347 |
// insert DIV and innernode before the form |
|
2246
e89c15221a8a
remove error class from fields as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2242
diff
changeset
|
348 |
var div = DIV({'class' : "errorMessage", 'id': formid + 'ErrorMessage'}); |
0 | 349 |
div.appendChild(innernode); |
350 |
jQuery('#' + formid).before(div); |
|
351 |
} |
|
352 |
return firsterrfield || formid; |
|
353 |
} |
|
354 |
||
355 |
||
3343
383b42263bb1
[validatecontroller] allow additional args to be passed to the js callback
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3342
diff
changeset
|
356 |
function handleFormValidationResponse(formid, onsuccess, onfailure, result, cbargs) { |
0 | 357 |
// Success |
358 |
if (result[0]) { |
|
359 |
if (onsuccess) { |
|
3343
383b42263bb1
[validatecontroller] allow additional args to be passed to the js callback
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3342
diff
changeset
|
360 |
onsuccess(result, formid, cbargs); |
0 | 361 |
} else { |
362 |
document.location.href = result[1]; |
|
363 |
} |
|
3100
b0a583156d6d
fix reledit validation error handling for relations #345477
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2859
diff
changeset
|
364 |
return true; |
0 | 365 |
} |
366 |
unfreezeFormButtons(formid); |
|
367 |
// Failures |
|
368 |
_clearPreviousErrors(formid); |
|
369 |
var descr = result[1]; |
|
370 |
// Unknown structure |
|
371 |
if ( !isArrayLike(descr) || descr.length != 2 ) { |
|
372 |
log('got strange error :', descr); |
|
373 |
updateMessage(descr); |
|
3100
b0a583156d6d
fix reledit validation error handling for relations #345477
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2859
diff
changeset
|
374 |
return false; |
0 | 375 |
} |
376 |
_displayValidationerrors(formid, descr[0], descr[1]); |
|
3100
b0a583156d6d
fix reledit validation error handling for relations #345477
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2859
diff
changeset
|
377 |
updateMessage(_('please correct errors below')); |
0 | 378 |
document.location.hash = '#header'; |
3100
b0a583156d6d
fix reledit validation error handling for relations #345477
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2859
diff
changeset
|
379 |
if (onfailure) { |
3343
383b42263bb1
[validatecontroller] allow additional args to be passed to the js callback
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3342
diff
changeset
|
380 |
onfailure(formid, cbargs); |
1864
4ceaf8f2709b
add onfailure fonction for validateForm, return formid on success
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
1798
diff
changeset
|
381 |
} |
3100
b0a583156d6d
fix reledit validation error handling for relations #345477
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2859
diff
changeset
|
382 |
return false; |
0 | 383 |
} |
384 |
||
385 |
||
386 |
/* unfreeze form buttons when the validation process is over*/ |
|
387 |
function unfreezeFormButtons(formid) { |
|
388 |
jQuery('#progress').hide(); |
|
389 |
jQuery('#' + formid + ' input.validateButton').removeAttr('disabled'); |
|
390 |
return true; |
|
391 |
} |
|
392 |
||
393 |
/* disable form buttons while the validation is being done */ |
|
394 |
function freezeFormButtons(formid) { |
|
395 |
jQuery('#progress').show(); |
|
977 | 396 |
jQuery('#' + formid + ' input.validateButton').attr('disabled', 'disabled'); |
0 | 397 |
return true; |
398 |
} |
|
399 |
||
400 |
/* used by additional submit buttons to remember which button was clicked */ |
|
401 |
function postForm(bname, bvalue, formid) { |
|
402 |
var form = getNode(formid); |
|
403 |
if (bname) { |
|
404 |
form.appendChild(INPUT({type: 'hidden', name: bname, value: bvalue})); |
|
405 |
} |
|
406 |
var onsubmit = form.onsubmit; |
|
407 |
if (!onsubmit || (onsubmit && onsubmit())) { |
|
408 |
form.submit(); |
|
409 |
} |
|
410 |
} |
|
411 |
||
412 |
||
413 |
/* called on load to set target and iframeso object. |
|
414 |
* NOTE: this is a hack to make the XHTML compliant. |
|
415 |
* NOTE2: `object` nodes might be a potential replacement for iframes |
|
416 |
* NOTE3: there is a XHTML module allowing iframe elements but there |
|
417 |
* is still the problem of the form's `target` attribute |
|
418 |
*/ |
|
419 |
function setFormsTarget() { |
|
420 |
jQuery('form.entityForm').each(function () { |
|
421 |
var form = jQuery(this); |
|
422 |
var target = form.attr('cubicweb:target'); |
|
423 |
if (target) { |
|
424 |
form.attr('target', target); |
|
1419 | 425 |
/* do not use display: none because some browsers ignore iframe |
426 |
* with no display */ |
|
0 | 427 |
form.append(IFRAME({name: target, id: target, |
428 |
src: 'javascript: void(0)', |
|
429 |
width: '0px', height: '0px'})); |
|
430 |
} |
|
431 |
}); |
|
432 |
} |
|
433 |
||
2364
fa16d36d60cb
[js] small cleanup
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2345
diff
changeset
|
434 |
jQuery(document).ready(setFormsTarget); |
0 | 435 |
|
436 |
||
437 |
/* |
|
438 |
* called on traditionnal form submission : the idea is to try |
|
439 |
* to post the form. If the post is successful, `validateForm` redirects |
|
440 |
* to the appropriate URL. Otherwise, the validation errors are displayed |
|
441 |
* around the corresponding input fields. |
|
442 |
*/ |
|
1864
4ceaf8f2709b
add onfailure fonction for validateForm, return formid on success
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
1798
diff
changeset
|
443 |
function validateForm(formid, action, onsuccess, onfailure) { |
0 | 444 |
try { |
1419 | 445 |
var zipped = formContents(formid); |
446 |
var d = asyncRemoteExec('validate_form', action, zipped[0], zipped[1]); |
|
0 | 447 |
} catch (ex) { |
448 |
log('got exception', ex); |
|
449 |
return false; |
|
450 |
} |
|
451 |
function _callback(result, req) { |
|
1864
4ceaf8f2709b
add onfailure fonction for validateForm, return formid on success
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
1798
diff
changeset
|
452 |
handleFormValidationResponse(formid, onsuccess, onfailure, result); |
0 | 453 |
} |
454 |
d.addCallback(_callback); |
|
455 |
return false; |
|
456 |
} |
|
457 |
||
1419 | 458 |
|
0 | 459 |
/* |
1759
61d026ced19f
preliminary support for inline edition of relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1713
diff
changeset
|
460 |
* called by reledit forms to submit changes |
0 | 461 |
* @param formid : the dom id of the form used |
462 |
* @param rtype : the attribute being edited |
|
463 |
* @param eid : the eid of the entity being edited |
|
464 |
* @param reload: boolean to reload page if true (when changing URL dependant data) |
|
2482
dead2d56f711
[reledit] attributes : have a laning zone after all (less intrusive), fix likely bug of relation edition
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2382
diff
changeset
|
465 |
* @param default_value : value if the field is empty |
dead2d56f711
[reledit] attributes : have a laning zone after all (less intrusive), fix likely bug of relation edition
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2382
diff
changeset
|
466 |
* @param lzone : html fragment (string) for a clic-zone triggering actual edition |
0 | 467 |
*/ |
2371
76bf522c27be
[reledit] simplify, fixing #344545
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2364
diff
changeset
|
468 |
function inlineValidateAttributeForm(rtype, eid, divid, reload, default_value) { |
0 | 469 |
try { |
2371
76bf522c27be
[reledit] simplify, fixing #344545
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2364
diff
changeset
|
470 |
var form = getNode(divid+'-form'); |
0 | 471 |
if (typeof FCKeditorAPI != "undefined") { |
472 |
for ( var name in FCKeditorAPI.__Instances ) { |
|
473 |
var oEditor = FCKeditorAPI.__Instances[name] ; |
|
474 |
if ( oEditor.GetParentForm() == form ) { |
|
475 |
oEditor.UpdateLinkedField(); |
|
476 |
} |
|
477 |
} |
|
478 |
} |
|
479 |
var zipped = formContents(form); |
|
1798
cc86fe8efaaa
pass default values along the whole call chain, fix hidden field update bug
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1760
diff
changeset
|
480 |
var d = asyncRemoteExec('edit_field', 'apply', zipped[0], zipped[1], |
2345
16e3d0e47ee6
[reledit] there is nothing to escape, also cleanup lzone for attributes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2334
diff
changeset
|
481 |
rtype, eid, default_value); |
0 | 482 |
} catch (ex) { |
483 |
log('got exception', ex); |
|
484 |
return false; |
|
485 |
} |
|
486 |
d.addCallback(function (result, req) { |
|
3294
5047b2566634
do not wipe a good value if input is bad and cancelled
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3232
diff
changeset
|
487 |
if (handleFormValidationResponse(divid+'-form', noop, noop, result)) { |
5047b2566634
do not wipe a good value if input is bad and cancelled
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3232
diff
changeset
|
488 |
if (reload) { |
2490
b0771c03f531
[reledit] do NOT peruse the likely ?vid=edition part
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2483
diff
changeset
|
489 |
document.location.href = result[1].split('?')[0]; |
3294
5047b2566634
do not wipe a good value if input is bad and cancelled
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3232
diff
changeset
|
490 |
} else { |
2482
dead2d56f711
[reledit] attributes : have a laning zone after all (less intrusive), fix likely bug of relation edition
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2382
diff
changeset
|
491 |
var fieldview = getNode('value-' + divid); |
0 | 492 |
// XXX using innerHTML is very fragile and won't work if |
493 |
// we mix XHTML and HTML |
|
494 |
fieldview.innerHTML = result[2]; |
|
495 |
// switch inline form off only if no error |
|
496 |
if (result[0]) { |
|
497 |
// hide global error messages |
|
2371
76bf522c27be
[reledit] simplify, fixing #344545
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2364
diff
changeset
|
498 |
hideInlineEdit(eid, rtype, divid); |
0 | 499 |
} |
3294
5047b2566634
do not wipe a good value if input is bad and cancelled
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3232
diff
changeset
|
500 |
} |
5047b2566634
do not wipe a good value if input is bad and cancelled
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3232
diff
changeset
|
501 |
} |
0 | 502 |
return false; |
503 |
}); |
|
504 |
return false; |
|
505 |
} |
|
506 |
||
2371
76bf522c27be
[reledit] simplify, fixing #344545
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2364
diff
changeset
|
507 |
function inlineValidateRelationForm(rtype, role, eid, divid, reload, vid, |
2345
16e3d0e47ee6
[reledit] there is nothing to escape, also cleanup lzone for attributes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2334
diff
changeset
|
508 |
default_value, lzone) { |
1759
61d026ced19f
preliminary support for inline edition of relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1713
diff
changeset
|
509 |
try { |
2371
76bf522c27be
[reledit] simplify, fixing #344545
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2364
diff
changeset
|
510 |
var form = getNode(divid+'-form'); |
1798
cc86fe8efaaa
pass default values along the whole call chain, fix hidden field update bug
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1760
diff
changeset
|
511 |
var relname = rtype + ':' + eid; |
cc86fe8efaaa
pass default values along the whole call chain, fix hidden field update bug
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1760
diff
changeset
|
512 |
var newtarget = jQuery('[name=' + relname + ']').val(); |
1759
61d026ced19f
preliminary support for inline edition of relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1713
diff
changeset
|
513 |
var zipped = formContents(form); |
2382
c1dcb5aef4b4
[reledit] simplify a bit more
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2371
diff
changeset
|
514 |
var d = asyncRemoteExec('validate_form', 'apply', zipped[0], zipped[1]); |
1759
61d026ced19f
preliminary support for inline edition of relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1713
diff
changeset
|
515 |
} catch (ex) { |
61d026ced19f
preliminary support for inline edition of relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1713
diff
changeset
|
516 |
return false; |
61d026ced19f
preliminary support for inline edition of relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1713
diff
changeset
|
517 |
} |
61d026ced19f
preliminary support for inline edition of relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1713
diff
changeset
|
518 |
d.addCallback(function (result, req) { |
3100
b0a583156d6d
fix reledit validation error handling for relations #345477
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2859
diff
changeset
|
519 |
if (handleFormValidationResponse(divid+'-form', noop, noop, result)) { |
b0a583156d6d
fix reledit validation error handling for relations #345477
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2859
diff
changeset
|
520 |
if (reload) { |
b0a583156d6d
fix reledit validation error handling for relations #345477
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2859
diff
changeset
|
521 |
document.location.href = result[1].split('?')[0]; |
b0a583156d6d
fix reledit validation error handling for relations #345477
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2859
diff
changeset
|
522 |
} else { |
2382
c1dcb5aef4b4
[reledit] simplify a bit more
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2371
diff
changeset
|
523 |
var d = asyncRemoteExec('reledit_form', eid, rtype, role, default_value, lzone); |
2371
76bf522c27be
[reledit] simplify, fixing #344545
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2364
diff
changeset
|
524 |
d.addCallback(function (result) { |
2482
dead2d56f711
[reledit] attributes : have a laning zone after all (less intrusive), fix likely bug of relation edition
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2382
diff
changeset
|
525 |
// XXX brittle ... replace with loadxhtml |
2371
76bf522c27be
[reledit] simplify, fixing #344545
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2364
diff
changeset
|
526 |
jQuery('#'+divid+'-reledit').replaceWith(result); |
76bf522c27be
[reledit] simplify, fixing #344545
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2364
diff
changeset
|
527 |
}); |
2334
464c896bee65
[reledit] reload support for relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2330
diff
changeset
|
528 |
} |
1759
61d026ced19f
preliminary support for inline edition of relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1713
diff
changeset
|
529 |
} |
1760
6b97d286eb5a
[reledit] relation edition : cleanup a bit #343123
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1759
diff
changeset
|
530 |
return false; |
1759
61d026ced19f
preliminary support for inline edition of relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1713
diff
changeset
|
531 |
}); |
1760
6b97d286eb5a
[reledit] relation edition : cleanup a bit #343123
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1759
diff
changeset
|
532 |
return false; |
1759
61d026ced19f
preliminary support for inline edition of relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1713
diff
changeset
|
533 |
} |
61d026ced19f
preliminary support for inline edition of relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1713
diff
changeset
|
534 |
|
61d026ced19f
preliminary support for inline edition of relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1713
diff
changeset
|
535 |
|
0 | 536 |
/**** inline edition ****/ |
537 |
function showInlineEditionForm(eid, rtype, divid) { |
|
538 |
jQuery('#' + divid).hide(); |
|
2371
76bf522c27be
[reledit] simplify, fixing #344545
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2364
diff
changeset
|
539 |
jQuery('#' + divid+'-form').show(); |
0 | 540 |
} |
541 |
||
2371
76bf522c27be
[reledit] simplify, fixing #344545
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2364
diff
changeset
|
542 |
function hideInlineEdit(eid, rtype, divid) { |
3100
b0a583156d6d
fix reledit validation error handling for relations #345477
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2859
diff
changeset
|
543 |
jQuery('#appMsg').hide(); |
b0a583156d6d
fix reledit validation error handling for relations #345477
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2859
diff
changeset
|
544 |
jQuery('div.errorMessage').remove(); |
0 | 545 |
jQuery('#' + divid).show(); |
2371
76bf522c27be
[reledit] simplify, fixing #344545
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2364
diff
changeset
|
546 |
jQuery('#' + divid+'-form').hide(); |
0 | 547 |
} |
548 |
||
549 |
CubicWeb.provide('edition.js'); |