add autocomplete api
This commit is contained in:
parent
9db6adc222
commit
a48f039e89
5 changed files with 62 additions and 16 deletions
|
@ -12,6 +12,7 @@
|
||||||
"title": "Title",
|
"title": "Title",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"autocomplete": true,
|
"autocomplete": true,
|
||||||
|
"autocompleteSort": [{"key": "title", "operator": "+"}],
|
||||||
"columnRequired": true,
|
"columnRequired": true,
|
||||||
"columnWidth": 256,
|
"columnWidth": 256,
|
||||||
"find": true,
|
"find": true,
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
from sqlalchemy.orm import load_only
|
from sqlalchemy.orm import load_only
|
||||||
|
from sqlalchemy import func
|
||||||
|
|
||||||
from oxtornado import actions
|
from oxtornado import actions
|
||||||
from utils import cleanup_id
|
from utils import cleanup_id
|
||||||
|
@ -148,8 +147,56 @@ def remove(data):
|
||||||
actions.register(remove, cache=False)
|
actions.register(remove, cache=False)
|
||||||
|
|
||||||
def autocomplete(data):
|
def autocomplete(data):
|
||||||
return {}
|
'''
|
||||||
actions.register(remove, cache=False)
|
takes {
|
||||||
|
key: string,
|
||||||
|
value: string,
|
||||||
|
operator: string // '=', '==', '^', '$'
|
||||||
|
query: object // item query to limit results
|
||||||
|
range: [int, int]
|
||||||
|
}
|
||||||
|
returns {
|
||||||
|
items: [string, ...] //array of matching values
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
response = {}
|
||||||
|
response['items'] = []
|
||||||
|
if not 'range' in data:
|
||||||
|
data['range'] = [0, 10]
|
||||||
|
op = data.get('operator', '=')
|
||||||
|
|
||||||
|
key = utils.get_by_id(settings.config['itemKeys'], data['key'])
|
||||||
|
order_by = key.get('autocompleteSort', False)
|
||||||
|
add_itemsort = False
|
||||||
|
if order_by:
|
||||||
|
for o in order_by:
|
||||||
|
if o['operator'] != '-': o['operator'] = ''
|
||||||
|
order_by = ['%(operator)ssort.%(key)s' % o for o in order_by]
|
||||||
|
add_itemsort = True
|
||||||
|
else:
|
||||||
|
order_by = ['-items']
|
||||||
|
|
||||||
|
items = query.parse({'query': data.get('query', {})})['qs'].options(load_only('id'))
|
||||||
|
qs = state.db.session.query(models.Find.value, func.count(models.Find.value).label('items'))
|
||||||
|
qs = qs.filter(models.Find.item_id.in_(items))
|
||||||
|
if data['value']:
|
||||||
|
value = data['value'].lower()
|
||||||
|
qs = qs.filter(models.Find.key.is_(data['key']))
|
||||||
|
if op == '=':
|
||||||
|
qs = qs.filter(models.Find.findvalue.contains(value))
|
||||||
|
elif op == '==':
|
||||||
|
qs = qs.filter(models.Find.findvalue.is_(value))
|
||||||
|
elif op == '^':
|
||||||
|
qs = qs.filter(models.Find.findvalue.startswith(value))
|
||||||
|
elif op == '$':
|
||||||
|
qs = qs.filter(models.Find.findvalue.endswith(value))
|
||||||
|
qs = qs.group_by(models.Find.value)
|
||||||
|
if add_itemsort:
|
||||||
|
qs = qs.join(models.Item).join(models.Sort)
|
||||||
|
qs = qs.order_by(*order_by)
|
||||||
|
response['items'] = [r.value for r in qs[data['range'][0]:data['range'][1]]]
|
||||||
|
return response
|
||||||
|
actions.register(autocomplete)
|
||||||
|
|
||||||
def findMetadata(data):
|
def findMetadata(data):
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
|
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from io import StringIO, BytesIO
|
from io import BytesIO
|
||||||
import base64
|
import base64
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
|
@ -148,6 +145,7 @@ class Item(db.Model):
|
||||||
value = list(value.values())
|
value = list(value.values())
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
value = ''.join(value)
|
value = ''.join(value)
|
||||||
|
value = ox.get_sort_title(value)
|
||||||
value = utils.sort_title(value).lower()
|
value = utils.sort_title(value).lower()
|
||||||
else:
|
else:
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
def loads(*args, **kargs):
|
def loads(*args, **kwargs):
|
||||||
#print('loads', args, kargs)
|
#print('loads', args, kwargs)
|
||||||
if isinstance(args[0], bytes):
|
if isinstance(args[0], bytes):
|
||||||
args = (args[0].decode('utf-8'),) + args[1:]
|
args = (args[0].decode('utf-8'),) + args[1:]
|
||||||
return json.loads(*args, **kargs)
|
return json.loads(*args, **kwargs)
|
||||||
|
|
||||||
def dumps(*args, **kargs):
|
def dumps(*args, **kwargs):
|
||||||
#print('dumps', args, kargs)
|
#print('dumps', args, kwargs)
|
||||||
return json.dumps(*args, **kargs).encode()
|
return json.dumps(*args, **kwargs).encode()
|
||||||
|
|
|
@ -131,7 +131,7 @@ oml.ui.findElement = function() {
|
||||||
function getAutocomplete() {
|
function getAutocomplete() {
|
||||||
var key = !that
|
var key = !that
|
||||||
? ui._findState.key
|
? ui._findState.key
|
||||||
: that.value()[ui._list ? 1 : 0],
|
: that.value()[1],
|
||||||
findKey = Ox.getObjectById(oml.config.findKeys, key);
|
findKey = Ox.getObjectById(oml.config.findKeys, key);
|
||||||
return findKey && findKey.autocomplete ? function(value, callback) {
|
return findKey && findKey.autocomplete ? function(value, callback) {
|
||||||
oml.api.autocomplete({
|
oml.api.autocomplete({
|
||||||
|
|
Loading…
Reference in a new issue