Revision 7a646681
Von Sven Schöling vor mehr als 11 Jahren hinzugefügt
SL/Controller/Part.pm | ||
---|---|---|
11 | 11 |
use SL::Controller::Helper::Paginated; |
12 | 12 |
use SL::Controller::Helper::Filtered; |
13 | 13 |
use SL::Locale::String qw(t8); |
14 |
use SL::JSON; |
|
14 | 15 |
|
15 | 16 |
use Rose::Object::MakeMethods::Generic ( |
16 | 17 |
'scalar --get_set_init' => [ qw(parts) ], |
... | ... | |
20 | 21 |
__PACKAGE__->run_before(sub { $::auth->assert('part_service_assembly_edit') }); |
21 | 22 |
|
22 | 23 |
__PACKAGE__->make_filtered( |
23 |
ONLY => [ qw(part_picker_search part_picker_result) ], |
|
24 |
ONLY => [ qw(part_picker_search part_picker_result ajax_autocomplete) ],
|
|
24 | 25 |
LAUNDER_TO => 'filter', |
25 | 26 |
); |
26 | 27 |
__PACKAGE__->make_paginated( |
27 |
ONLY => [ qw(part_picker_search part_picker_result) ], |
|
28 |
ONLY => [ qw(part_picker_search part_picker_result ajax_autocomplete) ],
|
|
28 | 29 |
); |
29 | 30 |
|
30 | 31 |
__PACKAGE__->make_sorted( |
31 |
ONLY => [ qw(part_picker_search part_picker_result) ], |
|
32 |
ONLY => [ qw(part_picker_search part_picker_result ajax_autocomplete) ],
|
|
32 | 33 |
|
33 | 34 |
DEFAULT_BY => 'partnumber', |
34 | 35 |
DEFAULT_DIR => 1, |
... | ... | |
39 | 40 |
sub action_ajax_autocomplete { |
40 | 41 |
my ($self, %params) = @_; |
41 | 42 |
|
42 |
my $limit = $::form->{limit} || 20; |
|
43 |
my $type = $::form->{type} || {}; |
|
44 |
my $query = { ilike => "%$::form->{term}%" }; |
|
45 |
my @filter; |
|
46 |
push @filter, SL::DB::Manager::Part->type_filter($type); |
|
47 |
push @filter, ($::form->{column}) |
|
48 |
? ($::form->{column} => $query) |
|
49 |
: (or => [ partnumber => $query, description => $query ]); |
|
50 |
|
|
51 |
$self->{parts} = SL::DB::Manager::Part->get_all(query => [ @filter ], limit => $limit); |
|
52 |
$self->{value} = $::form->{column} || 'description'; |
|
43 |
my $value = $::form->{column} || 'description'; |
|
53 | 44 |
|
54 | 45 |
# if someone types something, and hits enter, assume he entered the full name. |
55 | 46 |
# if something matches, treat that as sole match |
56 | 47 |
if ($::form->{prefer_exact}) { |
57 |
for my $part (@{ $self->{parts} }) { |
|
58 |
if ( lc $part->description eq lc $::form->{term} |
|
59 |
|| lc $part->partnumber eq lc $::form->{term}) { |
|
60 |
$self->{parts} = [ $part ]; |
|
61 |
last; |
|
62 |
} |
|
63 |
} |
|
48 |
# TODO! |
|
64 | 49 |
} |
65 | 50 |
|
66 |
$self->render('part/ajax_autocomplete', { layout => 0, type => 'json' }); |
|
51 |
my @hashes = map { |
|
52 |
+{ |
|
53 |
value => $_->$value, |
|
54 |
label => $_->long_description, |
|
55 |
id => $_->id, |
|
56 |
partnumber => $_->partnumber, |
|
57 |
description => $_->description, |
|
58 |
type => $_->type, |
|
59 |
} |
|
60 |
} @{ $self->parts }; |
|
61 |
|
|
62 |
$self->render(\ SL::JSON::to_json(\@hashes), { layout => 0, type => 'json', process => 0 }); |
|
67 | 63 |
} |
68 | 64 |
|
69 | 65 |
sub action_test_page { |
SL/DB/Part.pm | ||
---|---|---|
179 | 179 |
return $charts->{$taxzone}->{$type}; |
180 | 180 |
} |
181 | 181 |
|
182 |
sub long_description { |
|
183 |
join ' ', grep $_, map $_[0]->$_, qw(partnumber description); |
|
184 |
} |
|
185 |
|
|
182 | 186 |
1; |
183 | 187 |
|
184 | 188 |
__END__ |
SL/Presenter/Part.pm | ||
---|---|---|
51 | 51 |
|
52 | 52 |
If C<PARAMS> contains C<type> only parts of this type will be used for autocompletion. |
53 | 53 |
|
54 |
Obsolete parts will by default not displayed for selection. However they are |
|
55 |
accepted as default values and can persist during updates. |
|
54 | 56 |
|
55 | 57 |
=back |
56 | 58 |
|
js/autocomplete_part.js | ||
---|---|---|
18 | 18 |
var last_dummy = $dummy.val(); |
19 | 19 |
var open_dialog = function(){ |
20 | 20 |
open_jqm_window({ |
21 |
url: 'controller.pl', |
|
22 |
data: { |
|
23 |
action: 'Part/part_picker_search', |
|
21 |
url: 'controller.pl?action=Part/part_picker_search', |
|
22 |
data: $.extend({ |
|
24 | 23 |
real_id: real_id, |
25 |
'filter.all:substr::ilike': function(){ return $dummy.val() }, |
|
26 |
'filter.type': function(){ return $type.val() }, |
|
27 |
'column': function(){ return $column.val() }, |
|
28 |
}, |
|
24 |
}, ajax_data($dummy.val())), |
|
29 | 25 |
id: 'part_selection', |
30 | 26 |
}); |
31 | 27 |
return true; |
... | ... | |
33 | 29 |
|
34 | 30 |
function ajax_data(term) { |
35 | 31 |
return { |
36 |
term: term, |
|
37 |
type: function() { return $type.val() }, |
|
32 |
'filter.all:substr::ilike': term, |
|
33 |
'filter.type': function() { return $type.val() }, |
|
34 |
'filter.obsolete': 0, |
|
38 | 35 |
column: function() { return $column.val()===undefined ? '' : $column.val() }, |
39 | 36 |
current: function() { return $real.val() }, |
40 |
obsolete: 0, |
|
41 | 37 |
} |
42 | 38 |
} |
43 | 39 |
|
... | ... | |
68 | 64 |
function update_results () { |
69 | 65 |
$.ajax({ |
70 | 66 |
url: 'controller.pl?action=Part/part_picker_result', |
71 |
data: { |
|
72 |
'filter.all:substr::ilike': function(){ var val = $('#part_picker_filter').val(); return val === undefined ? '' : val }, |
|
73 |
'filter.type': $type.val(), |
|
74 |
'column': $column.val(), |
|
75 |
'real_id': $real.val, |
|
76 |
}, |
|
67 |
data: $.extend({ |
|
68 |
'real_id': $real.val(), |
|
69 |
}, ajax_data(function(){ var val = $('#part_picker_filter').val(); return val === undefined ? '' : val })), |
|
77 | 70 |
success: function(data){ $('#part_picker_result').html(data) } |
78 | 71 |
}); |
79 | 72 |
}; |
templates/webpages/part/ajax_autocomplete.json | ||
---|---|---|
1 |
[%- USE HTML %][% USE JSON %][ |
|
2 |
[%- FOREACH part = SELF.parts %] |
|
3 |
[%- ajax_autocomplete__label = part.partnumber _ " " _ part.description %] |
|
4 |
{ |
|
5 |
"value": [% part.${SELF.value}.json %], |
|
6 |
"label": [% ajax_autocomplete__label.json %], |
|
7 |
"id": [% part.id.json %], |
|
8 |
"partnumber": [% part.partnumber.json %], |
|
9 |
"description": [% part.description.json %], |
|
10 |
"type": [% part.type.json %] |
|
11 |
}[% ',' UNLESS loop.last %] |
|
12 |
[%- END %] |
|
13 |
] |
Auch abrufbar als: Unified diff
ajax_autocomplete umgestellt auf get_models und inline JSON (20% schneller als template)