0001-misc-add-dynamic-autocomplete-for-select-of-cards-47.patch
tests/test_form_pages.py | ||
---|---|---|
6091 | 6091 |
assert '0_structured' not in formdef.data_class().select()[0].data |
6092 | 6092 | |
6093 | 6093 | |
6094 |
def test_item_field_autocomplete_cards_source(pub): |
|
6095 |
user = create_user(pub) |
|
6096 |
formdef = create_formdef() |
|
6097 |
formdef.data_class().wipe() |
|
6098 | ||
6099 |
carddef = CardDef() |
|
6100 |
carddef.name = 'items' |
|
6101 |
carddef.digest_template = '{{form_var_name}}' |
|
6102 |
carddef.fields = [ |
|
6103 |
fields.StringField(id='0', label='string', varname='name'), |
|
6104 |
fields.StringField(id='1', label='string', varname='attr'), |
|
6105 |
] |
|
6106 |
carddef.store() |
|
6107 |
for i, value in enumerate(['foo', 'bar', 'baz']): |
|
6108 |
carddata = carddef.data_class()() |
|
6109 |
carddata.data = { |
|
6110 |
'0': value, |
|
6111 |
'1': 'attr%s' % i, |
|
6112 |
} |
|
6113 |
carddata.just_created() |
|
6114 |
carddata.store() |
|
6115 | ||
6116 |
ds = {'type': 'carddef:%s' % carddef.url_name} |
|
6117 |
formdef.fields = [ |
|
6118 |
fields.ItemField(id='0', label='string', type='item', |
|
6119 |
data_source=ds, |
|
6120 |
display_mode='autocomplete', |
|
6121 |
), |
|
6122 |
] |
|
6123 |
formdef.store() |
|
6124 | ||
6125 |
app = get_app(pub) |
|
6126 |
resp = app.get('/test/') |
|
6127 |
select2_url = resp.pyquery('select').attr['data-select2-url'] |
|
6128 |
resp2 = app.get(select2_url + '?q=ba') |
|
6129 |
assert [x['text'] for x in resp2.json['data']] == ['bar', 'baz'] |
|
6130 |
resp.form['f0'].force_value(str(resp2.json['data'][0]['id'])) |
|
6131 |
resp = resp.form.submit('submit') # -> validation page |
|
6132 |
resp = resp.form.submit('submit') # -> submit |
|
6133 |
assert formdef.data_class().select()[0].data['0'] == '2' |
|
6134 |
assert formdef.data_class().select()[0].data['0_display'] == 'bar' |
|
6135 | ||
6136 | ||
6094 | 6137 |
def test_form_data_keywords(pub): |
6095 | 6138 |
formdef = create_formdef() |
6096 | 6139 |
formdef.keywords = 'hello,world' |
wcs/api.py | ||
---|---|---|
829 | 829 | |
830 | 830 |
class AutocompleteDirectory(Directory): |
831 | 831 |
def _q_lookup(self, component): |
832 |
url = get_session().get_data_source_query_url_from_token(component)
|
|
833 |
if not url:
|
|
832 |
info = get_session().get_data_source_query_info_from_token(component)
|
|
833 |
if not info:
|
|
834 | 834 |
raise AccessForbiddenError() |
835 |
get_response().set_content_type('application/json') |
|
836 |
if info.startswith('carddef:'): |
|
837 |
from wcs.carddef import CardDef |
|
838 |
values = CardDef.get_data_source_items(info, |
|
839 |
query=get_request().form['q'], |
|
840 |
limit=get_request().form.get('page_limit')) |
|
841 |
return json.dumps({'data': [{'id': x['id'], 'text': x['text']} for x in values]}) |
|
842 |
url = info |
|
835 | 843 |
url += urllib.quote(get_request().form['q']) |
836 |
unsigned_url = url |
|
837 | 844 |
url = sign_url_auto_orig(url) |
838 | 845 |
get_response().set_content_type('application/json') |
839 | 846 |
return misc.urlopen(url).read() |
wcs/carddef.py | ||
---|---|---|
19 | 19 | |
20 | 20 |
from quixote import get_publisher |
21 | 21 |
from .qommon import _, N_, misc |
22 |
from .qommon.storage import Equal, NotEqual |
|
22 |
from .qommon.storage import Equal, NotEqual, ILike
|
|
23 | 23 | |
24 | 24 |
from wcs.carddata import CardData |
25 | 25 |
from wcs.formdef import FormDef |
... | ... | |
154 | 154 |
yield (data_source_id, '%s - %s' % (carddef['name'], custom_view.title), data_source_id) |
155 | 155 | |
156 | 156 |
@classmethod |
157 |
def get_data_source_items(cls, data_source_id): |
|
157 |
def get_data_source_items(cls, data_source_id, query=None, limit=None):
|
|
158 | 158 |
assert data_source_id.startswith('carddef:') |
159 | 159 |
parts = data_source_id.split(':') |
160 | 160 |
try: |
... | ... | |
178 | 178 |
criterias.extend(form_page.get_view_criterias()) |
179 | 179 |
order_by = custom_view.order_by |
180 | 180 | |
181 |
if query: |
|
182 |
criterias.append(ILike('digest', query)) |
|
181 | 183 |
items = [x.get_data_source_structured_item() |
182 | 184 |
for x in carddef.data_class().select( |
183 | 185 |
clause=criterias, |
184 |
order_by=order_by)] |
|
186 |
order_by=order_by, |
|
187 |
limit=limit)] |
|
185 | 188 |
if order_by is None: |
186 | 189 |
items.sort(key=lambda x: misc.simplify(x['text'])) |
187 | 190 |
return items |
wcs/data_sources.py | ||
---|---|---|
335 | 335 |
return True |
336 | 336 |
if self.type == 'json' and self.query_parameter: |
337 | 337 |
return True |
338 |
if self.type and self.type.startswith('carddef:'): |
|
339 |
return True |
|
338 | 340 |
return False |
339 | 341 | |
340 | 342 |
def migrate(self): |
... | ... | |
416 | 418 |
return self.data_source.get('value') |
417 | 419 |
if self.type == 'json' and self.query_parameter: |
418 | 420 |
return '/api/autocomplete/%s' % ( |
419 |
get_session().get_data_source_query_url_token(self.get_json_query_url())) |
|
421 |
get_session().get_data_source_query_info_token(self.get_json_query_url())) |
|
422 |
if self.type and self.type.startswith('carddef:'): |
|
423 |
return '/api/autocomplete/%s' % ( |
|
424 |
get_session().get_data_source_query_info_token(self.type)) |
|
420 | 425 |
return None |
421 | 426 | |
422 | 427 |
def get_value_by_id(self, param_name, param_value): |
wcs/sessions.py | ||
---|---|---|
142 | 142 |
del session.visiting_objects[object_key] |
143 | 143 |
session.store() |
144 | 144 | |
145 |
def get_data_source_query_url_token(self, url): |
|
145 |
def get_data_source_query_info_token(self, info): |
|
146 |
# info can be an URL in case of remote JSON source or a cards |
|
147 |
# reference, like carddef:foobar. It is stored in a dictionary |
|
148 |
# with _url_ in its name for historical reasons. |
|
146 | 149 |
if not self.data_source_query_url_tokens: |
147 | 150 |
self.data_source_query_url_tokens = {} |
148 | 151 |
for key, value in self.data_source_query_url_tokens.items(): |
149 |
if value == url:
|
|
152 |
if value == info:
|
|
150 | 153 |
return key |
151 | 154 |
key = str(uuid.uuid4()) |
152 |
self.data_source_query_url_tokens[key] = url
|
|
155 |
self.data_source_query_url_tokens[key] = info
|
|
153 | 156 |
self.store() |
154 | 157 |
return key |
155 | 158 | |
156 |
def get_data_source_query_url_from_token(self, token):
|
|
159 |
def get_data_source_query_info_from_token(self, token):
|
|
157 | 160 |
if not self.data_source_query_url_tokens: |
158 | 161 |
return None |
159 | 162 |
return self.data_source_query_url_tokens.get(token) |
160 |
- |