Revision f16c5520
Von Sven Schöling vor mehr als 10 Jahren hinzugefügt
SL/Controller/CustomerVendor.pm | ||
---|---|---|
7 | 7 |
use SL::DBUtils; |
8 | 8 |
use SL::Helper::Flash; |
9 | 9 |
use SL::Locale::String; |
10 |
use SL::Controller::Helper::GetModels; |
|
10 | 11 |
|
11 | 12 |
use SL::DB::Customer; |
12 | 13 |
use SL::DB::Vendor; |
... | ... | |
23 | 24 |
use SL::DB::History; |
24 | 25 |
use SL::DB::Currency; |
25 | 26 |
|
27 |
use Rose::Object::MakeMethods::Generic ( |
|
28 |
'scalar --get_set_init' => [ qw(customer_models vendor_models) ], |
|
29 |
); |
|
30 |
|
|
26 | 31 |
# safety |
27 | 32 |
__PACKAGE__->run_before( |
28 | 33 |
sub { |
... | ... | |
50 | 55 |
'_load_customer_vendor', |
51 | 56 |
only => [ |
52 | 57 |
'edit', |
58 |
'show', |
|
53 | 59 |
'update', |
54 | 60 |
'ajaj_get_shipto', |
55 | 61 |
'ajaj_get_contact', |
... | ... | |
88 | 94 |
); |
89 | 95 |
} |
90 | 96 |
|
97 |
sub action_show { |
|
98 |
my ($self) = @_; |
|
99 |
|
|
100 |
if ($::request->type eq 'json') { |
|
101 |
my $cv_hash; |
|
102 |
if (!$self->{cv}) { |
|
103 |
# TODO error |
|
104 |
} else { |
|
105 |
$cv_hash = $self->{cv}->as_tree; |
|
106 |
$cv_hash->{cvars} = $self->{cv}->cvar_as_hashref; |
|
107 |
} |
|
108 |
|
|
109 |
$self->render(\ SL::JSON::to_json($cv_hash), { layout => 0, type => 'json', process => 0 }); |
|
110 |
} |
|
111 |
} |
|
112 |
|
|
91 | 113 |
sub _save { |
92 | 114 |
my ($self) = @_; |
93 | 115 |
|
... | ... | |
539 | 561 |
$self->render(\SL::JSON::to_json($data), { type => 'json', process => 0 }); |
540 | 562 |
} |
541 | 563 |
|
542 |
sub action_ajaj_customer_autocomplete {
|
|
564 |
sub action_ajaj_autocomplete { |
|
543 | 565 |
my ($self, %params) = @_; |
544 | 566 |
|
545 |
my $limit = $::form->{limit} || 20; |
|
546 |
my $type = $::form->{type} || {}; |
|
547 |
my $query = { ilike => '%'. $::form->{term} .'%' }; |
|
548 |
|
|
549 |
my @filter; |
|
550 |
push( |
|
551 |
@filter, |
|
552 |
$::form->{column} ? ($::form->{column} => $query) : (or => [ customernumber => $query, name => $query ]) |
|
553 |
); |
|
567 |
my ($model, $manager, $number, $matches); |
|
568 |
|
|
569 |
# first see if this is customer or vendor picking |
|
570 |
if ($::form->{type} eq 'customer') { |
|
571 |
$model = $self->customer_models; |
|
572 |
$manager = 'SL::DB::Manager::Customer'; |
|
573 |
$number = 'customernumber'; |
|
574 |
} elsif ($::form->{type} eq 'vendor') { |
|
575 |
$model = $self->vendor_models; |
|
576 |
$manager = 'SL::DB::Manager::Vendor'; |
|
577 |
$number = 'vendornumber'; |
|
578 |
} else { |
|
579 |
die "unknown type $::form->{type}"; |
|
580 |
} |
|
554 | 581 |
|
555 |
push @filter, (or => [ obsolete => undef, obsolete => 0 ]) if !$::form->{obsolete}; |
|
582 |
# if someone types something, and hits enter, assume he entered the full name. |
|
583 |
# if something matches, treat that as sole match |
|
584 |
# unfortunately get_models can't do more than one per package atm, so we d it |
|
585 |
# the oldfashioned way. |
|
586 |
if ($::form->{prefer_exact}) { |
|
587 |
my $exact_matches; |
|
588 |
if (1 == scalar @{ $exact_matches = $manager->get_all( |
|
589 |
query => [ |
|
590 |
obsolete => 0, |
|
591 |
or => [ |
|
592 |
name => { ilike => $::form->{filter}{'all:substr:multi::ilike'} }, |
|
593 |
$number => { ilike => $::form->{filter}{'all:substr:multi::ilike'} }, |
|
594 |
] |
|
595 |
], |
|
596 |
limit => 2, |
|
597 |
) }) { |
|
598 |
$matches = $exact_matches; |
|
599 |
} |
|
600 |
} |
|
556 | 601 |
|
557 |
my $customers = SL::DB::Manager::Customer->get_all(query => [ @filter ], limit => $limit); |
|
558 |
my $value_col = $::form->{column} || 'name'; |
|
602 |
$matches //= $model->get; |
|
603 |
|
|
604 |
my @hashes = map { |
|
605 |
+{ |
|
606 |
value => $_->name, |
|
607 |
label => $_->displayable_name, |
|
608 |
id => $_->id, |
|
609 |
$number => $_->$number, |
|
610 |
name => $_->name, |
|
611 |
type => $::form->{type}, |
|
612 |
cvars => { map { ($_->config->name => { value => $_->value_as_text, is_valid => $_->is_valid }) } @{ $_->cvars_by_config } }, |
|
613 |
} |
|
614 |
} @{ $matches }; |
|
559 | 615 |
|
560 |
my $data = [ |
|
561 |
map( |
|
562 |
{ |
|
563 |
{ |
|
564 |
value => $_->can($value_col)->($_), |
|
565 |
label => $_->displayable_name, |
|
566 |
id => $_->id, |
|
567 |
customernumber => $_->customernumber, |
|
568 |
name => $_->name, |
|
569 |
} |
|
570 |
} |
|
571 |
@{$customers} |
|
572 |
) |
|
573 |
]; |
|
616 |
$self->render(\ SL::JSON::to_json(\@hashes), { layout => 0, type => 'json', process => 0 }); |
|
617 |
} |
|
574 | 618 |
|
575 |
$self->render(\SL::JSON::to_json($data), { layout => 0, type => 'json' }); |
|
619 |
sub action_test_page { |
|
620 |
$::request->{layout}->add_javascripts('autocomplete_customer.js'); |
|
621 |
$_[0]->render('customer_vendor/test_page'); |
|
576 | 622 |
} |
577 | 623 |
|
578 | 624 |
sub is_vendor { |
... | ... | |
892 | 938 |
return $address; |
893 | 939 |
} |
894 | 940 |
|
941 |
sub init_customer_models { |
|
942 |
my ($self) = @_; |
|
943 |
|
|
944 |
SL::Controller::Helper::GetModels->new( |
|
945 |
controller => $self, |
|
946 |
model => 'Customer', |
|
947 |
sorted => { |
|
948 |
_default => { |
|
949 |
by => 'name', |
|
950 |
dir => 1, |
|
951 |
}, |
|
952 |
name => t8('name'), |
|
953 |
}, |
|
954 |
); |
|
955 |
} |
|
956 |
|
|
957 |
sub init_vendor_models { |
|
958 |
my ($self) = @_; |
|
959 |
|
|
960 |
SL::Controller::Helper::GetModels->new( |
|
961 |
controller => $self, |
|
962 |
model => 'Vendor', |
|
963 |
sorted => { |
|
964 |
_default => { |
|
965 |
by => 'name', |
|
966 |
dir => 1, |
|
967 |
}, |
|
968 |
name => t8('name'), |
|
969 |
}, |
|
970 |
); |
|
971 |
} |
|
972 |
|
|
895 | 973 |
1; |
SL/DB/Customer.pm | ||
---|---|---|
2 | 2 |
|
3 | 3 |
use strict; |
4 | 4 |
|
5 |
use Rose::DB::Object::Helpers qw(as_tree); |
|
6 |
|
|
5 | 7 |
use SL::DB::MetaSetup::Customer; |
6 | 8 |
use SL::DB::Manager::Customer; |
7 | 9 |
use SL::DB::Helper::TransNumberGenerator; |
SL/DB/Manager/Customer.pm | ||
---|---|---|
3 | 3 |
use strict; |
4 | 4 |
|
5 | 5 |
use SL::DB::Helper::Manager; |
6 |
use base qw(SL::DB::Helper::Manager); |
|
7 |
|
|
8 | 6 |
use SL::DB::Helper::Sorted; |
7 |
use SL::DB::Helper::Paginated; |
|
8 |
use SL::DB::Helper::Filtered; |
|
9 |
use base qw(SL::DB::Helper::Manager); |
|
9 | 10 |
|
10 | 11 |
sub object_class { 'SL::DB::Customer' } |
11 | 12 |
|
12 | 13 |
__PACKAGE__->make_manager_methods; |
13 | 14 |
|
15 |
__PACKAGE__->add_filter_specs( |
|
16 |
all => sub { |
|
17 |
my ($key, $value, $prefix) = @_; |
|
18 |
return or => [ map { $prefix . $_ => $value } qw(customernumber name) ] |
|
19 |
} |
|
20 |
); |
|
21 |
|
|
14 | 22 |
sub _sort_spec { |
15 | 23 |
return ( default => [ 'name', 1 ], |
16 | 24 |
columns => { SIMPLE => 'ALL', |
SL/DB/Manager/Vendor.pm | ||
---|---|---|
3 | 3 |
use strict; |
4 | 4 |
|
5 | 5 |
use SL::DB::Helper::Manager; |
6 |
use base qw(SL::DB::Helper::Manager); |
|
7 |
|
|
8 |
use SL::DB::Helper::Filtered; |
|
9 | 6 |
use SL::DB::Helper::Sorted; |
7 |
use SL::DB::Helper::Paginated; |
|
8 |
use SL::DB::Helper::Filtered; |
|
9 |
use base qw(SL::DB::Helper::Manager); |
|
10 | 10 |
|
11 | 11 |
sub object_class { 'SL::DB::Vendor' } |
12 | 12 |
|
SL/DB/Vendor.pm | ||
---|---|---|
2 | 2 |
|
3 | 3 |
use strict; |
4 | 4 |
|
5 |
use Rose::DB::Object::Helpers qw(as_tree); |
|
6 |
|
|
5 | 7 |
use SL::DB::MetaSetup::Vendor; |
6 | 8 |
use SL::DB::Manager::Vendor; |
7 | 9 |
use SL::DB::Helper::TransNumberGenerator; |
SL/Presenter/CustomerVendor.pm | ||
---|---|---|
5 | 5 |
use parent qw(Exporter); |
6 | 6 |
|
7 | 7 |
use Exporter qw(import); |
8 |
our @EXPORT = qw(customer vendor); |
|
8 |
our @EXPORT = qw(customer vendor customer_vendor_picker);
|
|
9 | 9 |
|
10 | 10 |
use Carp; |
11 | 11 |
|
... | ... | |
36 | 36 |
return $self->escaped_text($text); |
37 | 37 |
} |
38 | 38 |
|
39 |
sub customer_vendor_picker { |
|
40 |
my ($self, $name, $value, %params) = @_; |
|
41 |
|
|
42 |
$value = SL::DB::Manager::Customer->find_by(id => $value) if $value && !ref $value; |
|
43 |
my $id = delete($params{id}) || $self->name_to_id($name); |
|
44 |
my $fat_set_item = delete $params{fat_set_item}; |
|
45 |
|
|
46 |
my @classes = $params{class} ? ($params{class}) : (); |
|
47 |
push @classes, 'customer_vendor_autocomplete'; |
|
48 |
push @classes, 'customer-vendor-picker-fat-set-item' if $fat_set_item; |
|
49 |
|
|
50 |
my $ret = |
|
51 |
$self->input_tag($name, (ref $value && $value->can('id') ? $value->id : ''), class => "@classes", type => 'hidden', id => $id) . |
|
52 |
join('', map { $params{$_} ? $self->input_tag("", delete $params{$_}, id => "${id}_${_}", type => 'hidden') : '' } qw(type)) . |
|
53 |
$self->input_tag("", (ref $value && $value->can('name')) ? $value->name : '', id => "${id}_name", %params); |
|
54 |
|
|
55 |
$::request->presenter->need_reinit_widgets($id); |
|
56 |
|
|
57 |
$self->html_tag('span', $ret, class => 'customer_vendor_picker'); |
|
58 |
} |
|
59 |
|
|
39 | 60 |
1; |
40 | 61 |
|
41 | 62 |
__END__ |
SL/Template/Plugin/L.pm | ||
---|---|---|
67 | 67 |
sub truncate { return _call_presenter('truncate', @_); } |
68 | 68 |
sub simple_format { return _call_presenter('simple_format', @_); } |
69 | 69 |
sub part_picker { return _call_presenter('part_picker', @_); } |
70 |
sub customer_vendor_picker { return _call_presenter('customer_vendor_picker', @_); } |
|
70 | 71 |
|
71 | 72 |
sub _set_id_attribute { |
72 | 73 |
my ($attributes, $name, $unique) = @_; |
... | ... | |
241 | 242 |
); |
242 | 243 |
} |
243 | 244 |
|
244 |
sub customer_picker { |
|
245 |
my ($self, $name, $value, %params) = _hashify(3, @_); |
|
246 |
my $name_e = _H($name); |
|
247 |
|
|
248 |
$::request->{layout}->add_javascripts('autocomplete_customer.js'); |
|
249 |
|
|
250 |
$self->hidden_tag($name, (ref $value && $value->can('id') ? $value->id : ''), class => 'customer_autocomplete') . |
|
251 |
$self->input_tag('', (ref $value && $value->can('name')) ? $value->name : '', id => $self->name_to_id("$name_e\_name"), %params); |
|
252 |
} |
|
253 |
|
|
254 | 245 |
# simple version with select_tag |
255 | 246 |
sub vendor_selector { |
256 | 247 |
my ($self, $name, $value, %params) = _hashify(3, @_); |
css/kivitendo/main.css | ||
---|---|---|
404 | 404 |
padding-right: 16px; |
405 | 405 |
} |
406 | 406 |
|
407 |
.customer-vendor-picker-undefined, |
|
407 | 408 |
.partpicker-undefined { |
408 | 409 |
color: red; |
409 | 410 |
font-style: italic; |
css/lx-office-erp/main.css | ||
---|---|---|
455 | 455 |
.part_picker { |
456 | 456 |
padding-right: 16px; |
457 | 457 |
} |
458 |
.customer-vendor-picker-undefined, |
|
458 | 459 |
.partpicker-undefined { |
459 | 460 |
color: red; |
460 | 461 |
font-style: italic; |
js/autocomplete_customer.js | ||
---|---|---|
1 |
$(function(){ |
|
2 |
$('input.customer_autocomplete').each(function(i,real){ |
|
3 |
var dummy = $('#' + real.id + '_name'); |
|
4 |
$(dummy).autocomplete({ |
|
5 |
source: function(req, rsp) { |
|
1 |
namespace('kivi', function(k){ |
|
2 |
k.CustomerVendorPicker = function($real, options) { |
|
3 |
// short circuit in case someone double inits us |
|
4 |
if ($real.data("customer_vendor_picker")) |
|
5 |
return $real.data("customer_vendor_picker"); |
|
6 |
|
|
7 |
var KEY = { |
|
8 |
ESCAPE: 27, |
|
9 |
ENTER: 13, |
|
10 |
TAB: 9, |
|
11 |
LEFT: 37, |
|
12 |
RIGHT: 39, |
|
13 |
PAGE_UP: 33, |
|
14 |
PAGE_DOWN: 34, |
|
15 |
}; |
|
16 |
var CLASSES = { |
|
17 |
PICKED: 'customer-vendor-picker-picked', |
|
18 |
UNDEFINED: 'customer-vendor-picker-undefined', |
|
19 |
FAT_SET_ITEM: 'customer-vendor-picker-fat-set-item', |
|
20 |
} |
|
21 |
var o = $.extend({ |
|
22 |
limit: 20, |
|
23 |
delay: 50, |
|
24 |
fat_set_item: $real.hasClass(CLASSES.FAT_SET_ITEM), |
|
25 |
}, options); |
|
26 |
var STATES = { |
|
27 |
PICKED: CLASSES.PICKED, |
|
28 |
UNDEFINED: CLASSES.UNDEFINED |
|
29 |
} |
|
30 |
var real_id = $real.attr('id'); |
|
31 |
var $dummy = $('#' + real_id + '_name'); |
|
32 |
var $type = $('#' + real_id + '_type'); |
|
33 |
var $unit = $('#' + real_id + '_unit'); |
|
34 |
var state = STATES.PICKED; |
|
35 |
var last_real = $real.val(); |
|
36 |
var last_dummy = $dummy.val(); |
|
37 |
var timer; |
|
38 |
|
|
39 |
function ajax_data(term) { |
|
40 |
var data = { |
|
41 |
'filter.all:substr:multi::ilike': term, |
|
42 |
'filter.obsolete': 0, |
|
43 |
current: $real.val(), |
|
44 |
type: $type.val(), |
|
45 |
}; |
|
46 |
|
|
47 |
return data; |
|
48 |
} |
|
49 |
|
|
50 |
function set_item (item) { |
|
51 |
if (item.id) { |
|
52 |
$real.val(item.id); |
|
53 |
// autocomplete ui has name, ajax items have description |
|
54 |
$dummy.val(item.name ? item.name : item.description); |
|
55 |
} else { |
|
56 |
$real.val(''); |
|
57 |
$dummy.val(''); |
|
58 |
} |
|
59 |
state = STATES.PICKED; |
|
60 |
last_real = $real.val(); |
|
61 |
last_dummy = $dummy.val(); |
|
62 |
last_unverified_dummy = $dummy.val(); |
|
63 |
$real.trigger('change'); |
|
64 |
|
|
65 |
if (o.fat_set_item && item.id) { |
|
6 | 66 |
$.ajax({ |
7 |
url: 'controller.pl?action=CustomerVendor/ajaj_customer_autocomplete', |
|
8 |
dataType: "json", |
|
9 |
data: { |
|
10 |
term: req.term, |
|
11 |
current: function() { real.val }, |
|
12 |
obsolete: 0, |
|
67 |
url: 'controller.pl?action=CustomerVendor/show.json', |
|
68 |
data: { id: item.id, db: item.type }, |
|
69 |
success: function(rsp) { |
|
70 |
$real.trigger('set_item:CustomerVendorPicker', rsp); |
|
13 | 71 |
}, |
14 |
success: function (data){ rsp(data) } |
|
15 | 72 |
}); |
73 |
} else { |
|
74 |
$real.trigger('set_item:CustomerVendorPicker', item); |
|
75 |
} |
|
76 |
annotate_state(); |
|
77 |
} |
|
78 |
|
|
79 |
function make_defined_state () { |
|
80 |
if (state == STATES.PICKED) { |
|
81 |
annotate_state(); |
|
82 |
return true |
|
83 |
} else if (state == STATES.UNDEFINED && $dummy.val() == '') |
|
84 |
set_item({}) |
|
85 |
else { |
|
86 |
last_unverified_dummy = $dummy.val(); |
|
87 |
set_item({ id: last_real, name: last_dummy }) |
|
88 |
} |
|
89 |
annotate_state(); |
|
90 |
} |
|
91 |
|
|
92 |
function annotate_state () { |
|
93 |
if (state == STATES.PICKED) |
|
94 |
$dummy.removeClass(STATES.UNDEFINED).addClass(STATES.PICKED); |
|
95 |
else if (state == STATES.UNDEFINED && $dummy.val() == '') |
|
96 |
$dummy.removeClass(STATES.UNDEFINED).addClass(STATES.PICKED); |
|
97 |
else { |
|
98 |
last_unverified_dummy = $dummy.val(); |
|
99 |
$dummy.addClass(STATES.UNDEFINED).removeClass(STATES.PICKED); |
|
100 |
} |
|
101 |
} |
|
102 |
|
|
103 |
$dummy.autocomplete({ |
|
104 |
source: function(req, rsp) { |
|
105 |
$.ajax($.extend(o, { |
|
106 |
url: 'controller.pl?action=CustomerVendor/ajaj_autocomplete', |
|
107 |
dataType: "json", |
|
108 |
data: ajax_data(req.term), |
|
109 |
success: function (data){ rsp(data) } |
|
110 |
})); |
|
16 | 111 |
}, |
17 |
limit: 20, |
|
18 |
delay: 50, |
|
19 | 112 |
select: function(event, ui) { |
20 |
$(real).val(ui.item.id); |
|
21 |
$(dummy).val(ui.item.name); |
|
113 |
set_item(ui.item); |
|
22 | 114 |
}, |
23 | 115 |
}); |
24 |
}); |
|
116 |
/* In case users are impatient and want to skip ahead: |
|
117 |
* Capture <enter> key events and check if it's a unique hit. |
|
118 |
* If it is, go ahead and assume it was selected. If it wasn't don't do |
|
119 |
* anything so that autocompletion kicks in. For <tab> don't prevent |
|
120 |
* propagation. It would be nice to catch it, but javascript is too stupid |
|
121 |
* to fire a tab event later on, so we'd have to reimplement the "find |
|
122 |
* next active element in tabindex order and focus it". |
|
123 |
*/ |
|
124 |
/* note: |
|
125 |
* event.which does not contain tab events in keypressed in firefox but will report 0 |
|
126 |
* chrome does not fire keypressed at all on tab or escape |
|
127 |
*/ |
|
128 |
$dummy.keydown(function(event){ |
|
129 |
if (event.which == KEY.ENTER || event.which == KEY.TAB) { |
|
130 |
// if string is empty assume they want to delete |
|
131 |
if ($dummy.val() == '') { |
|
132 |
set_item({}); |
|
133 |
return true; |
|
134 |
} else if (state == STATES.PICKED) { |
|
135 |
return true; |
|
136 |
} |
|
137 |
if (event.which == KEY.TAB) event.preventDefault(); |
|
138 |
$.ajax({ |
|
139 |
url: 'controller.pl?action=CustomerVendor/ajaj_autocomplete', |
|
140 |
dataType: "json", |
|
141 |
data: $.extend( ajax_data($dummy.val()), { prefer_exact: 1 } ), |
|
142 |
success: function (data) { |
|
143 |
if (data.length == 1) { |
|
144 |
set_item(data[0]); |
|
145 |
if (event.which == KEY.ENTER) |
|
146 |
$('#update_button').click(); |
|
147 |
} else { |
|
148 |
} |
|
149 |
annotate_state(); |
|
150 |
} |
|
151 |
}); |
|
152 |
if (event.which == KEY.ENTER) |
|
153 |
return false; |
|
154 |
} else { |
|
155 |
state = STATES.UNDEFINED; |
|
156 |
} |
|
157 |
}); |
|
158 |
|
|
159 |
$dummy.blur(function(){ |
|
160 |
window.clearTimeout(timer); |
|
161 |
timer = window.setTimeout(annotate_state, 100); |
|
162 |
}); |
|
163 |
|
|
164 |
// now add a picker div after the original input |
|
165 |
var pp = { |
|
166 |
real: function() { return $real }, |
|
167 |
dummy: function() { return $dummy }, |
|
168 |
type: function() { return $type }, |
|
169 |
set_item: set_item, |
|
170 |
reset: make_defined_state, |
|
171 |
is_defined_state: function() { return state == STATES.PICKED }, |
|
172 |
} |
|
173 |
$real.data('customer_vendor_picker', pp); |
|
174 |
return pp; |
|
175 |
} |
|
176 |
}); |
|
177 |
|
|
178 |
$(function(){ |
|
179 |
$('input.customer_vendor_autocomplete').each(function(i,real){ |
|
180 |
kivi.CustomerVendorPicker($(real)); |
|
181 |
}) |
|
25 | 182 |
}); |
js/kivi.js | ||
---|---|---|
127 | 127 |
kivi.PartPicker($(elt)); |
128 | 128 |
}); |
129 | 129 |
|
130 |
if (ns.CustomerVendorPicker) |
|
131 |
ns.run_once_for('input.customer_vendor_autocomplete', 'customer_vendor_picker', function(elt) { |
|
132 |
kivi.CustomerVendorPicker($(elt)); |
|
133 |
}); |
|
134 |
|
|
130 | 135 |
var func = kivi.get_function_by_name('local_reinit_widgets'); |
131 | 136 |
if (func) |
132 | 137 |
func(); |
templates/webpages/customer_vendor/test_page.html | ||
---|---|---|
1 |
[% USE L %] |
|
2 |
|
|
3 |
<h1>Customer Vendor Autocomplete Testpage</h1> |
|
4 |
|
|
5 |
<br> |
|
6 |
Customer: with preselected id 822<br> |
|
7 |
[% L.customer_vendor_picker('customer_id', 822, type='customer') %]<br> |
|
8 |
|
|
9 |
<br><hr> |
|
10 |
Vendor: <br> |
|
11 |
[% L.customer_vendor_picker('vendor_id', '', type='vendor') %]<br> |
|
12 |
|
|
13 |
<br><hr> |
|
14 |
customer with fat change<br> |
|
15 |
[% L.customer_vendor_picker('customer_id2', '', type='customer', fat_set_item=1) %]<br> |
|
16 |
<div>id from change <span id='change1'></span></div> |
|
17 |
<div>greeting from fat change <span id='change2'></span></div> |
|
18 |
|
|
19 |
<br><hr> |
|
20 |
fat vendor with change<br> |
|
21 |
[% L.customer_vendor_picker('vendor_id2', '', type='vendor', fat_set_item=1) %]<br> |
|
22 |
<div>id from change<span id='change3'></span></div> |
|
23 |
<div>greeting from fat change <span id='change4'></span></div> |
|
24 |
|
|
25 |
<br><hr> |
|
26 |
this one will be 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"> |
|
30 |
<input id="vendor3_id_name" type="text" name="" value=""> |
|
31 |
</span> |
|
32 |
|
|
33 |
<br><hr> |
|
34 |
this shouold have three '-' before and after touching:<br> |
|
35 |
---[% L.customer_vendor_picker('vendor5_id', '', type='vendor') %]--- |
|
36 |
|
|
37 |
|
|
38 |
<script type='text/javascript'> |
|
39 |
$('#customer_id2').change(function() { $('#change1').html($('#customer_id2').val()) }) |
|
40 |
$('#customer_id2').on('set_item:CustomerVendorPicker', function(e,o) { $('#change2').html(o.greeting) }) |
|
41 |
|
|
42 |
$('#vendor_id2').change(function() { $('#change3').html($('#vendor_id2').val()) }) |
|
43 |
$('#vendor_id2').on('set_item:CustomerVendorPicker', function(e,o) { $('#change4').html(o.greeting) }) |
|
44 |
|
|
45 |
window.setTimeout(function() { |
|
46 |
console.log("adding last one now!"); |
|
47 |
$('#vendor3_id').addClass('customer_vendor_autocomplete'); |
|
48 |
$('#vendor3').addClass('customer_vendor_picker'); |
|
49 |
kivi.reinit_widgets(); |
|
50 |
}, 4000); |
|
51 |
</script> |
|
52 |
|
Auch abrufbar als: Unified diff
CustomerVendor: Picker nach Art von PartPicker
- reinit_widgets fähig
- Tab und Enter atomar
- unterstützt onChange und set_item:CustomerVendorPicker trigger
- unterstützt fat_set_item