Merge lp:~xmo-deactivatedaccount/openobject-client-web/m2o-dialogs into lp:openobject-client-web/trunk
- m2o-dialogs
- Merge into trunk
Proposed by
Xavier (Open ERP)
Status: | Merged |
---|---|
Merged at revision: | 4045 |
Proposed branch: | lp:~xmo-deactivatedaccount/openobject-client-web/m2o-dialogs |
Merge into: | lp:openobject-client-web/trunk |
Diff against target: |
543 lines (+187/-116) 7 files modified
addons/openerp/controllers/search.py (+5/-6) addons/openerp/controllers/templates/openm2o.mako (+8/-13) addons/openerp/controllers/templates/search.mako (+32/-46) addons/openerp/static/css/style.css (+2/-2) addons/openerp/static/javascript/form.js (+19/-3) addons/openerp/static/javascript/m2o.js (+114/-29) addons/openerp/static/javascript/openerp/openerp.base.js (+7/-17) |
To merge this branch: | bzr merge lp:~xmo-deactivatedaccount/openobject-client-web/m2o-dialogs |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Aline (OpenERP) | Approve | ||
Review via email: mp+42354@code.launchpad.net |
Commit message
Description of the change
Branch replacing the existing dialogs for selecting values in m2o (when no filter or initial filter matches more than a single value) by jquery-ui's in-page dialogs (tab-modal)
To post a comment you must log in.
Revision history for this message
Aline (OpenERP) (apr-tinyerp) wrote : | # |
- 4002. By Xavier (Open ERP)
-
[FIX] URL for creation in m2o and m2m popups
- 4003. By Xavier (Open ERP)
-
[FIX] issue with openLink in popup context
- 4004. By Xavier (Open ERP)
-
[FIX] make m2o dialog [new] aware of the $.m2o interface and use it, so that it's possible to create new objects via the m2o selector interface
Revision history for this message
Xavier (Open ERP) (xmo-deactivatedaccount) wrote : | # |
[new] should be fixed, there is a known issue with clicking on an m2o link in a readonly form view (popup opens and the [close] button doesn't work).
Revision history for this message
Xavier (Open ERP) (xmo-deactivatedaccount) wrote : | # |
Voilà, j'avais un peu oublié les popups pour voir ou éditer un record m2o, normalement c'est bon maintenant.
- 4005. By Xavier (Open ERP)
-
[IMP] make m2o popups for single records (edition or readonly) use dialogs as well
Revision history for this message
Aline (OpenERP) (apr-tinyerp) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'addons/openerp/controllers/search.py' |
2 | --- addons/openerp/controllers/search.py 2010-11-30 10:18:24 +0000 |
3 | +++ addons/openerp/controllers/search.py 2010-12-02 08:39:30 +0000 |
4 | @@ -199,19 +199,18 @@ |
5 | data = {} |
6 | res = proxy.fields_get() |
7 | |
8 | - frm = {} |
9 | all_values = {} |
10 | |
11 | for k, v in record.items(): |
12 | values = {} |
13 | for key, val in v.items(): |
14 | for field in val: |
15 | - fld = {} |
16 | - datas = {} |
17 | - fld['value'] = val[field] |
18 | - fld['type'] = res[field].get('type') |
19 | + fld = { |
20 | + 'value': val[field], |
21 | + 'type': res[field].get('type') |
22 | + } |
23 | + datas = {field: fld} |
24 | |
25 | - data[field] = fld |
26 | try: |
27 | frm = TinyForm(**data).to_python() |
28 | except TinyFormError, e: |
29 | |
30 | === modified file 'addons/openerp/controllers/templates/openm2o.mako' |
31 | --- addons/openerp/controllers/templates/openm2o.mako 2010-09-29 10:26:28 +0000 |
32 | +++ addons/openerp/controllers/templates/openm2o.mako 2010-12-02 08:39:30 +0000 |
33 | @@ -15,18 +15,13 @@ |
34 | |
35 | jQuery(document).ready(function() { |
36 | |
37 | - var id = parseInt(openobject.dom.get('_terp_id').value) || null; |
38 | - var lc = parseInt(openobject.dom.get('_terp_load_counter').value) || 1; |
39 | - |
40 | - if (lc > 1 && id) { |
41 | - window.opener.document.getElementById('${params.m2o}').value = id; |
42 | - window.opener.document.getElementById('${params.m2o}_text').value = ''; |
43 | - window.opener.setTimeout("signal(openobject.dom.get('${params.m2o}'), 'onchange')", 0); |
44 | - } |
45 | - |
46 | - if (lc > 1) { |
47 | - window.close(); |
48 | - } |
49 | + var id = parseInt(openobject.dom.get('_terp_id').value, 10) || null; |
50 | + var lc = parseInt(openobject.dom.get('_terp_load_counter', 10).value) || 1; |
51 | + |
52 | + if(lc <= 1) { |
53 | + return; |
54 | + } |
55 | + $.m2o('close', id); |
56 | }); |
57 | </script> |
58 | </%def> |
59 | @@ -54,7 +49,7 @@ |
60 | </td> |
61 | % endif |
62 | <td class="save_close"> |
63 | - <a class="button-a" onclick="window.close()" href="javascript: void(0)">${_("Close")}</a> |
64 | + <a class="button-a" onclick="$.m2o('close');" href="javascript: void(0)">${_("Close")}</a> |
65 | </td> |
66 | <td width="100%"> |
67 | </td> |
68 | |
69 | === modified file 'addons/openerp/controllers/templates/search.mako' |
70 | --- addons/openerp/controllers/templates/search.mako 2010-11-30 10:49:29 +0000 |
71 | +++ addons/openerp/controllers/templates/search.mako 2010-12-02 08:39:30 +0000 |
72 | @@ -1,22 +1,32 @@ |
73 | <%inherit file="/openerp/controllers/templates/base_dispatch.mako"/> |
74 | +<%! |
75 | + KINDS = { |
76 | + 'M2O': 1, |
77 | + 'M2M': 2 |
78 | + } |
79 | +%> |
80 | |
81 | <%def name="header()"> |
82 | <% |
83 | - if params.selectable == 1: |
84 | + if params.selectable == KINDS['M2O']: |
85 | create_url = "/openm2o/edit" |
86 | - elif params.selectable == 2: |
87 | + elif params.selectable == KINDS['M2M']: |
88 | create_url = "/openm2m/new" |
89 | %> |
90 | <title>Search ${form.screen.string}</title> |
91 | |
92 | <script type="text/javascript"> |
93 | var form_controller = '/openerp/search'; |
94 | + function close_dialog() { |
95 | + window.close() |
96 | + } |
97 | </script> |
98 | - % if params.selectable == 1: |
99 | + % if params.selectable == KINDS['M2O']: |
100 | <script type="text/javascript"> |
101 | - function do_select(res_id){ |
102 | - var selected_id = res_id |
103 | - |
104 | + function close_dialog() { |
105 | + $.m2o('close'); |
106 | + } |
107 | + function do_select(selected_id){ |
108 | if (!selected_id) { |
109 | var ids = new ListView('_terp_list').getSelectedRecords(); |
110 | |
111 | @@ -25,34 +35,10 @@ |
112 | |
113 | selected_id = ids[0]; |
114 | } |
115 | - |
116 | - var $ = window.opener.jQuery; |
117 | - var $value = $(idSelector('${params.source}')); |
118 | - var $text = $(idSelector('${params.source}_text')); |
119 | - |
120 | - $value.val(selected_id); |
121 | - $text.val(''); |
122 | - |
123 | - if($value[0].onchange) { |
124 | - $value[0].onchange(); |
125 | - } else { |
126 | - $value.change(); |
127 | - window.opener.MochiKit.Signal.signal($value[0], 'onchange'); |
128 | - } |
129 | - |
130 | - window.close(); |
131 | - } |
132 | - |
133 | - function do_create(){ |
134 | - openLink(openobject.http.getURL('/openerp/openm2o/edit', { |
135 | - _terp_model: '${params.model}', |
136 | - _terp_source: '${params.source}', |
137 | - _terp_m2o: '${params.source}', |
138 | - _terp_domain: openobject.dom.get('_terp_domain').value, |
139 | - _terp_context: openobject.dom.get('_terp_context').value})); |
140 | + $.m2o('close', selected_id); |
141 | } |
142 | </script> |
143 | - % elif params.selectable == 2: |
144 | + % elif params.selectable == KINDS['M2M']: |
145 | % if params.get('return_to'): |
146 | <script type="text/javascript"> |
147 | function do_select() { |
148 | @@ -76,7 +62,7 @@ |
149 | return; |
150 | } |
151 | } |
152 | - window.close() |
153 | + close_dialog(); |
154 | } |
155 | </script> |
156 | % else: |
157 | @@ -109,21 +95,21 @@ |
158 | |
159 | m2m.setValue(ids); |
160 | } |
161 | - window.close(); |
162 | + close_dialog(); |
163 | } |
164 | </script> |
165 | % endif |
166 | - <script type="text/javascript"> |
167 | - function do_create(){ |
168 | - openLink(openobject.http.getURL('/openerp/openm2m/new', { |
169 | - _terp_model: '${params.model}', |
170 | - _terp_source: '${params.source}', |
171 | - _terp_m2m: '${params.source}', |
172 | - _terp_domain: openobject.dom.get('_terp_domain').value, |
173 | - _terp_context: openobject.dom.get('_terp_context').value})); |
174 | - } |
175 | - </script> |
176 | % endif |
177 | + <script type="text/javascript"> |
178 | + function do_create(){ |
179 | + openLink(openobject.http.getURL('/openerp${create_url}', { |
180 | + _terp_model: '${params.model}', |
181 | + _terp_source: '${params.source}', |
182 | + _terp_m2m: '${params.source}', |
183 | + _terp_domain: openobject.dom.get('_terp_domain').value, |
184 | + _terp_context: openobject.dom.get('_terp_context').value})); |
185 | + } |
186 | + </script> |
187 | </%def> |
188 | |
189 | <%def name="content()"> |
190 | @@ -160,7 +146,7 @@ |
191 | % endif |
192 | <a class="button-a" href="javascript: void(0)" onclick="search_filter()">${_("Search")}</a> |
193 | <a class="button-a" href="javascript: void(0)" onclick="do_create()">${_("New")}</a> |
194 | - <a class="button-a" href="javascript: void(0)" onclick="window.close()">${_("Close")}</a> |
195 | + <a class="button-a" href="javascript: void(0)" onclick="close_dialog();">${_("Close")}</a> |
196 | |
197 | </td> |
198 | </tr> |
199 | @@ -196,7 +182,7 @@ |
200 | }); |
201 | } |
202 | jQuery('table.search_table input:text').eq(0).focus(); |
203 | - % if params.selectable == 2: |
204 | + % if params.selectable == KINDS['M2M']: |
205 | var $select_link = jQuery('a.select-link').hide(); |
206 | jQuery('form#search_form').click(function(event) { |
207 | if ($(event.target).is("input[type=checkbox]")) { |
208 | |
209 | === modified file 'addons/openerp/static/css/style.css' |
210 | --- addons/openerp/static/css/style.css 2010-11-30 17:30:39 +0000 |
211 | +++ addons/openerp/static/css/style.css 2010-12-02 08:39:30 +0000 |
212 | @@ -1022,7 +1022,7 @@ |
213 | vertical-align: middle; |
214 | } |
215 | |
216 | -.action-dialog, |
217 | -.action-dialog .ui-dialog-content { |
218 | +iframe.ui-dialog-content { |
219 | padding: 0 !important; |
220 | + width: 100% !important; |
221 | } |
222 | |
223 | === modified file 'addons/openerp/static/javascript/form.js' |
224 | --- addons/openerp/static/javascript/form.js 2010-12-01 17:27:22 +0000 |
225 | +++ addons/openerp/static/javascript/form.js 2010-12-02 08:39:30 +0000 |
226 | @@ -720,8 +720,10 @@ |
227 | }); |
228 | } |
229 | |
230 | +var KIND_M2O = 1; |
231 | +var KIND_M2M = 2; |
232 | function open_search_window(relation, domain, context, source, kind, text){ |
233 | - if (kind == 2 && source.indexOf('_terp_listfields/') == 0) { |
234 | + if (kind == KIND_M2M && source.indexOf('_terp_listfields/') == 0) { |
235 | text = ""; |
236 | } |
237 | |
238 | @@ -730,14 +732,28 @@ |
239 | 'domain': domain, |
240 | 'context': context |
241 | }).addCallback(function(obj){ |
242 | - openobject.tools.openWindow(openobject.http.getURL('/openerp/search/new', { |
243 | + var dialog_url = openobject.http.getURL('/openerp/search/new', { |
244 | 'model': relation, |
245 | 'domain': obj.domain, |
246 | 'context': obj.context, |
247 | 'source': source, |
248 | 'kind': kind, |
249 | 'text': text |
250 | - })); |
251 | + }); |
252 | + switch(kind) { |
253 | + case KIND_M2O: |
254 | + jQuery.m2o({ |
255 | + 'model': relation, |
256 | + 'domain': obj.domain, |
257 | + 'context': obj.context, |
258 | + 'source': source, |
259 | + 'kind': kind, |
260 | + 'text': text |
261 | + }); |
262 | + break; |
263 | + default: |
264 | + openobject.tools.openWindow(dialog_url); |
265 | + } |
266 | }); |
267 | } |
268 | |
269 | |
270 | === modified file 'addons/openerp/static/javascript/m2o.js' |
271 | --- addons/openerp/static/javascript/m2o.js 2010-11-29 15:28:52 +0000 |
272 | +++ addons/openerp/static/javascript/m2o.js 2010-12-02 08:39:30 +0000 |
273 | @@ -56,13 +56,8 @@ |
274 | this.lastKey = null; |
275 | this.delayedRequest = null; |
276 | this.completeDelay = 1; |
277 | - this.hasHiddenValue = false; |
278 | this.lastTextResult = null; |
279 | this.lastSearch = null; |
280 | - this.onlySuggest = false; |
281 | - this.minChars = 1; |
282 | - this.processCount = 0; |
283 | - this.takeFocus = false; |
284 | this.hasFocus = false; |
285 | this.suggestionBoxMouseOver = false; |
286 | this.selectedResult = false; |
287 | @@ -103,17 +98,11 @@ |
288 | this.field._m2o = this; |
289 | |
290 | this.change_icon(); |
291 | - |
292 | - if(this.takeFocus) { |
293 | - this.text.focus(); |
294 | - this.gotFocus(); |
295 | - } |
296 | } |
297 | }; |
298 | |
299 | ManyToOne.prototype.gotFocus = function(evt) { |
300 | this.hasFocus = true; |
301 | - if(!this.minChars) this.on_keyup(evt); |
302 | }; |
303 | |
304 | ManyToOne.prototype.lostFocus = function() { |
305 | @@ -167,10 +156,15 @@ |
306 | domain: domain, |
307 | context: context |
308 | }).addCallback(function(obj) { |
309 | - openobject.tools.openWindow(openobject.http.getURL('/openerp/openm2o/edit', { |
310 | - _terp_model: model, _terp_id: id, |
311 | - _terp_domain: obj.domain, _terp_context: obj.context, |
312 | - _terp_m2o: source, _terp_editable: editable ? 'True' : 'False'})); |
313 | + $.m2o({ |
314 | + record: true, |
315 | + _terp_model: model, |
316 | + _terp_id: id, |
317 | + _terp_domain: obj.domain, |
318 | + _terp_context: obj.context, |
319 | + _terp_m2o: source, |
320 | + _terp_editable: editable ? 'True' : 'False' |
321 | + }); |
322 | }); |
323 | }; |
324 | |
325 | @@ -235,7 +229,7 @@ |
326 | // Stop processing if a special key has been pressed. Or if the last search requested the same string |
327 | if(this.specialKeyPressed || (this.text.value == this.lastSearch)) return false; |
328 | |
329 | - if(this.minChars && this.text.value.length < this.minChars) { |
330 | + if(!this.text.value.length) { |
331 | if(this.delayedRequest) { |
332 | this.delayedRequest.cancel(); |
333 | this.clearResults(); |
334 | @@ -287,10 +281,6 @@ |
335 | case 13: |
336 | case 1: |
337 | var $selectedRow = jQuery(idSelector("autoComplete" + this.name + "_" + this.selectedResultRow)); |
338 | - if(this.onlySuggest && $selectedRow.length) { |
339 | - this.clearResults(); |
340 | - break; |
341 | - } |
342 | |
343 | this.setCompletionText($selectedRow); |
344 | |
345 | @@ -436,14 +426,12 @@ |
346 | var val = s.lastIndexOf(',') >= 0 ? s.substring(s.lastIndexOf(',') + 1).replace(/^\s+|\s+$/g, "") : s.replace(/^\s+|\s+$/g, ""); |
347 | |
348 | // Check again if less than required chars, then we won't search. |
349 | - if(this.minChars && val.length < this.minChars) { |
350 | + if(!val.length) { |
351 | this.clearResults(); |
352 | return false; |
353 | } |
354 | |
355 | // Get what we are searching for |
356 | - this.processCount++; |
357 | - |
358 | this.lastSearch = this.text.value; |
359 | jQuery.getJSON('/openerp/search/get_matched', { |
360 | text: val, |
361 | @@ -456,7 +444,6 @@ |
362 | try { |
363 | if(!this.hasFocus) { |
364 | this.updateSelectedResult(); |
365 | - this.processCount--; |
366 | return false; |
367 | } |
368 | |
369 | @@ -466,10 +453,7 @@ |
370 | "id": "autoCompleteTable" + this.name}); |
371 | this.numResultRows = result.values.length; |
372 | |
373 | - if(this.onlySuggest) |
374 | - this.selectedResultRow = null; |
375 | - else |
376 | - this.selectedResultRow = 0; |
377 | + this.selectedResultRow = 0; |
378 | |
379 | var mouseOver = jQuery.proxy(this, 'getMouseover'); |
380 | var onClick = jQuery.proxy(this, 'getOnclick'); |
381 | @@ -501,7 +485,6 @@ |
382 | $resultsHolder.hide(); |
383 | } |
384 | |
385 | - this.processCount--; |
386 | return true; |
387 | } |
388 | catch(e) { |
389 | @@ -538,3 +521,105 @@ |
390 | evt.which = 13; |
391 | this.on_keydown(evt); |
392 | }; |
393 | + |
394 | +(function ($) { |
395 | + /** |
396 | + * Opens an m2o dialog linked to the provided <code>$this</code> window, |
397 | + * with the selected options. |
398 | + * |
399 | + * @param $this the parent window of the opened dialog, contains the |
400 | + * input to fill with the selected m2o value if any |
401 | + * @param options A map of options to provide to the xhr call. |
402 | + * The <code>source</code> key is also used for the id of the element |
403 | + * (in <code>$this</code>) on which any selected m2o value should be set. |
404 | + * The <code>record</code> key indicates whether a record should be opened |
405 | + * instead of a search view |
406 | + */ |
407 | + function open($this, options) { |
408 | + var url; |
409 | + if(options.record) { |
410 | + url = '/openerp/openm2o/edit' |
411 | + } else { |
412 | + url = '/openerp/search/new'; |
413 | + } |
414 | + return $('<iframe>', { |
415 | + src: openobject.http.getURL(url, options), |
416 | + frameborder: 0 |
417 | + }).data('source_window', $this[0]) |
418 | + .data('source_id', options.source || null) |
419 | + .appendTo(document.documentElement) |
420 | + .dialog({ |
421 | + modal: true, |
422 | + width: 640, |
423 | + height: 480, |
424 | + close: function () { |
425 | + jQuery(this).dialog('destroy').remove(); |
426 | + } |
427 | + }); |
428 | + } |
429 | + |
430 | + /** |
431 | + * Closes the m2o dialog it was called from (represented by |
432 | + * <code>$this</code>, setting the related m2o input to the provided |
433 | + * <code>value</code>, if any. |
434 | + * |
435 | + * @param $this the window of the dialog to close |
436 | + * @param value optional, the value to set the m2o input to if it is |
437 | + * provided |
438 | + */ |
439 | + function close($this, value) { |
440 | + var $frame = $($this.attr('frameElement')); |
441 | + if(value) { |
442 | + // the m2o input to set is in the source_window, which is set as |
443 | + // a `data` of the dialog iframe |
444 | + var jQ = $frame.data('source_window').jQuery; |
445 | + var source_id = $frame.data('source_id'); |
446 | + jQ(idSelector(source_id + '_text')).val(''); |
447 | + var $m2o_field = jQ(idSelector(source_id)).val(value); |
448 | + |
449 | + if($m2o_field[0].onchange) { |
450 | + $m2o_field[0].onchange(); |
451 | + } else { |
452 | + $m2o_field.change(); |
453 | + } |
454 | + } |
455 | + $frame.dialog('close'); |
456 | + return null; |
457 | + } |
458 | + |
459 | + /** |
460 | + * Manage m2o dialogs for this scope |
461 | + * <ul> |
462 | + * <li><p>Called with only options, opens a new m2o dialog linking to the |
463 | + * current scope.</p></li> |
464 | + * <li><p>Called with the <code>"close"</code> command, closes the m2o |
465 | + * dialog it was invoked from and focuses its parent scope. |
466 | + * </p></li> |
467 | + * <li><p>Called with the <code>"close"</code> command and an argument, |
468 | + * sets that argument as the m2o value of the parent widget and |
469 | + * closes the m2o dialog it was invoked from as above. |
470 | + * </p></li> |
471 | + * </ul> |
472 | + * |
473 | + * @returns the m2o container (iframe) if one was created |
474 | + */ |
475 | + $.m2o = function () { |
476 | + // $this should be the holder for the window from which $.m2o was |
477 | + // originally called, even if $.m2o() was bubbled to the top of |
478 | + // the window stack. |
479 | + var $this; |
480 | + if(this == $) $this = $(window); |
481 | + else $this = $(this); |
482 | + if(window != window.top) { |
483 | + return window.top.jQuery.m2o.apply($this[0], arguments); |
484 | + } |
485 | + // We're at the top-level window, $this is the window from which the |
486 | + // original $.m2o call was performed, window being the current window |
487 | + // level. |
488 | + if(arguments[0] === "close") { |
489 | + return close($this, arguments[1]); |
490 | + } else { |
491 | + return open($this, arguments[0]); |
492 | + } |
493 | + }; |
494 | +})(jQuery); |
495 | |
496 | === modified file 'addons/openerp/static/javascript/openerp/openerp.base.js' |
497 | --- addons/openerp/static/javascript/openerp/openerp.base.js 2010-11-29 11:13:59 +0000 |
498 | +++ addons/openerp/static/javascript/openerp/openerp.base.js 2010-12-02 08:39:30 +0000 |
499 | @@ -25,9 +25,7 @@ |
500 | error: loadingError |
501 | }); |
502 | } else { |
503 | - window.location.assign( |
504 | - '/?' + jQuery.param({next: url}) |
505 | - ); |
506 | + window.location.assign(url); |
507 | } |
508 | } |
509 | /** |
510 | @@ -100,27 +98,19 @@ |
511 | var $dialogs = jQuery('.action-dialog'); |
512 | switch(target) { |
513 | case 'new': |
514 | - var $contentFrame = jQuery('<iframe>', { |
515 | + jQuery('<iframe>', { |
516 | src: action_url, |
517 | - frameborder: 0, |
518 | - width: '99%', |
519 | - height: '99%' |
520 | - }); |
521 | - jQuery('<div class="action-dialog">') |
522 | - .appendTo(document.documentElement) |
523 | + 'class': 'action-dialog', |
524 | + frameborder: 0 |
525 | + }).appendTo(document.documentElement) |
526 | .dialog({ |
527 | modal: true, |
528 | width: 640, |
529 | height: 480, |
530 | close: function () { |
531 | - var $this = jQuery(this); |
532 | - $this.find('iframe').remove(); |
533 | - setTimeout(function () { |
534 | - $this.dialog('destroy').remove(); |
535 | - }); |
536 | + jQuery(this).dialog('destroy').remove(); |
537 | } |
538 | - }) |
539 | - .append($contentFrame); |
540 | + }); |
541 | break; |
542 | case 'current': |
543 | default: |
did you try to click "new" ?