""" Adds client-side Javascript filtering to the widget instance passed. The widget is expected to render as an HTML select, or the Javascript associated will fail. This only works in Gecko - functionality in IE and Opera is limited. The list is not filtered, but the first matching item will automatically be selected. """ make_searchable_js = \ """ // filters a select by hiding all non-matching items - only works in FF so far. // // select - the id of the select control to filter // filter_by_ctrl - a reference to an input object with the text to filter by function filter_select(select, filter_by_ctrl) { filter_text = filter_by_ctrl.value.replace(/^\s+|\s+$/g,""); // trimmed if (filter_by_ctrl.value == filter_by_ctrl.old_value) return false; select_ctrl = document.getElementById(select); sel_found = false; for(i=0;i=0;i--) { if (select_ctrl.options[i].style.display!='none') { select_ctrl.options[i].selected = true; return true; } }; } // TODO: page up / page down (33/34) } """ def make_searchable(widget, set_size=None): def render_hook(self, old_render, name, value, attrs, choices): result = '
' % {'id': attrs['id']} # add a search box return result+old_render(name, value, attrs, choices) old_render = widget.render import new widget.render = new.instancemethod( lambda self, name, value, attrs=None, choices=(): \ render_hook(self, old_render, name, value, attrs, choices), widget, widget.__class__) widget.attrs['tabindex'] = -1 if set_size: widget.attrs['size'] = set_size """ Make multiple fields of a form searchable in one go. form can be either a form class, or a form instance. fields can be a list of valid field names for this form, or a dict with field names as keys, and options dicts as values. Example: {'foreignkey': {'set_size': 5}, ...} Valid options are whatever is allowed by make_searchable(), the dict is directly expandend to a parameter list on call. """ def make_fields_searchable(form, fields): # determine whether this is a form class or a form instance, and use # the correct field property accordingly. if hasattr(form, 'base_fields'): fields_array = form.base_fields else: fields_array = form.fields # get a list of field names if type(fields) == list: field_names = fields else: field_names = fields.keys() for field in field_names: params = {} if type(fields) == dict: params = fields[field] make_searchable(fields_array[field].widget, **params)