Revision 7e7aae8d
Von Sven Schöling vor mehr als 6 Jahren hinzugefügt
SL/Controller/CustomerVendor.pm | ||
---|---|---|
640 | 640 |
} |
641 | 641 |
|
642 | 642 |
sub action_test_page { |
643 |
$::request->{layout}->add_javascripts('autocomplete_customer.js'); |
|
644 | 643 |
$_[0]->render('customer_vendor/test_page'); |
645 | 644 |
} |
646 | 645 |
|
... | ... | |
939 | 938 |
|
940 | 939 |
$self->{template_args} ||= {}; |
941 | 940 |
|
942 |
$::request->{layout}->add_javascripts('autocomplete_customer.js'); |
|
943 | 941 |
$::request->{layout}->add_javascripts('kivi.CustomerVendor.js'); |
944 | 942 |
$::request->{layout}->add_javascripts('kivi.File.js'); |
945 | 943 |
|
SL/Presenter/CustomerVendor.pm | ||
---|---|---|
53 | 53 |
} |
54 | 54 |
|
55 | 55 |
my $id = delete($params{id}) || $self->name_to_id($name); |
56 |
my $fat_set_item = delete $params{fat_set_item}; |
|
57 | 56 |
|
58 | 57 |
my @classes = $params{class} ? ($params{class}) : (); |
59 | 58 |
push @classes, 'customer_vendor_autocomplete'; |
60 |
push @classes, 'customer-vendor-picker-fat-set-item' if $fat_set_item; |
|
61 | 59 |
|
62 | 60 |
my $ret = |
63 |
$self->input_tag($name, (ref $value && $value->can('id') ? $value->id : ''), class => "@classes", type => 'hidden', id => $id) . |
|
64 |
join('', map { $params{$_} ? $self->input_tag("", delete $params{$_}, id => "${id}_${_}", type => 'hidden') : '' } qw(type)) . |
|
61 |
$self->input_tag($name, (ref $value && $value->can('id') ? $value->id : ''), class => "@classes", type => 'hidden', id => $id, |
|
62 |
'data-customer-vendor-picker-data' => JSON::to_json(\%params), |
|
63 |
) . |
|
65 | 64 |
$self->input_tag("", ref $value ? $value->displayable_name : '', id => "${id}_name", %params); |
66 | 65 |
|
67 |
$::request->layout->add_javascripts('autocomplete_customer.js');
|
|
66 |
$::request->layout->add_javascripts('kivi.CustomerVendor.js');
|
|
68 | 67 |
$::request->presenter->need_reinit_widgets($id); |
69 | 68 |
|
70 | 69 |
$self->html_tag('span', $ret, class => 'customer_vendor_picker'); |
js/autocomplete_customer.js | ||
---|---|---|
1 |
namespace('kivi', function(k){ |
|
2 |
"use strict"; |
|
3 |
|
|
4 |
k.CustomerVendorPicker = function($real, options) { |
|
5 |
// short circuit in case someone double inits us |
|
6 |
if ($real.data("customer_vendor_picker")) |
|
7 |
return $real.data("customer_vendor_picker"); |
|
8 |
|
|
9 |
var KEY = { |
|
10 |
ESCAPE: 27, |
|
11 |
ENTER: 13, |
|
12 |
TAB: 9, |
|
13 |
LEFT: 37, |
|
14 |
RIGHT: 39, |
|
15 |
PAGE_UP: 33, |
|
16 |
PAGE_DOWN: 34, |
|
17 |
SHIFT: 16, |
|
18 |
CTRL: 17, |
|
19 |
ALT: 18, |
|
20 |
}; |
|
21 |
var CLASSES = { |
|
22 |
PICKED: 'customer-vendor-picker-picked', |
|
23 |
UNDEFINED: 'customer-vendor-picker-undefined', |
|
24 |
FAT_SET_ITEM: 'customer-vendor-picker-fat-set-item', |
|
25 |
} |
|
26 |
var o = $.extend({ |
|
27 |
limit: 20, |
|
28 |
delay: 50, |
|
29 |
fat_set_item: $real.hasClass(CLASSES.FAT_SET_ITEM), |
|
30 |
}, options); |
|
31 |
var STATES = { |
|
32 |
PICKED: CLASSES.PICKED, |
|
33 |
UNDEFINED: CLASSES.UNDEFINED |
|
34 |
} |
|
35 |
var real_id = $real.attr('id'); |
|
36 |
var $dummy = $('#' + real_id + '_name'); |
|
37 |
var $type = $('#' + real_id + '_type'); |
|
38 |
var $unit = $('#' + real_id + '_unit'); |
|
39 |
var state = STATES.PICKED; |
|
40 |
var last_real = $real.val(); |
|
41 |
var last_dummy = $dummy.val(); |
|
42 |
var timer; |
|
43 |
|
|
44 |
function ajax_data(term) { |
|
45 |
var data = { |
|
46 |
'filter.all:substr:multi::ilike': term, |
|
47 |
'filter.obsolete': 0, |
|
48 |
current: $real.val(), |
|
49 |
type: $type.val(), |
|
50 |
}; |
|
51 |
|
|
52 |
return data; |
|
53 |
} |
|
54 |
|
|
55 |
function set_item (item) { |
|
56 |
if (item.id) { |
|
57 |
$real.val(item.id); |
|
58 |
// autocomplete ui has name, ajax items have description |
|
59 |
$dummy.val(item.name ? item.name : item.description); |
|
60 |
} else { |
|
61 |
$real.val(''); |
|
62 |
$dummy.val(''); |
|
63 |
} |
|
64 |
state = STATES.PICKED; |
|
65 |
last_real = $real.val(); |
|
66 |
last_dummy = $dummy.val(); |
|
67 |
$real.trigger('change'); |
|
68 |
|
|
69 |
if (o.fat_set_item && item.id) { |
|
70 |
$.ajax({ |
|
71 |
url: 'controller.pl?action=CustomerVendor/show.json', |
|
72 |
data: { id: item.id, db: item.type }, |
|
73 |
success: function(rsp) { |
|
74 |
$real.trigger('set_item:CustomerVendorPicker', rsp); |
|
75 |
}, |
|
76 |
}); |
|
77 |
} else { |
|
78 |
$real.trigger('set_item:CustomerVendorPicker', item); |
|
79 |
} |
|
80 |
annotate_state(); |
|
81 |
} |
|
82 |
|
|
83 |
function make_defined_state () { |
|
84 |
if (state == STATES.PICKED) { |
|
85 |
annotate_state(); |
|
86 |
return true |
|
87 |
} else if (state == STATES.UNDEFINED && $dummy.val() === '') |
|
88 |
set_item({}) |
|
89 |
else { |
|
90 |
set_item({ id: last_real, name: last_dummy }) |
|
91 |
} |
|
92 |
annotate_state(); |
|
93 |
} |
|
94 |
|
|
95 |
function annotate_state () { |
|
96 |
if (state == STATES.PICKED) |
|
97 |
$dummy.removeClass(STATES.UNDEFINED).addClass(STATES.PICKED); |
|
98 |
else if (state == STATES.UNDEFINED && $dummy.val() === '') |
|
99 |
$dummy.removeClass(STATES.UNDEFINED).addClass(STATES.PICKED); |
|
100 |
else { |
|
101 |
$dummy.addClass(STATES.UNDEFINED).removeClass(STATES.PICKED); |
|
102 |
} |
|
103 |
} |
|
104 |
|
|
105 |
function handle_changed_text(callbacks) { |
|
106 |
$.ajax({ |
|
107 |
url: 'controller.pl?action=CustomerVendor/ajaj_autocomplete', |
|
108 |
dataType: "json", |
|
109 |
data: $.extend( ajax_data($dummy.val()), { prefer_exact: 1 } ), |
|
110 |
success: function (data) { |
|
111 |
if (data.length == 1) { |
|
112 |
set_item(data[0]); |
|
113 |
if (callbacks && callbacks.match_one) callbacks.match_one(data[0]); |
|
114 |
} else if (data.length > 1) { |
|
115 |
state = STATES.UNDEFINED; |
|
116 |
if (callbacks && callbacks.match_many) callbacks.match_many(data); |
|
117 |
} else { |
|
118 |
state = STATES.UNDEFINED; |
|
119 |
if (callbacks &&callbacks.match_none) callbacks.match_none(); |
|
120 |
} |
|
121 |
annotate_state(); |
|
122 |
} |
|
123 |
}); |
|
124 |
} |
|
125 |
|
|
126 |
$dummy.autocomplete({ |
|
127 |
source: function(req, rsp) { |
|
128 |
$.ajax($.extend(o, { |
|
129 |
url: 'controller.pl?action=CustomerVendor/ajaj_autocomplete', |
|
130 |
dataType: "json", |
|
131 |
data: ajax_data(req.term), |
|
132 |
success: function (data){ rsp(data) } |
|
133 |
})); |
|
134 |
}, |
|
135 |
select: function(event, ui) { |
|
136 |
set_item(ui.item); |
|
137 |
}, |
|
138 |
search: function(event, ui) { |
|
139 |
if ((event.which == KEY.SHIFT) || (event.which == KEY.CTRL) || (event.which == KEY.ALT)) |
|
140 |
event.preventDefault(); |
|
141 |
} |
|
142 |
}); |
|
143 |
/* In case users are impatient and want to skip ahead: |
|
144 |
* Capture <enter> key events and check if it's a unique hit. |
|
145 |
* If it is, go ahead and assume it was selected. If it wasn't don't do |
|
146 |
* anything so that autocompletion kicks in. For <tab> don't prevent |
|
147 |
* propagation. It would be nice to catch it, but javascript is too stupid |
|
148 |
* to fire a tab event later on, so we'd have to reimplement the "find |
|
149 |
* next active element in tabindex order and focus it". |
|
150 |
*/ |
|
151 |
/* note: |
|
152 |
* event.which does not contain tab events in keypressed in firefox but will report 0 |
|
153 |
* chrome does not fire keypressed at all on tab or escape |
|
154 |
*/ |
|
155 |
$dummy.keydown(function(event){ |
|
156 |
if (event.which == KEY.ENTER || event.which == KEY.TAB) { |
|
157 |
// if string is empty assume they want to delete |
|
158 |
if ($dummy.val() === '') { |
|
159 |
set_item({}); |
|
160 |
return true; |
|
161 |
} else if (state == STATES.PICKED) { |
|
162 |
return true; |
|
163 |
} |
|
164 |
if (event.which == KEY.TAB) { |
|
165 |
event.preventDefault(); |
|
166 |
handle_changed_text(); |
|
167 |
} |
|
168 |
if (event.which == KEY.ENTER) { |
|
169 |
handle_changed_text({ |
|
170 |
match_one: function(){$('#update_button').click();}, |
|
171 |
}); |
|
172 |
return false; |
|
173 |
} |
|
174 |
} else if ((event.which != KEY.SHIFT) && (event.which != KEY.CTRL) && (event.which != KEY.ALT)) { |
|
175 |
state = STATES.UNDEFINED; |
|
176 |
} |
|
177 |
}); |
|
178 |
|
|
179 |
$dummy.on('paste', function(){ |
|
180 |
setTimeout(function() { |
|
181 |
handle_changed_text(); |
|
182 |
}, 1); |
|
183 |
}); |
|
184 |
|
|
185 |
$dummy.blur(function(){ |
|
186 |
window.clearTimeout(timer); |
|
187 |
timer = window.setTimeout(annotate_state, 100); |
|
188 |
}); |
|
189 |
|
|
190 |
// now add a picker div after the original input |
|
191 |
var pp = { |
|
192 |
real: function() { return $real }, |
|
193 |
dummy: function() { return $dummy }, |
|
194 |
type: function() { return $type }, |
|
195 |
set_item: set_item, |
|
196 |
reset: make_defined_state, |
|
197 |
is_defined_state: function() { return state == STATES.PICKED }, |
|
198 |
} |
|
199 |
$real.data('customer_vendor_picker', pp); |
|
200 |
return pp; |
|
201 |
} |
|
202 |
}); |
|
203 |
|
|
204 |
$(function(){ |
|
205 |
$('input.customer_vendor_autocomplete').each(function(i,real){ |
|
206 |
kivi.CustomerVendorPicker($(real)); |
|
207 |
}) |
|
208 |
}); |
js/kivi.CustomerVendor.js | ||
---|---|---|
45 | 45 |
$ctrl.prop('checked', cvar.value == 1 ? 'checked' : ''); |
46 | 46 |
|
47 | 47 |
else if ((cvar.type == 'customer') || (cvar.type == 'vendor')) |
48 |
kivi.CustomerVendorPicker($ctrl).set_item({ id: cvar.id, name: cvar.value }); |
|
48 |
kivi.CustomerVendor.Picker($ctrl).set_item({ id: cvar.id, name: cvar.value });
|
|
49 | 49 |
|
50 | 50 |
else if (cvar.type == 'part') |
51 | 51 |
kivi.Part.Picker($ctrl).set_item({ id: cvar.id, name: cvar.value }); |
... | ... | |
222 | 222 |
event.preventDefault(); |
223 | 223 |
ns.inline_report(target, event.target + '', {}); |
224 | 224 |
}; |
225 |
}); |
|
226 | 225 |
|
227 |
function local_reinit_widgets() { |
|
228 |
$('#cv_phone,#shipto_shiptophone,#contact_cp_phone1,#contact_cp_phone2,#contact_cp_mobile1,#contact_cp_mobile2').each(function(idx, elt) { |
|
229 |
kivi.CustomerVendor.init_dial_action($(elt)); |
|
226 |
var KEY = { |
|
227 |
TAB: 9, |
|
228 |
ENTER: 13, |
|
229 |
SHIFT: 16, |
|
230 |
CTRL: 17, |
|
231 |
ALT: 18, |
|
232 |
ESCAPE: 27, |
|
233 |
PAGE_UP: 33, |
|
234 |
PAGE_DOWN: 34, |
|
235 |
LEFT: 37, |
|
236 |
UP: 38, |
|
237 |
RIGHT: 39, |
|
238 |
DOWN: 40, |
|
239 |
}; |
|
240 |
|
|
241 |
ns.Picker = function($real, options) { |
|
242 |
var self = this; |
|
243 |
this.o = $.extend(true, { |
|
244 |
limit: 20, |
|
245 |
delay: 50, |
|
246 |
action: { |
|
247 |
commit_none: function(){ }, |
|
248 |
commit_one: function(){ $('#update_button').click(); }, |
|
249 |
commit_many: function(){ } |
|
250 |
} |
|
251 |
}, $real.data('customer-vendor-picker-data'), options); |
|
252 |
this.$real = $real; |
|
253 |
this.real_id = $real.attr('id'); |
|
254 |
this.last_real = $real.val(); |
|
255 |
this.$dummy = $($real.siblings()[0]); |
|
256 |
this.autocomplete_open = false; |
|
257 |
this.state = this.STATES.PICKED; |
|
258 |
this.last_dummy = this.$dummy.val(); |
|
259 |
this.timer = undefined; |
|
260 |
|
|
261 |
this.init(); |
|
262 |
}; |
|
263 |
|
|
264 |
ns.Picker.prototype = { |
|
265 |
CLASSES: { |
|
266 |
PICKED: 'customer-vendor-picker-picked', |
|
267 |
UNDEFINED: 'customer-vendor-picker-undefined', |
|
268 |
}, |
|
269 |
ajax_data: function(term) { |
|
270 |
return { |
|
271 |
'filter.all:substr:multi::ilike': term, |
|
272 |
'filter.obsolete': 0, |
|
273 |
current: this.$real.val(), |
|
274 |
type: this.o.type, |
|
275 |
}; |
|
276 |
}, |
|
277 |
set_item: function(item) { |
|
278 |
var self = this; |
|
279 |
if (item.id) { |
|
280 |
this.$real.val(item.id); |
|
281 |
// autocomplete ui has name, use the value for ajax items, which contains displayable_name |
|
282 |
this.$dummy.val(item.name ? item.name : item.value); |
|
283 |
} else { |
|
284 |
this.$real.val(''); |
|
285 |
this.$dummy.val(''); |
|
286 |
} |
|
287 |
this.state = this.STATES.PICKED; |
|
288 |
this.last_real = this.$real.val(); |
|
289 |
this.last_dummy = this.$dummy.val(); |
|
290 |
this.$real.trigger('change'); |
|
291 |
|
|
292 |
if (this.o.fat_set_item && item.id) { |
|
293 |
$.ajax({ |
|
294 |
url: 'controller.pl?action=CustomerVendor/show.json', |
|
295 |
data: { 'id': item.id, 'db': item.type }, |
|
296 |
success: function(rsp) { |
|
297 |
self.$real.trigger('set_item:CustomerVendorPicker', rsp); |
|
298 |
}, |
|
299 |
}); |
|
300 |
} else { |
|
301 |
this.$real.trigger('set_item:CustomerVendorPicker', item); |
|
302 |
} |
|
303 |
this.annotate_state(); |
|
304 |
}, |
|
305 |
set_multi_items: function(data) { |
|
306 |
this.run_action(this.o.action.set_multi_items, [ data ]); |
|
307 |
}, |
|
308 |
make_defined_state: function() { |
|
309 |
if (this.state == this.STATES.PICKED) { |
|
310 |
this.annotate_state(); |
|
311 |
return true |
|
312 |
} else if (this.state == this.STATES.UNDEFINED && this.$dummy.val() === '') |
|
313 |
this.set_item({}) |
|
314 |
else { |
|
315 |
this.set_item({ id: this.last_real, name: this.last_dummy }) |
|
316 |
} |
|
317 |
this.annotate_state(); |
|
318 |
}, |
|
319 |
annotate_state: function() { |
|
320 |
if (this.state == this.STATES.PICKED) |
|
321 |
this.$dummy.removeClass(this.STATES.UNDEFINED).addClass(this.STATES.PICKED); |
|
322 |
else if (this.state == this.STATES.UNDEFINED && this.$dummy.val() === '') |
|
323 |
this.$dummy.removeClass(this.STATES.UNDEFINED).addClass(this.STATES.PICKED); |
|
324 |
else { |
|
325 |
this.$dummy.addClass(this.STATES.UNDEFINED).removeClass(this.STATES.PICKED); |
|
326 |
} |
|
327 |
}, |
|
328 |
handle_changed_text: function(callbacks) { |
|
329 |
var self = this; |
|
330 |
$.ajax({ |
|
331 |
url: 'controller.pl?action=CustomerVendor/ajaj_autocomplete', |
|
332 |
dataType: "json", |
|
333 |
data: $.extend( self.ajax_data(self.$dummy.val()), { prefer_exact: 1 } ), |
|
334 |
success: function (data) { |
|
335 |
if (data.length == 1) { |
|
336 |
self.set_item(data[0]); |
|
337 |
if (callbacks && callbacks.match_one) self.run_action(callbacks.match_one, [ data[0] ]); |
|
338 |
} else if (data.length > 1) { |
|
339 |
self.state = self.STATES.UNDEFINED; |
|
340 |
if (callbacks && callbacks.match_many) self.run_action(callbacks.match_many, [ data ]); |
|
341 |
} else { |
|
342 |
self.state = self.STATES.UNDEFINED; |
|
343 |
if (callbacks && callbacks.match_none) self.run_action(callbacks.match_none, [ self, self.$dummy.val() ]); |
|
344 |
} |
|
345 |
self.annotate_state(); |
|
346 |
} |
|
347 |
}); |
|
348 |
}, |
|
349 |
handle_keydown: function(event) { |
|
350 |
var self = this; |
|
351 |
if (event.which == KEY.ENTER || event.which == KEY.TAB) { |
|
352 |
// if string is empty assume they want to delete |
|
353 |
if (self.$dummy.val() === '') { |
|
354 |
self.set_item({}); |
|
355 |
return true; |
|
356 |
} else if (self.state == self.STATES.PICKED) { |
|
357 |
if (self.o.action.commit_one) { |
|
358 |
self.run_action(self.o.action.commit_one); |
|
359 |
} |
|
360 |
return true; |
|
361 |
} |
|
362 |
if (event.which == KEY.TAB) { |
|
363 |
event.preventDefault(); |
|
364 |
self.handle_changed_text(); |
|
365 |
} |
|
366 |
if (event.which == KEY.ENTER) { |
|
367 |
self.handle_changed_text({ |
|
368 |
match_none: self.o.action.commit_none, |
|
369 |
match_one: self.o.action.commit_one, |
|
370 |
match_many: self.o.action.commit_many |
|
371 |
}); |
|
372 |
return false; |
|
373 |
} |
|
374 |
} else if (event.which == KEY.DOWN && !self.autocomplete_open) { |
|
375 |
var old_options = self.$dummy.autocomplete('option'); |
|
376 |
self.$dummy.autocomplete('option', 'minLength', 0); |
|
377 |
self.$dummy.autocomplete('search', self.$dummy.val()); |
|
378 |
self.$dummy.autocomplete('option', 'minLength', old_options.minLength); |
|
379 |
} else if ((event.which != KEY.SHIFT) && (event.which != KEY.CTRL) && (event.which != KEY.ALT)) { |
|
380 |
self.state = self.STATES.UNDEFINED; |
|
381 |
} |
|
382 |
}, |
|
383 |
init: function() { |
|
384 |
var self = this; |
|
385 |
this.$dummy.autocomplete({ |
|
386 |
source: function(req, rsp) { |
|
387 |
$.ajax($.extend({}, self.o, { |
|
388 |
url: 'controller.pl?action=CustomerVendor/ajaj_autocomplete', |
|
389 |
dataType: "json", |
|
390 |
type: 'get', |
|
391 |
data: self.ajax_data(req.term), |
|
392 |
success: function (data){ rsp(data) } |
|
393 |
})); |
|
394 |
}, |
|
395 |
select: function(event, ui) { |
|
396 |
self.set_item(ui.item); |
|
397 |
}, |
|
398 |
search: function(event, ui) { |
|
399 |
if ((event.which == KEY.SHIFT) || (event.which == KEY.CTRL) || (event.which == KEY.ALT)) |
|
400 |
event.preventDefault(); |
|
401 |
}, |
|
402 |
open: function() { |
|
403 |
self.autocomplete_open = true; |
|
404 |
}, |
|
405 |
close: function() { |
|
406 |
self.autocomplete_open = false; |
|
407 |
} |
|
408 |
}); |
|
409 |
this.$dummy.keydown(function(event){ self.handle_keydown(event) }); |
|
410 |
this.$dummy.on('paste', function(){ |
|
411 |
setTimeout(function() { |
|
412 |
self.handle_changed_text(); |
|
413 |
}, 1); |
|
414 |
}); |
|
415 |
this.$dummy.blur(function(){ |
|
416 |
window.clearTimeout(self.timer); |
|
417 |
self.timer = window.setTimeout(function() { self.annotate_state() }, 100); |
|
418 |
}); |
|
419 |
}, |
|
420 |
run_action: function(code, args) { |
|
421 |
if (typeof code === 'function') |
|
422 |
code.apply(this, args) |
|
423 |
else |
|
424 |
kivi.run(code, args); |
|
425 |
}, |
|
426 |
clear: function() { |
|
427 |
this.set_item({}); |
|
428 |
} |
|
429 |
}; |
|
430 |
ns.Picker.prototype.STATES = { |
|
431 |
PICKED: ns.Picker.prototype.CLASSES.PICKED, |
|
432 |
UNDEFINED: ns.Picker.prototype.CLASSES.UNDEFINED |
|
433 |
}; |
|
434 |
|
|
435 |
ns.reinit_widgets = function() { |
|
436 |
kivi.run_once_for('input.customer_vendor_autocomplete', 'customer_vendor_picker', function(elt) { |
|
437 |
if (!$(elt).data('customer_vendor_picker')) |
|
438 |
$(elt).data('customer_vendor_picker', new kivi.CustomerVendor.Picker($(elt))); |
|
439 |
}); |
|
440 |
|
|
441 |
$('#cv_phone,#shipto_shiptophone,#contact_cp_phone1,#contact_cp_phone2,#contact_cp_mobile1,#contact_cp_mobile2').each(function(idx, elt) { |
|
442 |
kivi.CustomerVendor.init_dial_action($(elt)); |
|
443 |
}); |
|
444 |
} |
|
445 |
|
|
446 |
ns.init = function() { |
|
447 |
ns.reinit_widgets(); |
|
448 |
} |
|
449 |
|
|
450 |
$(function(){ |
|
451 |
ns.init(); |
|
230 | 452 |
}); |
231 |
} |
|
453 |
}); |
js/kivi.js | ||
---|---|---|
242 | 242 |
}); |
243 | 243 |
|
244 | 244 |
if (ns.Part) ns.Part.reinit_widgets(); |
245 |
if (ns.CustomerVendor) ns.CustomerVendor.reinit_widgets(); |
|
245 | 246 |
|
246 | 247 |
if (ns.ProjectPicker) |
247 | 248 |
ns.run_once_for('input.project_autocomplete', 'project_picker', function(elt) { |
248 | 249 |
kivi.ProjectPicker($(elt)); |
249 | 250 |
}); |
250 | 251 |
|
251 |
if (ns.CustomerVendorPicker) |
|
252 |
ns.run_once_for('input.customer_vendor_autocomplete', 'customer_vendor_picker', function(elt) { |
|
253 |
kivi.CustomerVendorPicker($(elt)); |
|
254 |
}); |
|
255 |
|
|
256 | 252 |
if (ns.ChartPicker) |
257 | 253 |
ns.run_once_for('input.chart_autocomplete', 'chart_picker', function(elt) { |
258 | 254 |
kivi.ChartPicker($(elt)); |
templates/webpages/customer_vendor/tabs/contacts.html | ||
---|---|---|
18 | 18 |
empty_title = LxERP.t8('New contact'), |
19 | 19 |
value_key = 'cp_id', |
20 | 20 |
title_key = 'full_name', |
21 |
onchange = "kivi.CustomerVendor.selectContact({onFormSet: function(){ contactsMapWidget.testInputs(); local_reinit_widgets(); }});",
|
|
21 |
onchange = "kivi.CustomerVendor.selectContact({onFormSet: function(){ contactsMapWidget.testInputs(); kivi.reinit_widgets(); }});",
|
|
22 | 22 |
) |
23 | 23 |
%] |
24 | 24 |
</td> |
templates/webpages/customer_vendor/tabs/shipto.html | ||
---|---|---|
16 | 16 |
title_key = 'displayable_id', |
17 | 17 |
with_empty = 1, |
18 | 18 |
empty_title = LxERP.t8('New shipto'), |
19 |
onchange = "kivi.CustomerVendor.selectShipto({onFormSet: function(){ shiptoMapWidget.testInputs(); local_reinit_widgets(); }});",
|
|
19 |
onchange = "kivi.CustomerVendor.selectShipto({onFormSet: function(){ shiptoMapWidget.testInputs(); kivi.reinit_widgets(); }});",
|
|
20 | 20 |
) |
21 | 21 |
%] |
22 | 22 |
</td> |
templates/webpages/customer_vendor/test_page.html | ||
---|---|---|
24 | 24 |
|
25 | 25 |
<br><hr> |
26 | 26 |
this one will be a reinit_widget after 4s:<br> |
27 |
<span id='vendor3' class=""> |
|
28 |
<input id="vendor3_id" class="" type="hidden" name="vendor3_id" value=""> |
|
29 |
<input id="vendor3_id_type" type="hidden" name="" value="vendor"> |
|
27 |
<span id='vendor3' class="customer_vendor_picker"> |
|
28 |
<input id="vendor3_id" class="" type="hidden" name="vendor3_id" value="" data-customer-vendor-picker-data="{"type":"vendor"}"> |
|
30 | 29 |
<input id="vendor3_id_name" type="text" name="" value=""> |
31 | 30 |
</span> |
32 | 31 |
|
Auch abrufbar als: Unified diff
CustomerVendor Picker: auf prototype Picker umgestellt analog zu Part