|
|
"""Wrapper around the jQuery UI library
|
|
|
|
|
|
Exposes a single object, jq, to manipulate the widgets designed in the library
|
|
|
|
|
|
This object supports :
|
|
|
- subscription : js[elt_id] returns an object matching the element with the
|
|
|
specified id
|
|
|
- a method get(**kw). The only keyword currently supported is "selector". The
|
|
|
method returns a list of instances of the class Element, each instance wraps
|
|
|
the elements matching the CSS selector passed
|
|
|
|
|
|
jq(selector="button") : returns instances of Element for all button tags
|
|
|
|
|
|
The value can be a list or tuple of CSS selector strings :
|
|
|
|
|
|
js(selector=("input[type=submit]","a")) : instances of Element for all
|
|
|
"input" tags with attribute "type" set to "submit" + "a" tags (anchors)
|
|
|
|
|
|
Instances of Element have the same interface as the selections made by the
|
|
|
jQuery function $, with the additional methods provided by jQuery UI. For
|
|
|
instance, to turn an element into a dialog :
|
|
|
|
|
|
jq[elt_id].dialog()
|
|
|
|
|
|
When jQuery UI methods expect a Javascript object, they can be passed as
|
|
|
key/value pairs :
|
|
|
|
|
|
jq['tags'].autocomplete(source=availableTags)
|
|
|
|
|
|
"""
|
|
|
from browser import html, document, window
|
|
|
import javascript
|
|
|
|
|
|
_path = __file__[:__file__.rfind('/')]+'/'
|
|
|
|
|
|
document <= html.LINK(rel="stylesheet",
|
|
|
href=_path+'css/smoothness/jquery-ui.css')
|
|
|
|
|
|
# The scripts must be loaded in blocking mode, by using the function
|
|
|
# load(script_url[, names]) in module javascript
|
|
|
# If we just add them to the document with script tags, eg :
|
|
|
#
|
|
|
# document <= html.SCRIPT(sciprt_url)
|
|
|
# _jqui = window.jQuery.noConflict(True)
|
|
|
#
|
|
|
# the name "jQuery" is not in the Javascript namespace until the script is
|
|
|
# fully loaded in the page, so "window.jQuery" raises an exception
|
|
|
|
|
|
# Load jQuery and put name 'jQuery' in the global Javascript namespace
|
|
|
javascript.load(_path+'jquery-1.11.2.min.js', ['jQuery'])
|
|
|
javascript.load(_path+'jquery-ui.min.js')
|
|
|
|
|
|
_jqui = window.jQuery.noConflict(True)
|
|
|
|
|
|
_events = ['abort',
|
|
|
'beforeinput',
|
|
|
'blur',
|
|
|
'click',
|
|
|
'compositionstart',
|
|
|
'compositionupdate',
|
|
|
'compositionend',
|
|
|
'dblclick',
|
|
|
'error',
|
|
|
'focus',
|
|
|
'focusin',
|
|
|
'focusout',
|
|
|
'input',
|
|
|
'keydown',
|
|
|
'keyup',
|
|
|
'load',
|
|
|
'mousedown',
|
|
|
'mouseenter',
|
|
|
'mouseleave',
|
|
|
'mousemove',
|
|
|
'mouseout',
|
|
|
'mouseover',
|
|
|
'mouseup',
|
|
|
'resize',
|
|
|
'scroll',
|
|
|
'select',
|
|
|
'unload']
|
|
|
|
|
|
class JQFunction:
|
|
|
|
|
|
def __init__(self, func):
|
|
|
self.func = func
|
|
|
|
|
|
def __call__(self, *args, **kw):
|
|
|
if kw:
|
|
|
# keyword arguments are passed as a single Javascript object
|
|
|
return self.func(*args, kw)
|
|
|
else:
|
|
|
return self.func(*args)
|
|
|
|
|
|
class Element:
|
|
|
"""Wrapper around the objects returned by jQuery selections"""
|
|
|
|
|
|
def __init__(self, item):
|
|
|
self.item = item
|
|
|
|
|
|
def bind(self, event, callback):
|
|
|
"""Binds an event on the element to function callback"""
|
|
|
getattr(self.item, event)(callback)
|
|
|
|
|
|
def __getattr__(self, attr):
|
|
|
res = getattr(self.item, attr)
|
|
|
if attr in _events:
|
|
|
# elt.click(f) is handled like elt.bind('click', f)
|
|
|
return lambda f:self.bind(attr, f)
|
|
|
if callable(res):
|
|
|
res = JQFunction(res)
|
|
|
return res
|
|
|
|
|
|
class jq:
|
|
|
|
|
|
@staticmethod
|
|
|
def get(**selectors):
|
|
|
items = []
|
|
|
for k,v in selectors.items():
|
|
|
if k=='selector':
|
|
|
if isinstance(v,[list, tuple]):
|
|
|
values = v
|
|
|
else:
|
|
|
values = [v]
|
|
|
for value in values:
|
|
|
items.append(Element(_jqui(value)))
|
|
|
elif k=='element':
|
|
|
items = Element(_jqui(v))
|
|
|
return items
|
|
|
|
|
|
@staticmethod
|
|
|
def __getitem__(element_id):
|
|
|
return jq.get(selector='#'+element_id)[0]
|
|
|
|