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", "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,

View File

@ -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):
''' '''

View File

@ -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):

View File

@ -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()

View File

@ -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({
@ -220,4 +220,4 @@ oml.ui.findElement = function() {
return that; return that;
}; };