More grid filter improvements; add choice/enum/date value renderers.
This commit is contained in:
		
							parent
							
								
									226ca01720
								
							
						
					
					
						commit
						c9b01f6061
					
				
					 2 changed files with 64 additions and 9 deletions
				
			
		|  | @ -43,9 +43,6 @@ class FilterValueRenderer(object): | |||
|     Base class for all filter renderers. | ||||
|     """ | ||||
| 
 | ||||
|     def __init__(self, filter=None): | ||||
|         self.filter = filter | ||||
| 
 | ||||
|     @property | ||||
|     def name(self): | ||||
|         return self.filter.key | ||||
|  | @ -69,12 +66,40 @@ class NumericValueRenderer(FilterValueRenderer): | |||
|     Input renderer for numeric values. | ||||
|     """ | ||||
| 
 | ||||
|     def render(self, value=None, **kwargs): | ||||
|         return tags.text(self.name, value=value, type='number', **kwargs) | ||||
| 
 | ||||
| 
 | ||||
| class DateValueRenderer(FilterValueRenderer): | ||||
|     """ | ||||
|     Input renderer for date values. | ||||
|     """ | ||||
| 
 | ||||
|     def render(self, value=None, **kwargs): | ||||
|         return tags.text(self.name, value=value, type='date', **kwargs) | ||||
| 
 | ||||
| 
 | ||||
| class ChoiceValueRenderer(FilterValueRenderer): | ||||
|     """ | ||||
|     Renders value input as a dropdown/selectmenu of available choices. | ||||
|     """ | ||||
| 
 | ||||
|     def __init__(self, choices): | ||||
|         self.choices = choices | ||||
| 
 | ||||
|     def render(self, value=None, **kwargs): | ||||
|         return tags.select(self.name, [value], self.choices, **kwargs) | ||||
| 
 | ||||
| 
 | ||||
| class EnumValueRenderer(ChoiceValueRenderer): | ||||
|     """ | ||||
|     Renders value input as a dropdown/selectmenu of available choices. | ||||
|     """ | ||||
| 
 | ||||
|     def __init__(self, enum): | ||||
|         sorted_keys = sorted(enum, key=lambda k: enum[k].lower()) | ||||
|         self.choices = [(k, enum[k]) for k in sorted_keys] | ||||
| 
 | ||||
| 
 | ||||
| class GridFilter(object): | ||||
|     """ | ||||
|  | @ -106,11 +131,7 @@ class GridFilter(object): | |||
|         self.key = key | ||||
|         self.label = label or prettify(key) | ||||
|         self.verbs = verbs or self.get_default_verbs() | ||||
|         if value_renderer is not None: | ||||
|             value_renderer.filter = self | ||||
|             self.value_renderer = value_renderer | ||||
|         else: | ||||
|             self.value_renderer = self.value_renderer_factory(self) | ||||
|         self.set_value_renderer(value_renderer or self.value_renderer_factory) | ||||
|         self.default_active = default_active | ||||
|         self.default_verb = default_verb | ||||
|         self.default_value = default_value | ||||
|  | @ -130,6 +151,15 @@ class GridFilter(object): | |||
|             return verbs | ||||
|         return ['equal', 'not_equal', 'is_null', 'is_not_null'] | ||||
| 
 | ||||
|     def set_value_renderer(self, renderer): | ||||
|         """ | ||||
|         Set the value renderer for the filter, post-construction. | ||||
|         """ | ||||
|         if not isinstance(renderer, FilterValueRenderer): | ||||
|             renderer = renderer() | ||||
|         renderer.filter = self | ||||
|         self.value_renderer = renderer | ||||
| 
 | ||||
|     def filter(self, data, verb=None, value=UNSPECIFIED): | ||||
|         """ | ||||
|         Filter the given data set according to a verb/value pair.  If no verb | ||||
|  | @ -278,6 +308,7 @@ class AlchemyNumericFilter(AlchemyGridFilter): | |||
|     """ | ||||
|     Numeric filter for SQLAlchemy. | ||||
|     """ | ||||
|     value_renderer_factory = NumericValueRenderer | ||||
| 
 | ||||
|     def default_verbs(self): | ||||
|         """ | ||||
|  | @ -314,6 +345,13 @@ class AlchemyDateFilter(AlchemyGridFilter): | |||
|     """ | ||||
|     value_renderer_factory = DateValueRenderer | ||||
| 
 | ||||
|     def default_verbs(self): | ||||
|         """ | ||||
|         Expose greater-than / less-than verbs in addition to core. | ||||
|         """ | ||||
|         return ['equal', 'not_equal', 'greater_than', 'greater_equal', | ||||
|                 'less_than', 'less_equal', 'is_null', 'is_not_null'] | ||||
| 
 | ||||
|     def filter_is_true(self, query, value): | ||||
|         """ | ||||
|         Filter data with an "is true" query (alias for "is not null"). | ||||
|  |  | |||
							
								
								
									
										19
									
								
								tailbone/static/js/jquery.ui.tailbone.js
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								tailbone/static/js/jquery.ui.tailbone.js
									
										
									
									
										vendored
									
									
								
							|  | @ -250,6 +250,18 @@ | |||
|                 } | ||||
|             }); | ||||
| 
 | ||||
|             // Enhance any date values with datepicker widget.
 | ||||
|             this.inputs.find('.value input[type="date"]').datepicker({ | ||||
|                 dateFormat: 'yy-mm-dd', | ||||
|                 changeYear: true, | ||||
|                 changeMonth: true | ||||
|             }); | ||||
| 
 | ||||
|             // Enhance any choice/dropdown values with selectmenu.
 | ||||
|             this.inputs.find('.value select').selectmenu({ | ||||
|                 width: '15em' | ||||
|             }); | ||||
| 
 | ||||
|             // Listen for button click, to keep checkbox in sync.
 | ||||
|             this._on(this.activebutton, { | ||||
|                 click: function(e) { | ||||
|  | @ -269,6 +281,11 @@ | |||
|         refresh: function() { | ||||
|             if (this.checkbox.is(':checked')) { | ||||
|                 this.activebutton.button('option', 'icons', {primary: 'ui-icon-check'}); | ||||
|                 if (this.verb() in this.valueless_verbs) { | ||||
|                     this.inputs.find('.value').hide(); | ||||
|                 } else { | ||||
|                     this.inputs.find('.value').show(); | ||||
|                 } | ||||
|                 this.inputs.show(); | ||||
|             } else { | ||||
|                 this.activebutton.button('option', 'icons', {primary: 'ui-icon-blank'}); | ||||
|  | @ -312,7 +329,7 @@ | |||
|         }, | ||||
| 
 | ||||
|         value: function() { | ||||
|             return this.inputs.find('.value input').val(); | ||||
|             return this.inputs.find('.value input, .value select').val(); | ||||
|         }, | ||||
| 
 | ||||
|         verb: function() { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lance Edgar
						Lance Edgar