add autocomplete api

This commit is contained in:
j 2014-10-04 20:57:09 +02:00
parent 9db6adc222
commit a48f039e89
5 changed files with 62 additions and 16 deletions

View File

@ -12,6 +12,7 @@
"title": "Title",
"type": "string",
"autocomplete": true,
"autocompleteSort": [{"key": "title", "operator": "+"}],
"columnRequired": true,
"columnWidth": 256,
"find": true,

View File

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
import json
import hashlib
from sqlalchemy.orm import load_only
from sqlalchemy import func
from oxtornado import actions
from utils import cleanup_id
@ -148,8 +147,56 @@ def remove(data):
actions.register(remove, cache=False)
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):
'''

View File

@ -1,12 +1,9 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from datetime import datetime
from io import StringIO, BytesIO
from io import BytesIO
import base64
import hashlib
import json
import os
import re
import shutil
@ -148,6 +145,7 @@ class Item(db.Model):
value = list(value.values())
if isinstance(value, list):
value = ''.join(value)
value = ox.get_sort_title(value)
value = utils.sort_title(value).lower()
else:
if isinstance(value, list):

View File

@ -1,11 +1,11 @@
import json
def loads(*args, **kargs):
#print('loads', args, kargs)
def loads(*args, **kwargs):
#print('loads', args, kwargs)
if isinstance(args[0], bytes):
args = (args[0].decode('utf-8'),) + args[1:]
return json.loads(*args, **kargs)
return json.loads(*args, **kwargs)
def dumps(*args, **kargs):
#print('dumps', args, kargs)
return json.dumps(*args, **kargs).encode()
def dumps(*args, **kwargs):
#print('dumps', args, kwargs)
return json.dumps(*args, **kwargs).encode()

View File

@ -131,7 +131,7 @@ oml.ui.findElement = function() {
function getAutocomplete() {
var key = !that
? ui._findState.key
: that.value()[ui._list ? 1 : 0],
: that.value()[1],
findKey = Ox.getObjectById(oml.config.findKeys, key);
return findKey && findKey.autocomplete ? function(value, callback) {
oml.api.autocomplete({
@ -220,4 +220,4 @@ oml.ui.findElement = function() {
return that;
};
};