Commit 94ab17161a07f638d10b8ba68a0dc98049d1b789
1 parent
f5007024
slickgrid: wstępnie działające filtrowanie
Showing
8 changed files
with
288 additions
and
178 deletions
dictionary/ajax_lexeme_slickgrid.py
... | ... | @@ -19,23 +19,26 @@ class LexemeGrid(SlickGridAjax): |
19 | 19 | 'part_of_speech': 'part_of_speech__symbol', |
20 | 20 | } |
21 | 21 | |
22 | - @staticmethod | |
23 | - def sort_field_special_case(rule): | |
22 | + @classmethod | |
23 | + def get_sort_field(cls, rule): | |
24 | + new_rule = dict(rule) | |
24 | 25 | if rule['field'] == 'entry' and rule['a_tergo']: |
25 | - return 'rev' | |
26 | - else: | |
27 | - return rule['field'] | |
26 | + new_rule['field'] = 'rev' | |
27 | + return super(LexemeGrid, cls).get_sort_field(new_rule) | |
28 | 28 | |
29 | - @staticmethod | |
30 | - def sort_queryset_special_case(queryset, rule): | |
31 | - if rule['field'] == 'entry' and rule['a_tergo']: | |
32 | - return queryset.extra(select={'rev': "reverse(haslo)"}) | |
33 | - else: | |
34 | - return queryset | |
29 | + @classmethod | |
30 | + def sort_queryset(cls, queryset, sort_rules): | |
31 | + for rule in sort_rules: | |
32 | + if rule['field'] == 'entry' and rule['a_tergo']: | |
33 | + queryset = queryset.extra(select={'rev': "reverse(haslo)"}) | |
34 | + return super(LexemeGrid, cls).sort_queryset(queryset, sort_rules) | |
35 | 35 | |
36 | - @staticmethod | |
37 | - def filter_special_case(filter, lookup, negated, queryset): | |
36 | + @classmethod | |
37 | + def apply_filter(cls, queryset, filter): | |
38 | + lookup = cls.lookup_translation[filter['op']] | |
39 | + negated = (lookup[0] == '-') | |
38 | 40 | field, data = filter['field'], filter['data'] |
41 | + new_filter = dict(filter) | |
39 | 42 | special = False |
40 | 43 | field_translation = { |
41 | 44 | 'form': 'lexemeform__form', |
... | ... | @@ -60,30 +63,34 @@ class LexemeGrid(SlickGridAjax): |
60 | 63 | distinct=True)) |
61 | 64 | elif field == 'qualifier': |
62 | 65 | where = '''( |
63 | - exists ( | |
64 | - select * from kwalifikatory_leksemow where lexeme_id = leksemy.id and | |
65 | - qualifier_id = %s) or | |
66 | - exists ( | |
67 | - select * from kwalifikatory_odmieniasiow join odmieniasie o on | |
68 | - lexemeinflectionpattern_id = o.id | |
69 | - where | |
70 | - qualifier_id = %s and o.l_id = leksemy.id) or | |
71 | - exists ( | |
72 | - select * from | |
73 | - odmieniasie o | |
74 | - join wzory w on (o.w_id = w.id) | |
75 | - join szablony_tabel s on (w.typ = s.wtyp and o.charfl = s.charfl) | |
76 | - join klatki k on k.st_id = s.id | |
77 | - join zakonczenia z on (o.w_id = z.w_id and k.efobaz = z.efobaz) | |
78 | - join kwalifikatory_zakonczen kz on (z.id = kz.ending_id) | |
79 | - where o.l_id = leksemy.id and s.wariant = '1' and | |
80 | - kz.qualifier_id = %s) | |
81 | - )''' | |
66 | + exists ( | |
67 | + select * from kwalifikatory_leksemow where lexeme_id = leksemy.id and | |
68 | + qualifier_id = %s) or | |
69 | + exists ( | |
70 | + select * from kwalifikatory_odmieniasiow join odmieniasie o on | |
71 | + lexemeinflectionpattern_id = o.id | |
72 | + where | |
73 | + qualifier_id = %s and o.l_id = leksemy.id) or | |
74 | + exists ( | |
75 | + select * from | |
76 | + odmieniasie o | |
77 | + join wzory w on (o.w_id = w.id) | |
78 | + join szablony_tabel s on (w.typ = s.wtyp and o.charfl = s.charfl) | |
79 | + join klatki k on k.st_id = s.id | |
80 | + join zakonczenia z on (o.w_id = z.w_id and k.efobaz = z.efobaz) | |
81 | + join kwalifikatory_zakonczen kz on (z.id = kz.ending_id) | |
82 | + where o.l_id = leksemy.id and s.wariant = '1' and | |
83 | + kz.qualifier_id = %s) | |
84 | + )''' | |
82 | 85 | if negated: |
83 | 86 | where = 'not ' + where |
84 | 87 | queryset = queryset.extra(where=[where], params=[data] * 3) |
85 | 88 | special = True |
86 | - return special, field_translation.get(field, field), queryset | |
89 | + if not special: | |
90 | + new_filter['field'] = field_translation.get(field, field) | |
91 | + return super(LexemeGrid, cls).apply_filter(queryset, new_filter) | |
92 | + else: | |
93 | + return queryset | |
87 | 94 | |
88 | 95 | @classmethod |
89 | 96 | def get_queryset(cls, query): |
... | ... | @@ -105,25 +112,19 @@ class LexemeGrid(SlickGridAjax): |
105 | 112 | matching_lexemes = lexemes.filter(entry__istartswith=mask) |
106 | 113 | return matching_lexemes |
107 | 114 | |
108 | - @staticmethod | |
109 | - def filter_value_special_case(queryset, rule, from_value, greater): | |
115 | + @classmethod | |
116 | + def filter_value(cls, queryset, rule, from_value, upward): | |
117 | + greater = (rule['order'] == 'asc') == upward | |
110 | 118 | if rule['field'] == 'entry' and rule['a_tergo']: |
111 | 119 | if greater: |
112 | 120 | comp = '>=' |
113 | 121 | else: |
114 | 122 | comp = '<=' |
115 | - queryset = queryset.extra(where=["reverse(haslo) " + comp + " %s"], | |
123 | + return queryset.extra(where=["reverse(haslo) " + comp + " %s"], | |
116 | 124 | params=[reverse(from_value)]) |
117 | - return True, queryset | |
118 | 125 | else: |
119 | - return False, queryset | |
120 | - | |
121 | - @staticmethod | |
122 | - def get_field_special_case(field, lexeme): | |
123 | - if field == 'part_of_speech': | |
124 | - return True, lexeme.part_of_speech.symbol | |
125 | - else: | |
126 | - return False, None | |
126 | + return super(LexemeGrid, cls).filter_value( | |
127 | + queryset, rule, from_value, upward) | |
127 | 128 | |
128 | 129 | @staticmethod |
129 | 130 | def response_row(lexeme): |
... | ... | @@ -185,7 +186,11 @@ def make_lexeme_cmp(rule): |
185 | 186 | def find_id(request, id, sort_rules, mask, filters=None): |
186 | 187 | query = SlickGridQuery( |
187 | 188 | filters=filters, sort_rules=sort_rules, mask=mask, user=request.user) |
188 | - return LexemeGrid.find_id(id, query) | |
189 | + index, count = LexemeGrid.row_index(id, query) | |
190 | + return { | |
191 | + 'index': index, | |
192 | + 'count': count, | |
193 | + } | |
189 | 194 | |
190 | 195 | @ajax(method='get') |
191 | 196 | def search_index(request, sort_rules, search='', filters=None): |
... | ... | @@ -228,7 +233,6 @@ def get_id_list(query, force_reload=False): |
228 | 233 | if 'rev' in lexemes.query.extra_select: |
229 | 234 | id_list = list(row[0] for row in lexemes.values_list('id', 'rev')) |
230 | 235 | else: |
231 | - #print lexemes.values_list('pk', flat=True).query | |
232 | 236 | id_list = list(lexemes.values_list('id', flat=True)) |
233 | 237 | cache_lexemes(id_list, query) |
234 | 238 | return id_list |
... | ... | @@ -237,6 +241,7 @@ def get_id_list(query, force_reload=False): |
237 | 241 | @ajax(method='get') |
238 | 242 | def get_lexemes(request, from_page, to_page, rows, sort_rules, filters=None, |
239 | 243 | mask='', force_reload=False): |
244 | + # TODO na koniec | |
240 | 245 | #request.session['sort_rules'] = json_encode(sort_rules) |
241 | 246 | #request.session['filters'] = json_encode(filters) |
242 | 247 | query = SlickGridQuery( |
... | ... |
dictionary/ajax_slickgrid.py
1 | 1 | #-*- coding:utf-8 -*- |
2 | 2 | |
3 | -import math | |
4 | 3 | from accounts.models import filtering_mode |
5 | 4 | |
6 | - | |
5 | +# TODO jedna klasa zamiast dwóch | |
7 | 6 | class SlickGridQuery(object): |
8 | 7 | def __init__(self, filters, sort_rules, mask, user): |
9 | 8 | self.filters = filters |
... | ... | @@ -27,27 +26,17 @@ class SlickGridAjax(object): |
27 | 26 | else: |
28 | 27 | return field |
29 | 28 | |
30 | - @staticmethod | |
31 | - def sort_field_special_case(rule): | |
32 | - return rule['field'] | |
33 | - | |
34 | 29 | @classmethod |
35 | 30 | def get_sort_field(cls, rule): |
36 | - field = cls.sort_field_special_case(rule) | |
37 | - field = cls.translate_field(field) | |
31 | + field = cls.translate_field(rule['field']) | |
38 | 32 | if rule['order'] == 'desc': |
39 | 33 | field = '-' + field |
40 | 34 | return field |
41 | 35 | |
42 | - @staticmethod | |
43 | - def sort_queryset_special_case(queryset, field): | |
44 | - return queryset | |
45 | - | |
46 | 36 | @classmethod |
47 | 37 | def sort_queryset(cls, queryset, sort_rules): |
48 | 38 | order_list = [] |
49 | 39 | for rule in sort_rules: |
50 | - queryset = cls.sort_queryset_special_case(queryset, rule) | |
51 | 40 | order_list.append(cls.get_sort_field(rule)) |
52 | 41 | return queryset.extra(order_by=order_list) |
53 | 42 | |
... | ... | @@ -62,32 +51,21 @@ class SlickGridAjax(object): |
62 | 51 | 'nc': '-contains', |
63 | 52 | 're': 'regex', |
64 | 53 | 'nr': '-regex', |
65 | - #'se': 'surely', | |
66 | - #'sd': '-maybe', | |
67 | - #'me': 'maybe', | |
68 | - #'md': '-surely', | |
69 | 54 | 'le': 'lte', |
70 | 55 | 'ge': 'gte', |
71 | 56 | } |
72 | 57 | |
73 | - @staticmethod | |
74 | - def filter_special_case(filter, lookup, negated, queryset): | |
75 | - return False, filter['field'], queryset | |
76 | - | |
77 | 58 | @classmethod |
78 | 59 | def apply_filter(cls, queryset, filter): |
79 | 60 | lookup = cls.lookup_translation[filter['op']] |
80 | 61 | negated = (lookup[0] == '-') |
81 | 62 | lookup = lookup.lstrip('-') |
82 | 63 | data = filter['data'] |
83 | - special, field, queryset = cls.filter_special_case( | |
84 | - filter, lookup, negated, queryset) | |
85 | - if not special: | |
86 | - arg = {(field + '__' + lookup): data} | |
87 | - if negated: | |
88 | - queryset = queryset.exclude(**arg) | |
89 | - else: | |
90 | - queryset = queryset.filter(**arg).distinct() | |
64 | + arg = {(filter['field'] + '__' + lookup): data} | |
65 | + if negated: | |
66 | + queryset = queryset.exclude(**arg) | |
67 | + else: | |
68 | + queryset = queryset.filter(**arg).distinct() | |
91 | 69 | return queryset |
92 | 70 | |
93 | 71 | @classmethod |
... | ... | @@ -103,10 +81,10 @@ class SlickGridAjax(object): |
103 | 81 | filters = query.filters |
104 | 82 | queryset = cls.get_queryset(query) |
105 | 83 | if filters: |
106 | - if filters['groupOp'] == 'AND': | |
84 | + if filters['group_op'] == 'AND': | |
107 | 85 | for filter in filters['rules']: |
108 | 86 | queryset = cls.apply_filter(queryset, filter) |
109 | - elif filters['groupOp'] == 'OR': | |
87 | + elif filters['group_op'] == 'OR': | |
110 | 88 | new_queryset = cls.get_empty_queryset() |
111 | 89 | for filter in filters['rules']: |
112 | 90 | new_queryset |= cls.apply_filter(queryset, filter) |
... | ... | @@ -117,19 +95,11 @@ class SlickGridAjax(object): |
117 | 95 | def apply_mask(queryset, mask, sort_rules): |
118 | 96 | pass # abstract |
119 | 97 | |
120 | - @staticmethod | |
121 | - def filter_value_special_case(queryset, rule, from_value, upward): | |
122 | - return False, queryset | |
123 | - | |
124 | 98 | # filtruje queryset według pola z reguły rule od wartości from, |
125 | 99 | # wartości dalsze w porządku jeśli upward, w przeciwnym razie bliższe |
126 | 100 | @classmethod |
127 | 101 | def filter_value(cls, queryset, rule, from_value, upward): |
128 | 102 | greater = (rule['order'] == 'asc') == upward |
129 | - special, queryset = cls.filter_value_special_case( | |
130 | - queryset, rule, from_value, upward) | |
131 | - if special: | |
132 | - return queryset | |
133 | 103 | if greater: |
134 | 104 | lookup = '__gte' |
135 | 105 | else: |
... | ... | @@ -162,16 +132,9 @@ class SlickGridAjax(object): |
162 | 132 | queryset = cls.sort_queryset(queryset, query.sort_rules) |
163 | 133 | return queryset[0].pk |
164 | 134 | |
165 | - @staticmethod | |
166 | - def get_field_special_case(field, instance): | |
167 | - return False, None | |
168 | - | |
169 | 135 | @classmethod |
170 | 136 | def get_field(cls, field, instance): |
171 | - special, value = cls.get_field_special_case(field, instance) | |
172 | - if not special: | |
173 | - value = getattr(instance, field) | |
174 | - return cls.translate_field(field), value | |
137 | + return getattr(instance, field) | |
175 | 138 | |
176 | 139 | # indeks wiersza w danym sortowaniu, w którym |
177 | 140 | # znajdzie się instancja o danym id |
... | ... | @@ -181,26 +144,15 @@ class SlickGridAjax(object): |
181 | 144 | queryset = cls.apply_filters(query) |
182 | 145 | if query.filtering_mode(): |
183 | 146 | queryset = cls.apply_mask(queryset, query.mask, query.sort_rules) |
184 | - count = queryset.count() | |
185 | - if count == 0: | |
147 | + if queryset.count() == 0: | |
186 | 148 | return 0, 0 |
187 | 149 | preceding = None |
188 | 150 | assert len(query.sort_rules) > 0 |
189 | 151 | for rule in query.sort_rules: |
190 | - field = rule['field'] | |
191 | - field, data = cls.get_field(field, selected) | |
152 | + data = cls.get_field(rule['field'], selected) | |
192 | 153 | preceding = cls.filter_value( |
193 | 154 | queryset, rule, from_value=data, upward=False) |
194 | - return preceding.count(), count | |
195 | - | |
196 | - # też beznadziejna nazwa | |
197 | - @classmethod | |
198 | - def find_id(cls, selected_pk, query): | |
199 | - index, count = cls.row_index(selected_pk, query) | |
200 | - return { | |
201 | - 'rowIndex': index, | |
202 | - 'records': count, | |
203 | - } | |
155 | + return preceding.count() | |
204 | 156 | |
205 | 157 | @classmethod |
206 | 158 | def get_location(cls, query): |
... | ... |
dictionary/templates/lexeme_slickgrid_view.html
... | ... | @@ -108,12 +108,12 @@ |
108 | 108 | </div> |
109 | 109 | <div id="choose-filter-dialog" title="Filtrowanie"> |
110 | 110 | <p> |
111 | - <select class="op"> | |
111 | + <select id="group-op"> | |
112 | 112 | <option value="AND" selected="selected">oraz</option> |
113 | 113 | <option value="OR">lub</option> |
114 | 114 | </select> |
115 | 115 | <input type="button" value="+" title="Dodaj filtr" |
116 | - class="add-filter"> | |
116 | + id="add-filter-button"> | |
117 | 117 | </p> |
118 | 118 | <table id="filter-table"></table> |
119 | 119 | </div> |
... | ... | @@ -130,11 +130,11 @@ |
130 | 130 | <div id="choose-homonym-dialog" title="Wybierz homonim"> |
131 | 131 | <table id="homonym-list" class="choose-homonym-list"> |
132 | 132 | <thead> |
133 | - <tr> | |
134 | - <th>Nr hom.</th> | |
135 | - <th>Char. fleks.</th> | |
136 | - <th>Wzór</th> | |
137 | - </tr> | |
133 | + <tr> | |
134 | + <th>Nr hom.</th> | |
135 | + <th>Char. fleks.</th> | |
136 | + <th>Wzór</th> | |
137 | + </tr> | |
138 | 138 | </thead> |
139 | 139 | <tbody> |
140 | 140 | </tbody> |
... | ... |
dictionary/views.py
... | ... | @@ -182,16 +182,16 @@ def lexeme_slickgrid_view(request): |
182 | 182 | 'ajax_new_action_row': reverse('new_action_row'), |
183 | 183 | 'ajax_dynamic_fields': reverse('dynamic_action_fields'), |
184 | 184 | 'ajax_execute_actions': reverse('execute_group_actions'), |
185 | - 'visible_vocabularies': join_options((v.pk, v.id) for v in visible), | |
186 | 185 | 'vocabs': vocabs, |
187 | - 'parts_of_speech': join_options( | |
188 | - (pos.pk, pos.symbol) for pos in PartOfSpeech.objects.all()), | |
189 | - 'qualifier_options': join_options(qualifier_options), | |
190 | - 'cv_options': join_options(cv_options), | |
186 | + 'visible_vocabularies': [(v.pk, v.id) for v in visible], | |
187 | + 'parts_of_speech': [ | |
188 | + (pos.pk, pos.symbol) for pos in PartOfSpeech.objects.all()], | |
189 | + 'qualifier_options': qualifier_options, | |
190 | + 'cv_options': cv_options, | |
191 | + 'status_options': Lexeme.STATUS_CHOICES, | |
192 | + 'cr_type_options': cr_type_options, | |
191 | 193 | 'commonness': Classification.objects.get(name=u'pospolitość').pk, |
192 | 194 | 'exclusion_classes': exclusion_classes, |
193 | - 'status_options': dict(Lexeme.STATUS_CHOICES), | |
194 | - 'cr_type_options': join_options(cr_type_options), | |
195 | 195 | 'filtering_mode': request.user.usersettings.filter_search, |
196 | 196 | 'auto_search': request.user.usersettings.incremental_search, |
197 | 197 | 'default_owner': default_owner.id if default_owner else '', |
... | ... |
media/js/jqgrid.js
... | ... | @@ -9,7 +9,7 @@ var jqgrid = { |
9 | 9 | |
10 | 10 | changed: false, |
11 | 11 | |
12 | - filteroptions: null, // TODO filtrowanie | |
12 | + filteroptions: null, | |
13 | 13 | |
14 | 14 | put_filter: function(filter) { // TODO filtrowanie |
15 | 15 | "use strict"; |
... | ... | @@ -107,7 +107,7 @@ var jqgrid = { |
107 | 107 | |
108 | 108 | $(function () { |
109 | 109 | "use strict"; |
110 | - jqgrid.filteroptions = { // TODO filtrowanie | |
110 | + jqgrid.filteroptions = { | |
111 | 111 | multipleSearch: true, |
112 | 112 | overlay: false, |
113 | 113 | top: 300, |
... | ... | @@ -142,7 +142,7 @@ $(function () { |
142 | 142 | .dialog('option', 'position', 'center'); |
143 | 143 | return true; |
144 | 144 | }, |
145 | - onReset: function () { | |
145 | + onReset: function () { // TODO | |
146 | 146 | var init = { |
147 | 147 | "groupOp": "AND", |
148 | 148 | rules: [ |
... | ... | @@ -152,7 +152,7 @@ $(function () { |
152 | 152 | jqgrid.put_filter(init); |
153 | 153 | }, |
154 | 154 | onSearch: function () { |
155 | - $('#phrase_box').val(''); | |
155 | + $('#phrase_box').val(''); // TODO | |
156 | 156 | // TODO |
157 | 157 | jqgrid.grid.jqGrid('getGridParam', 'postData').force_reload = true; |
158 | 158 | }, |
... | ... | @@ -168,7 +168,7 @@ $(function () { |
168 | 168 | |
169 | 169 | jqgrid.grid = $('#scroll'); |
170 | 170 | var session_data = {}; |
171 | - if ($dj.filters) { // TODO filtrowanie | |
171 | + if ($dj.filters) { // TODO filtrowanie (na koniec) | |
172 | 172 | session_data.filters = $dj.filters; |
173 | 173 | } |
174 | 174 | if (sort_rules) { // TODO sortowanie |
... | ... | @@ -251,7 +251,7 @@ $(function () { |
251 | 251 | // nawigacja klawiaturą powoduje zmulenie, |
252 | 252 | // bo wszystkie leksemy muszą się załadować |
253 | 253 | //jqgrid.grid.jqGrid('bindKeys'); |
254 | - $('#filter-button').click(function() { // TODO filtrowanie | |
254 | + $('#filter-button').click(function() { | |
255 | 255 | jqgrid.grid.jqGrid('searchGrid', jqgrid.filteroptions); |
256 | 256 | }); |
257 | 257 | |
... | ... |
media/js/lexeme-slickgrid-view.js
... | ... | @@ -55,6 +55,10 @@ function count_column(name) { |
55 | 55 | }; |
56 | 56 | } |
57 | 57 | |
58 | +var text_ops = ['eq', 'ne', 'bw', 'bn', 'ew', 'en', 'cn', 'nc', 're', 'nr']; | |
59 | +var eqne = ['eq', 'ne']; | |
60 | +var count_ops = ['eq', 'ge', 'le']; | |
61 | + | |
58 | 62 | $.extend(slickgrid, { |
59 | 63 | grid_element_id: 'lexeme-grid', |
60 | 64 | main_field: 'entry', |
... | ... | @@ -72,46 +76,72 @@ $.extend(slickgrid, { |
72 | 76 | owner: {id: "owner", name: "Sł. właściciel", field: "owner"}, |
73 | 77 | status: {id: "status", name: "Status", field: "status"} |
74 | 78 | }, |
75 | - initialColModel: [ | |
76 | - {name: 'id', index: 'id', search: false, hidden: true}, | |
77 | - {name: 'entry', index: 'entry'}, | |
78 | - { | |
79 | - name: 'part_of_speech', | |
80 | - index: 'part_of_speech', | |
81 | - searchoptions: list_searchoptions($dj.parts_of_speech), | |
82 | - stype: 'select' | |
79 | + filter_fields: { | |
80 | + 'entry': {name: 'Hasło', gender: 'n', ops: text_ops}, | |
81 | + 'part_of_speech': { | |
82 | + name: 'Część mowy', | |
83 | + gender: 'f', | |
84 | + ops: eqne, | |
85 | + options: $dj.parts_of_speech | |
83 | 86 | }, |
84 | - lip_column('pattern_name'), | |
85 | - count_column('pattern_count'), | |
86 | - lip_column('inflection_characteristic'), | |
87 | - count_column('ic_count'), | |
88 | - { | |
89 | - name: 'form', | |
90 | - index: 'form', | |
91 | - hidden: true, | |
92 | - hidedlg: true, | |
93 | - sortable: false, | |
94 | - searchoptions: {searchhidden: true} | |
87 | + 'pattern_name': {name: 'Wzór', gender: 'm', ops: eqne}, | |
88 | + 'pattern_count': {name: 'Liczba wzorów', gender: 'f', ops: count_ops}, | |
89 | + 'inflection_characteristic': { | |
90 | + name: 'Char. fleks.', gender: 'f', ops: eqne}, | |
91 | + 'ic_count': {name: 'Liczba char. fleks.', gender: 'f', ops: count_ops}, | |
92 | + 'form': {name: 'Forma', gender: 'f', ops: text_ops}, | |
93 | + 'containing_vocabulary': { | |
94 | + name: 'Słownik', | |
95 | + gender: 'm', | |
96 | + ops: eqne, | |
97 | + options: $dj.visible_vocabularies | |
95 | 98 | }, |
96 | - list_column('containing_vocabulary', true, $dj.visible_vocabularies), | |
97 | - list_column('owner_vocabulary', true, $dj.visible_vocabularies), | |
98 | - list_column('status', true, $dj.status_options), | |
99 | - text_column('comment'), | |
100 | - list_column('lexeme_qualifier', false, $dj.qualifier_options), | |
101 | - list_column('lip_qualifier', false, $dj.qualifier_options), | |
102 | - list_column('qualifier', false, $dj.qualifier_options), | |
103 | - list_column('classification_value', false, $dj.cv_options), | |
104 | - text_column('gloss'), | |
105 | - text_column('note'), | |
106 | - list_column('cr_type', false, $dj.cr_type_options) | |
107 | - ], | |
108 | - initialColNames: [ | |
109 | - 'Id', 'Hasło', 'Część mowy', 'Wzór', 'Liczba wzorów', 'Char. fleks.', | |
110 | - 'Liczba char. fleks.', 'Forma', 'Słownik używający', 'Słownik właściciel', | |
111 | - 'Status', 'Komentarz', 'Kwal. leksemu', 'Kwal. odmieniasia', | |
112 | - 'Kwal. przy dow. formie', 'Wartość klasyfikacji', 'Glosa', 'Nota', | |
113 | - 'Typ odsyłacza' | |
114 | - ], | |
99 | + 'owner_vocabulary': { | |
100 | + name: 'Słownik właściciel', | |
101 | + gender: 'm', | |
102 | + ops: eqne, | |
103 | + options: $dj.visible_vocabularies | |
104 | + }, | |
105 | + 'status': { | |
106 | + name: 'Status', | |
107 | + gender: 'm', | |
108 | + ops: eqne, | |
109 | + options: $dj.status_options | |
110 | + }, | |
111 | + 'comment': {name: 'Komentarz', gender: 'm', ops: text_ops}, | |
112 | + 'lexeme_qualifier': { | |
113 | + name: 'Kwal. leksemu', | |
114 | + gender: 'm', | |
115 | + ops: eqne, | |
116 | + options: $dj.qualifier_options | |
117 | + }, | |
118 | + 'lip_qualifier': { | |
119 | + name: 'Kwal. odmieniasia', | |
120 | + gender: 'm', | |
121 | + ops: eqne, | |
122 | + options: $dj.qualifier_options | |
123 | + }, | |
124 | + 'qualifier': { | |
125 | + name: 'Kwal. przy dow. formie', | |
126 | + gender: 'm', | |
127 | + ops: eqne, | |
128 | + options: $dj.qualifier_options | |
129 | + }, | |
130 | + 'classification_value': { | |
131 | + name: 'Wartość klasyfikacji', | |
132 | + gender: 'f', | |
133 | + ops: eqne, | |
134 | + options: $dj.cv_options | |
135 | + }, | |
136 | + 'gloss': {name: 'Glosa', gender: 'f', ops: text_ops}, | |
137 | + 'nota': {name: 'Nota', gender: 'f', ops: text_ops}, | |
138 | + 'cr_type': { | |
139 | + name: 'Typ odsyłacza', | |
140 | + gender: 'm', | |
141 | + ops: eqne, | |
142 | + options: $dj.cr_type_options | |
143 | + } | |
144 | + }, | |
115 | 145 | initial_sort_rules: [ |
116 | 146 | {field: 'entry', order: 'asc', a_tergo: false}, |
117 | 147 | {field: 'part_of_speech', order: 'asc'}, |
... | ... |
media/js/remotemodel.js
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | var h_request = null; |
11 | 11 | var ajax_request = null; |
12 | 12 | var sort_rules = null; |
13 | - var filters = null; | |
13 | + var filter = {group_op: "AND", rules: []}; | |
14 | 14 | |
15 | 15 | // events |
16 | 16 | var onDataLoading = new Slick.Event(); |
... | ... | @@ -80,7 +80,8 @@ |
80 | 80 | rows: PAGESIZE, |
81 | 81 | from_page: fromPage, |
82 | 82 | to_page: toPage, |
83 | - sort_rules: sort_rules | |
83 | + sort_rules: sort_rules, | |
84 | + filters: filter | |
84 | 85 | }; |
85 | 86 | if (searchstr !== '') ajax_data.mask = searchstr; |
86 | 87 | |
... | ... | @@ -135,14 +136,14 @@ |
135 | 136 | clear(); |
136 | 137 | } |
137 | 138 | |
138 | - function setFilters(f) { | |
139 | - filters = f; | |
139 | + function setFilter(f) { | |
140 | + filter = f; | |
140 | 141 | clear(); |
141 | 142 | } |
142 | 143 | |
143 | 144 | function searchRow(search_text, callback) { |
144 | 145 | var data = { |
145 | - filters: filters, | |
146 | + filters: filter, | |
146 | 147 | sort_rules: sort_rules, |
147 | 148 | search: search_text |
148 | 149 | }; |
... | ... | @@ -169,7 +170,7 @@ |
169 | 170 | "reloadData": reloadData, |
170 | 171 | "setSort": setSort, |
171 | 172 | "setSearch": setSearch, |
172 | - "setFilters": setFilters, | |
173 | + "setFilter": setFilter, | |
173 | 174 | "searchRow": searchRow, |
174 | 175 | |
175 | 176 | // events |
... | ... |
media/js/slickgrid.js
... | ... | @@ -9,6 +9,21 @@ function search_string() { |
9 | 9 | var slickgrid = { |
10 | 10 | grid: null, |
11 | 11 | |
12 | + op_names: { | |
13 | + eq: ["równy", "równa", "równe"], | |
14 | + ne: ["różny od", "różna od", "różne od"], | |
15 | + le: ["mniejszy lub równy", "mniejsza lub równa", "mniejsze lub równe"], | |
16 | + ge: ["większy lub równy", "większa lub równa", "większe lub równe"], | |
17 | + bw: "zaczyna się od", | |
18 | + bn: "nie zaczyna się od", | |
19 | + ew: "kończy się na", | |
20 | + en: "nie kończy się na", | |
21 | + cn: "zawiera", | |
22 | + nc: "nie zawiera", | |
23 | + re: "pasuje do wzorca", | |
24 | + nr: "nie pasuje do wzorca" | |
25 | + }, | |
26 | + | |
12 | 27 | active_id: function(cell) { |
13 | 28 | "use strict"; |
14 | 29 | if (cell === undefined) |
... | ... | @@ -59,8 +74,6 @@ var options = { |
59 | 74 | enableCellNavigation: true |
60 | 75 | }; |
61 | 76 | |
62 | -var loadingIndicator = null; | |
63 | - | |
64 | 77 | function set_columns() { |
65 | 78 | "use strict"; |
66 | 79 | var chosen_column_ids = $('#column-list').val(); |
... | ... | @@ -76,6 +89,73 @@ function set_columns() { |
76 | 89 | });*/ //TODO |
77 | 90 | } |
78 | 91 | |
92 | +function update_filter_row(row) { | |
93 | + "use strict"; | |
94 | + var field = row.find('.field-select').val(); | |
95 | + var field_info = slickgrid.filter_fields[field]; | |
96 | + var op_select = $('<select/>').addClass('op-select'); | |
97 | + var value_input; | |
98 | + $.each(field_info.ops, function(i, op) { | |
99 | + var op_name; | |
100 | + var op_name_info = slickgrid.op_names[op]; | |
101 | + if (typeof op_name_info !== "string") { | |
102 | + var gender = 'mfn'.indexOf(field_info.gender); | |
103 | + op_name = op_name_info[gender]; | |
104 | + } else { | |
105 | + op_name = op_name_info; | |
106 | + } | |
107 | + $('<option/>').text(op_name).val(op).appendTo(op_select); | |
108 | + }); | |
109 | + if (field_info.options) { | |
110 | + value_input = $('<select/>').addClass('filter-data'); | |
111 | + $.each(field_info.options, function(i, option) { | |
112 | + $('<option/>').text(option[1]).val(option[0]).appendTo(value_input); | |
113 | + }); | |
114 | + } else { | |
115 | + value_input = $('<input/>').attr('type', 'text'); | |
116 | + value_input.addClass('filter-data'); | |
117 | + } | |
118 | + row.children().eq(1).empty().append(op_select); | |
119 | + row.children().eq(2).empty().append(value_input); | |
120 | +} | |
121 | + | |
122 | +function add_filter(field) { | |
123 | + "use strict"; | |
124 | + var filter_table = $('#filter-table'); | |
125 | + var row = $('<tr/>'); | |
126 | + var field_select = $('<select/>').addClass('field-select'); | |
127 | + | |
128 | + $.each(slickgrid.filter_fields, function(id, filter_field) { | |
129 | + var option = $('<option/>').text(filter_field.name).val(id); | |
130 | + if (id === field) { | |
131 | + option.prop('selected', true); | |
132 | + } | |
133 | + option.appendTo(field_select); | |
134 | + }); | |
135 | + $('<td/>').append(field_select).appendTo(row); | |
136 | + row.append($('<td/>')).append($('<td/>')); | |
137 | + var remove_button = $('<input/>').attr('type', 'button').val('-') | |
138 | + .addClass('remove-filter'); | |
139 | + $('<td/>').append(remove_button).appendTo(row); | |
140 | + update_filter_row(row); | |
141 | + filter_table.append(row); | |
142 | +} | |
143 | + | |
144 | +function get_filters() { | |
145 | + "use strict"; | |
146 | + return { | |
147 | + group_op: $('#group-op').val(), | |
148 | + rules: $('#filter-table').find('tr').map(function(i, row) { | |
149 | + var $row = $(row); | |
150 | + return { | |
151 | + 'field': $row.find('.field-select').val(), | |
152 | + 'op': $row.find('.op-select').val(), | |
153 | + 'data': $row.find('.filter-data').val() | |
154 | + }; | |
155 | + }).toArray() | |
156 | + }; | |
157 | +} | |
158 | + | |
79 | 159 | $(function() { |
80 | 160 | "use strict"; |
81 | 161 | slickgrid.element = $('#' + slickgrid.grid_element_id); |
... | ... | @@ -114,6 +194,7 @@ $(function() { |
114 | 194 | } |
115 | 195 | }); |
116 | 196 | |
197 | + var loadingIndicator = null; | |
117 | 198 | loader.onDataLoading.subscribe(function () { |
118 | 199 | if (!loadingIndicator) { |
119 | 200 | loadingIndicator = $( |
... | ... | @@ -149,6 +230,7 @@ $(function() { |
149 | 230 | } |
150 | 231 | }); |
151 | 232 | |
233 | + // wyszukiwanie | |
152 | 234 | var search_timeout_handler; |
153 | 235 | $("#text-search").keyup(function (e) { |
154 | 236 | if (e.which === 13) { |
... | ... | @@ -163,15 +245,52 @@ $(function() { |
163 | 245 | loader.setSearch(search_string()); |
164 | 246 | } |
165 | 247 | |
248 | + $('#search-button').click(slickgrid.search); | |
249 | + | |
250 | + // sortowanie | |
166 | 251 | loader.setSort($dj.sort_rules || slickgrid.initial_sort_rules); |
167 | 252 | |
168 | - loader.setFilters([]); | |
253 | + // filtry | |
254 | + var filter_table = $('#filter-table'); | |
255 | + add_filter(slickgrid.main_field); | |
256 | + $('#choose-filter-dialog').dialog({ | |
257 | + autoOpen: false, | |
258 | + width: 'auto', | |
259 | + modal: false, | |
260 | + buttons: [ | |
261 | + { | |
262 | + text: "Zapisz filtr" | |
263 | + }, | |
264 | + { | |
265 | + text: "Załaduj filtr" | |
266 | + }, | |
267 | + { | |
268 | + text: 'Filtruj', | |
269 | + click: function() { | |
270 | + loader.setFilter(get_filters()); | |
271 | + slickgrid.ensure_data(); | |
272 | + } | |
273 | + } | |
274 | + ] | |
275 | + }); | |
276 | + $('#add-filter-button').click(function() { | |
277 | + add_filter(slickgrid.main_field); | |
278 | + }); | |
279 | + $(document).on('change', '.field-select', function() { | |
280 | + update_filter_row($(this).closest('tr')); | |
281 | + }); | |
282 | + $(document).on('click', '.remove-filter', function() { | |
283 | + $(this).closest('tr').remove(); | |
284 | + }); | |
169 | 285 | |
170 | - $('#search-button').click(slickgrid.search); | |
286 | + $('#filter-button').click(function() { | |
287 | + $('#choose-filter-dialog').dialog('open'); | |
288 | + }); | |
171 | 289 | |
172 | - // load the first page | |
173 | - slickgrid.grid.onViewportChanged.notify(); | |
290 | + // TODO ustawić filtr jeśli był zapamiętany | |
291 | + //loader.setFilters(); | |
174 | 292 | |
293 | + // wybór kolumn | |
175 | 294 | $('#choose-columns-dialog').dialog({ |
176 | 295 | autoOpen: false, |
177 | 296 | width: 'auto', |
... | ... | @@ -217,5 +336,8 @@ $(function() { |
217 | 336 | sortable: true |
218 | 337 | }); |
219 | 338 | |
339 | + // load the first page | |
340 | + slickgrid.grid.onViewportChanged.notify(); | |
341 | + | |
220 | 342 | layout.adjust_tabs(); |
221 | 343 | }); |
222 | 344 | \ No newline at end of file |
... | ... |