rails_jq_grid 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYRIGHT.txt +17 -0
- data/GPL-LICENSE +675 -0
- data/README.rdoc +176 -0
- data/Rakefile +47 -0
- data/VERSION +1 -0
- data/app/helpers/rails_jq_grid/jq_grid_css_helper.rb +29 -0
- data/app/helpers/rails_jq_grid/jq_grid_helper.rb +21 -0
- data/app/helpers/rails_jq_grid/jq_grid_js_helper.rb +30 -0
- data/app/models/rails_jq_grid/jq_grid.rb +315 -0
- data/app/models/rails_jq_grid/jq_grid_column.rb +33 -0
- data/app/models/rails_jq_grid/jq_grid_method_missing.rb +50 -0
- data/app/models/rails_jq_grid/jq_grid_option_or_method.rb +46 -0
- data/lib/rails_jq_grid/acts_as_jq_grid_able.rb +76 -0
- data/lib/rails_jq_grid/acts_as_jq_grid_data_source.rb +34 -0
- data/lib/rails_jq_grid/engine.rb +23 -0
- data/lib/rails_jq_grid.rb +7 -0
- data/lib/tasks/rails_jq_grid.rake +1 -0
- data/public/javascripts/rails-jqgrid/Changes.txt +1160 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-bg.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-bg1251.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-cat.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-cn.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-cs.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-de.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-dk.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-el.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-en.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-es.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-fa.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-fi.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-fr.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-he.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-hu.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-is.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-it.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-ja.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-nl.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-no.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-pl.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-pt-br.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-pt.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-ro.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-ru.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-sk.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-sv.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-tr.js +1 -0
- data/public/javascripts/rails-jqgrid/i18n/grid.locale-ua.js +1 -0
- data/public/javascripts/rails-jqgrid/install.txt +43 -0
- data/public/javascripts/rails-jqgrid/jquery-1.4.2.min.js +154 -0
- data/public/javascripts/rails-jqgrid/jquery-ui-1.8.4.custom.min.js +763 -0
- data/public/javascripts/rails-jqgrid/jquery.jqGrid.min.js +445 -0
- data/public/javascripts/rails-jqgrid/src/JsonXml.js +330 -0
- data/public/javascripts/rails-jqgrid/src/css/ellipsis-xbl.xml +13 -0
- data/public/javascripts/rails-jqgrid/src/css/jquery.searchFilter.css +7 -0
- data/public/javascripts/rails-jqgrid/src/css/ui.jqgrid.css +129 -0
- data/public/javascripts/rails-jqgrid/src/css/ui.multiselect.css +30 -0
- data/public/javascripts/rails-jqgrid/src/grid.base.js +3003 -0
- data/public/javascripts/rails-jqgrid/src/grid.celledit.js +486 -0
- data/public/javascripts/rails-jqgrid/src/grid.common.js +636 -0
- data/public/javascripts/rails-jqgrid/src/grid.custom.js +818 -0
- data/public/javascripts/rails-jqgrid/src/grid.formedit.js +1872 -0
- data/public/javascripts/rails-jqgrid/src/grid.import.js +201 -0
- data/public/javascripts/rails-jqgrid/src/grid.inlinedit.js +250 -0
- data/public/javascripts/rails-jqgrid/src/grid.jqueryui.js +503 -0
- data/public/javascripts/rails-jqgrid/src/grid.loader.js +47 -0
- data/public/javascripts/rails-jqgrid/src/grid.postext.js +64 -0
- data/public/javascripts/rails-jqgrid/src/grid.setcolumns.js +126 -0
- data/public/javascripts/rails-jqgrid/src/grid.subgrid.js +260 -0
- data/public/javascripts/rails-jqgrid/src/grid.tbltogrid.js +106 -0
- data/public/javascripts/rails-jqgrid/src/grid.treegrid.js +483 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-bg.js +132 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-bg1251.js +132 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-cat.js +128 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-cn.js +132 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-cs.js +128 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-de.js +128 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-dk.js +128 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-el.js +126 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-en.js +128 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-es.js +128 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-fa.js +125 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-fi.js +130 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-fr.js +126 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-he.js +127 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-hu.js +129 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-is.js +126 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-it.js +1 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-ja.js +155 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-nl.js +149 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-no.js +1 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-pl.js +127 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-pt-br.js +127 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-pt.js +125 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-ro.js +139 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-ru.js +127 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-sk.js +127 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-sv.js +127 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-tr.js +126 -0
- data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-ua.js +127 -0
- data/public/javascripts/rails-jqgrid/src/jqDnR.js +68 -0
- data/public/javascripts/rails-jqgrid/src/jqModal.js +69 -0
- data/public/javascripts/rails-jqgrid/src/jquery.fmatter.js +542 -0
- data/public/javascripts/rails-jqgrid/src/jquery.searchFilter.js +716 -0
- data/public/javascripts/rails-jqgrid/src/ui.multiselect.js +314 -0
- data/public/stylesheets/rails-jqgrid/ellipsis-xbl.xml +13 -0
- data/public/stylesheets/rails-jqgrid/themes/AUTHORS.txt +30 -0
- data/public/stylesheets/rails-jqgrid/themes/GPL-LICENSE.txt +278 -0
- data/public/stylesheets/rails-jqgrid/themes/MIT-LICENSE.txt +25 -0
- data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/smoothness/jquery-ui-1.8.4.custom.css +572 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_flat_55_999999_40x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_flat_75_aaaaaa_40x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_glass_45_0078ae_1x400.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_glass_55_f8da4e_1x400.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_glass_75_79c9ec_1x400.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_gloss-wave_45_e14f1c_500x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_gloss-wave_50_6eac2c_500x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_gloss-wave_75_2191c0_500x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-icons_0078ae_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-icons_056b93_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-icons_d8e7f3_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-icons_e0fdff_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-icons_f5e175_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-icons_f7a50d_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/images/ui-icons_fcd113_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/start/jquery-ui-1.8.4.custom.css +573 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_flat_30_cccccc_40x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_flat_50_5c5c5c_40x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_glass_20_555555_1x400.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_glass_40_0078a3_1x400.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_glass_40_ffc73d_1x400.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_gloss-wave_25_333333_500x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_highlight-soft_80_eeeeee_1x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_inset-soft_25_000000_1x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_inset-soft_30_f58400_1x100.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-icons_222222_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-icons_4b8e0b_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-icons_a83300_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-icons_cccccc_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-icons_ffffff_256x240.png +0 -0
- data/public/stylesheets/rails-jqgrid/themes/ui-darkness/jquery-ui-1.8.4.custom.css +572 -0
- data/public/stylesheets/rails-jqgrid/themes/version.txt +1 -0
- data/public/stylesheets/rails-jqgrid/ui.jqgrid.css +2 -0
- data/rails_jq_grid.gemspec +200 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +8 -0
- metadata +240 -0
@@ -0,0 +1,716 @@
|
|
1
|
+
/* Plugin: searchFilter v1.2.9
|
2
|
+
* Author: Kasey Speakman (kasey@cornerspeed.com)
|
3
|
+
* License: Dual Licensed, MIT and GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
4
|
+
*
|
5
|
+
* REQUIREMENTS:
|
6
|
+
* jQuery 1.3+ (http://jquery.com/)
|
7
|
+
* A Themeroller Theme (http://jqueryui.com/themeroller/)
|
8
|
+
*
|
9
|
+
* SECURITY WARNING
|
10
|
+
* You should always implement server-side checking to ensure that
|
11
|
+
* the query will fail when forged/invalid data is received.
|
12
|
+
* Clever users can send any value they want through JavaScript and HTTP POST/GET.
|
13
|
+
*
|
14
|
+
* THEMES
|
15
|
+
* Simply include the CSS file for your Themeroller theme.
|
16
|
+
*
|
17
|
+
* DESCRIPTION
|
18
|
+
* This plugin creates a new searchFilter object in the specified container
|
19
|
+
*
|
20
|
+
* INPUT TYPE
|
21
|
+
* fields: an array of field objects. each object has the following properties:
|
22
|
+
* text: a string containing the display name of the field (e.g. "Field 1")
|
23
|
+
* itemval: a string containing the actual field name (e.g. "field1")
|
24
|
+
* optional properties:
|
25
|
+
* ops: an array of operators in the same format as jQuery.fn.searchFilter.defaults.operators
|
26
|
+
* that is: [ { op: 'gt', text: 'greater than'}, { op:'lt', text: 'less than'}, ... ]
|
27
|
+
* if not specified, the passed-in options used, and failting that, jQuery.fn.searchFilter.defaults.operators will be used
|
28
|
+
* *** NOTE ***
|
29
|
+
* Specifying a dataUrl or dataValues property means that a <select ...> (drop-down-list) will be generated
|
30
|
+
* instead of a text input <input type='text'.../> where the user would normally type in their search data
|
31
|
+
* ************
|
32
|
+
* dataUrl: a url that will return the html select for this field, this url will only be called once for this field
|
33
|
+
* dataValues: the possible values for this field in the form [ { text: 'Data Display Text', value: 'data_actual_value' }, { ... } ]
|
34
|
+
* dataInit: a function that you can use to initialize the data field. this function is passed the jQuery-fied data element
|
35
|
+
* dataEvents: list of events to apply to the data element. uses $("#id").bind(type, [data], fn) to bind events to data element
|
36
|
+
* *** JSON of this object could look like this: ***
|
37
|
+
* var fields = [
|
38
|
+
* {
|
39
|
+
* text: 'Field Display Name',
|
40
|
+
* itemval: 'field_actual_name',
|
41
|
+
* // below this are optional values
|
42
|
+
* ops: [ // this format is the same as jQuery.fn.searchFilter.defaults.operators
|
43
|
+
* { op: 'gt', text: 'greater than' },
|
44
|
+
* { op: 'lt', text: 'less than' }
|
45
|
+
* ],
|
46
|
+
* dataUrl: 'http://server/path/script.php?propName=propValue', // using this creates a select for the data input instead of an input type='text'
|
47
|
+
* dataValues: [ // using this creates a select for the data input instead of an input type='text'
|
48
|
+
* { text: 'Data Value Display Name', value: 'data_actual_value' },
|
49
|
+
* { ... }
|
50
|
+
* ],
|
51
|
+
* dataInit: function(jElem) { jElem.datepicker(options); },
|
52
|
+
* dataEvents: [ // these are the same options that you pass to $("#id").bind(type, [data], fn)
|
53
|
+
* { type: 'click', data: { i: 7 }, fn: function(e) { console.log(e.data.i); } },
|
54
|
+
* { type: 'keypress', fn: function(e) { console.log('keypress'); } }
|
55
|
+
* ]
|
56
|
+
* },
|
57
|
+
* { ... }
|
58
|
+
* ]
|
59
|
+
* options: name:value properties containing various creation options
|
60
|
+
* see jQuery.fn.searchFilter.defaults for the overridable options
|
61
|
+
*
|
62
|
+
* RETURN TYPE: This plugin returns a SearchFilter object, which has additional SearchFilter methods:
|
63
|
+
* Methods
|
64
|
+
* add: Adds a filter. added to the end of the list unless a jQuery event object or valid row number is passed.
|
65
|
+
* del: Removes a filter. removed from the end of the list unless a jQuery event object or valid row number is passed.
|
66
|
+
* reset: resets filters back to original state (only one blank filter), and calls onReset
|
67
|
+
* search: puts the search rules into an object and calls onSearch with it
|
68
|
+
* close: calls the onClose event handler
|
69
|
+
*
|
70
|
+
* USAGE
|
71
|
+
* HTML
|
72
|
+
* <head>
|
73
|
+
* ...
|
74
|
+
* <script src="path/to/jquery.min.js" type="text/javascript"></script>
|
75
|
+
* <link href="path/to/themeroller.css" rel="Stylesheet" type="text/css" />
|
76
|
+
* <script src="path/to/jquery.searchFilter.js" type="text/javascript"></script>
|
77
|
+
* <link href="path/to/jquery.searchFilter.css" rel="Stylesheet" type="text/css" />
|
78
|
+
* ...
|
79
|
+
* </head>
|
80
|
+
* <body>
|
81
|
+
* ...
|
82
|
+
* <div id='mySearch'></div>
|
83
|
+
* ...
|
84
|
+
* </body>
|
85
|
+
* JQUERY
|
86
|
+
* Methods
|
87
|
+
* initializing: $("#mySearch").searchFilter([{text: "Field 1", value: "field1"},{text: "Field 2", value: "field2"}], {onSearch: myFilterRuleReceiverFn, onReset: myFilterResetFn });
|
88
|
+
* Manual Methods (there's no need to call these methods unless you are trying to manipulate searchFilter with script)
|
89
|
+
* add: $("#mySearch").searchFilter().add(); // appends a blank filter
|
90
|
+
* $("#mySearch").searchFilter().add(0); // copies the first filter as second
|
91
|
+
* del: $("#mySearch").searchFilter().del(); // removes the bottom filter
|
92
|
+
* $("#mySearch").searchFilter().del(1); // removes the second filter
|
93
|
+
* search: $("#mySearch").searchFilter().search(); // invokes onSearch, passing it a ruleGroup object
|
94
|
+
* reset: $("#mySearch").searchFilter().reset(); // resets rules and invokes onReset
|
95
|
+
* close: $("#mySearch").searchFilter().close(); // without an onClose handler, equivalent to $("#mySearch").hide();
|
96
|
+
*
|
97
|
+
* NOTE: You can get the jQuery object back from the SearchFilter object by chaining .$
|
98
|
+
* Example
|
99
|
+
* $("#mySearch").searchFilter().add().add().reset().$.hide();
|
100
|
+
* Verbose Example
|
101
|
+
* $("#mySearch") // gets jQuery object for the HTML element with id="mySearch"
|
102
|
+
* .searchFilter() // gets the SearchFilter object for an existing search filter
|
103
|
+
* .add() // adds a new filter to the end of the list
|
104
|
+
* .add() // adds another new filter to the end of the list
|
105
|
+
* .reset() // resets filters back to original state, triggers onReset
|
106
|
+
* .$ // returns jQuery object for $("#mySearch")
|
107
|
+
* .hide(); // equivalent to $("#mySearch").hide();
|
108
|
+
*/
|
109
|
+
|
110
|
+
jQuery.fn.searchFilter = function(fields, options) {
|
111
|
+
|
112
|
+
function SearchFilter(jQ, fields, options) {
|
113
|
+
|
114
|
+
|
115
|
+
//---------------------------------------------------------------
|
116
|
+
// PUBLIC VARS
|
117
|
+
//---------------------------------------------------------------
|
118
|
+
|
119
|
+
this.$ = jQ; // makes the jQuery object available as .$ from the return value
|
120
|
+
|
121
|
+
|
122
|
+
//---------------------------------------------------------------
|
123
|
+
// PUBLIC FUNCTIONS
|
124
|
+
//---------------------------------------------------------------
|
125
|
+
|
126
|
+
this.add = function(i) {
|
127
|
+
if (i == null) jQ.find(".ui-add-last").click();
|
128
|
+
else jQ.find(".sf:eq(" + i + ") .ui-add").click();
|
129
|
+
return this;
|
130
|
+
};
|
131
|
+
|
132
|
+
this.del = function(i) {
|
133
|
+
if (i == null) jQ.find(".sf:last .ui-del").click();
|
134
|
+
else jQ.find(".sf:eq(" + i + ") .ui-del").click();
|
135
|
+
return this;
|
136
|
+
};
|
137
|
+
|
138
|
+
this.search = function(e) {
|
139
|
+
jQ.find(".ui-search").click();
|
140
|
+
return this;
|
141
|
+
};
|
142
|
+
|
143
|
+
this.reset = function(o) {
|
144
|
+
if(o===undefined) o = false;
|
145
|
+
jQ.find(".ui-reset").trigger('click',[o]);
|
146
|
+
return this;
|
147
|
+
};
|
148
|
+
|
149
|
+
this.close = function() {
|
150
|
+
jQ.find(".ui-closer").click();
|
151
|
+
return this;
|
152
|
+
};
|
153
|
+
|
154
|
+
|
155
|
+
|
156
|
+
//---------------------------------------------------------------
|
157
|
+
// "CONSTRUCTOR" (in air quotes)
|
158
|
+
//---------------------------------------------------------------
|
159
|
+
|
160
|
+
if (fields != null) { // type coercion matches undefined as well as null
|
161
|
+
|
162
|
+
|
163
|
+
//---------------------------------------------------------------
|
164
|
+
// UTILITY FUNCTIONS
|
165
|
+
//---------------------------------------------------------------
|
166
|
+
|
167
|
+
function hover() {
|
168
|
+
jQuery(this).toggleClass("ui-state-hover");
|
169
|
+
return false;
|
170
|
+
}
|
171
|
+
|
172
|
+
function active(e) {
|
173
|
+
jQuery(this).toggleClass("ui-state-active", (e.type == "mousedown"));
|
174
|
+
return false;
|
175
|
+
}
|
176
|
+
|
177
|
+
function buildOpt(value, text) {
|
178
|
+
return "<option value='" + value + "'>" + text + "</option>";
|
179
|
+
}
|
180
|
+
|
181
|
+
function buildSel(className, options, isHidden) {
|
182
|
+
return "<select class='" + className + "'" + (isHidden ? " style='display:none;'" : "") + ">" + options + "</select>";
|
183
|
+
}
|
184
|
+
|
185
|
+
function initData(selector, fn) {
|
186
|
+
var jElem = jQ.find("tr.sf td.data " + selector);
|
187
|
+
if (jElem[0] != null)
|
188
|
+
fn(jElem);
|
189
|
+
}
|
190
|
+
|
191
|
+
function bindDataEvents(selector, events) {
|
192
|
+
var jElem = jQ.find("tr.sf td.data " + selector);
|
193
|
+
if (jElem[0] != null) {
|
194
|
+
jQuery.each(events, function() {
|
195
|
+
if (this.data != null)
|
196
|
+
jElem.bind(this.type, this.data, this.fn);
|
197
|
+
else
|
198
|
+
jElem.bind(this.type, this.fn);
|
199
|
+
});
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
|
204
|
+
//---------------------------------------------------------------
|
205
|
+
// SUPER IMPORTANT PRIVATE VARS
|
206
|
+
//---------------------------------------------------------------
|
207
|
+
|
208
|
+
// copies jQuery.fn.searchFilter.defaults.options properties onto an empty object, then options onto that
|
209
|
+
var opts = jQuery.extend({}, jQuery.fn.searchFilter.defaults, options);
|
210
|
+
|
211
|
+
// this is keeps track of the last asynchronous setup
|
212
|
+
var highest_late_setup = -1;
|
213
|
+
|
214
|
+
|
215
|
+
//---------------------------------------------------------------
|
216
|
+
// CREATION PROCESS STARTS
|
217
|
+
//---------------------------------------------------------------
|
218
|
+
|
219
|
+
// generate the global ops
|
220
|
+
var gOps_html = "";
|
221
|
+
jQuery.each(opts.groupOps, function() { gOps_html += buildOpt(this.op, this.text); });
|
222
|
+
gOps_html = "<select name='groupOp'>" + gOps_html + "</select>";
|
223
|
+
|
224
|
+
/* original content - doesn't minify very well
|
225
|
+
jQ
|
226
|
+
.html("") // clear any old content
|
227
|
+
.addClass("ui-searchFilter") // add classes
|
228
|
+
.append( // add content
|
229
|
+
"\
|
230
|
+
<div class='ui-widget-overlay' style='z-index: -1'> </div>\
|
231
|
+
<table class='ui-widget-content ui-corner-all'>\
|
232
|
+
<thead>\
|
233
|
+
<tr>\
|
234
|
+
<td colspan='5' class='ui-widget-header ui-corner-all' style='line-height: 18px;'>\
|
235
|
+
<div class='ui-closer ui-state-default ui-corner-all ui-helper-clearfix' style='float: right;'>\
|
236
|
+
<span class='ui-icon ui-icon-close'></span>\
|
237
|
+
</div>\
|
238
|
+
" + opts.windowTitle + "\
|
239
|
+
</td>\
|
240
|
+
</tr>\
|
241
|
+
</thead>\
|
242
|
+
<tbody>\
|
243
|
+
<tr class='sf'>\
|
244
|
+
<td class='fields'></td>\
|
245
|
+
<td class='ops'></td>\
|
246
|
+
<td class='data'></td>\
|
247
|
+
<td><div class='ui-del ui-state-default ui-corner-all'><span class='ui-icon ui-icon-minus'></span></div></td>\
|
248
|
+
<td><div class='ui-add ui-state-default ui-corner-all'><span class='ui-icon ui-icon-plus'></span></div></td>\
|
249
|
+
</tr>\
|
250
|
+
<tr>\
|
251
|
+
<td colspan='5' class='divider'><div> </div></td>\
|
252
|
+
</tr>\
|
253
|
+
</tbody>\
|
254
|
+
<tfoot>\
|
255
|
+
<tr>\
|
256
|
+
<td colspan='3'>\
|
257
|
+
<span class='ui-reset ui-state-default ui-corner-all' style='display: inline-block; float: left;'><span class='ui-icon ui-icon-arrowreturnthick-1-w' style='float: left;'></span><span style='line-height: 18px; padding: 0 7px 0 3px;'>" + opts.resetText + "</span></span>\
|
258
|
+
<span class='ui-search ui-state-default ui-corner-all' style='display: inline-block; float: right;'><span class='ui-icon ui-icon-search' style='float: left;'></span><span style='line-height: 18px; padding: 0 7px 0 3px;'>" + opts.searchText + "</span></span>\
|
259
|
+
<span class='matchText'>" + opts.matchText + "</span> \
|
260
|
+
" + gOps_html + " \
|
261
|
+
<span class='rulesText'>" + opts.rulesText + "</span>\
|
262
|
+
</td>\
|
263
|
+
<td> </td>\
|
264
|
+
<td><div class='ui-add-last ui-state-default ui-corner-all'><span class='ui-icon ui-icon-plusthick'></span></div></td>\
|
265
|
+
</tr>\
|
266
|
+
</tfoot>\
|
267
|
+
</table>\
|
268
|
+
");
|
269
|
+
/* end hard-to-minify code */
|
270
|
+
/* begin easier to minify code */
|
271
|
+
jQ.html("").addClass("ui-searchFilter").append("<div class='ui-widget-overlay' style='z-index: -1'> </div><table class='ui-widget-content ui-corner-all'><thead><tr><td colspan='5' class='ui-widget-header ui-corner-all' style='line-height: 18px;'><div class='ui-closer ui-state-default ui-corner-all ui-helper-clearfix' style='float: right;'><span class='ui-icon ui-icon-close'></span></div>" + opts.windowTitle + "</td></tr></thead><tbody><tr class='sf'><td class='fields'></td><td class='ops'></td><td class='data'></td><td><div class='ui-del ui-state-default ui-corner-all'><span class='ui-icon ui-icon-minus'></span></div></td><td><div class='ui-add ui-state-default ui-corner-all'><span class='ui-icon ui-icon-plus'></span></div></td></tr><tr><td colspan='5' class='divider'><div> </div></td></tr></tbody><tfoot><tr><td colspan='3'><span class='ui-reset ui-state-default ui-corner-all' style='display: inline-block; float: left;'><span class='ui-icon ui-icon-arrowreturnthick-1-w' style='float: left;'></span><span style='line-height: 18px; padding: 0 7px 0 3px;'>" + opts.resetText + "</span></span><span class='ui-search ui-state-default ui-corner-all' style='display: inline-block; float: right;'><span class='ui-icon ui-icon-search' style='float: left;'></span><span style='line-height: 18px; padding: 0 7px 0 3px;'>" + opts.searchText + "</span></span><span class='matchText'>" + opts.matchText + "</span> " + gOps_html + " <span class='rulesText'>" + opts.rulesText + "</span></td><td> </td><td><div class='ui-add-last ui-state-default ui-corner-all'><span class='ui-icon ui-icon-plusthick'></span></div></td></tr></tfoot></table>");
|
272
|
+
/* end easier-to-minify code */
|
273
|
+
|
274
|
+
var jRow = jQ.find("tr.sf");
|
275
|
+
var jFields = jRow.find("td.fields");
|
276
|
+
var jOps = jRow.find("td.ops");
|
277
|
+
var jData = jRow.find("td.data");
|
278
|
+
|
279
|
+
// generate the defaults
|
280
|
+
var default_ops_html = "";
|
281
|
+
jQuery.each(opts.operators, function() { default_ops_html += buildOpt(this.op, this.text); });
|
282
|
+
default_ops_html = buildSel("default", default_ops_html, true);
|
283
|
+
jOps.append(default_ops_html);
|
284
|
+
var default_data_html = "<input type='text' class='default' style='display:none;' />";
|
285
|
+
jData.append(default_data_html);
|
286
|
+
|
287
|
+
// generate the field list as a string
|
288
|
+
var fields_html = "";
|
289
|
+
var has_custom_ops = false;
|
290
|
+
var has_custom_data = false;
|
291
|
+
jQuery.each(fields, function(i) {
|
292
|
+
var field_num = i;
|
293
|
+
fields_html += buildOpt(this.itemval, this.text);
|
294
|
+
// add custom ops if they exist
|
295
|
+
if (this.ops != null) {
|
296
|
+
has_custom_ops = true;
|
297
|
+
var custom_ops = "";
|
298
|
+
jQuery.each(this.ops, function() { custom_ops += buildOpt(this.op, this.text); });
|
299
|
+
custom_ops = buildSel("field" + field_num, custom_ops, true);
|
300
|
+
jOps.append(custom_ops);
|
301
|
+
}
|
302
|
+
// add custom data if it is given
|
303
|
+
if (this.dataUrl != null) {
|
304
|
+
if (i > highest_late_setup) highest_late_setup = i;
|
305
|
+
has_custom_data = true;
|
306
|
+
var dEvents = this.dataEvents;
|
307
|
+
var iEvent = this.dataInit;
|
308
|
+
var bs = this.buildSelect;
|
309
|
+
jQuery.ajax(jQuery.extend({
|
310
|
+
url : this.dataUrl,
|
311
|
+
complete: function(data) {
|
312
|
+
var $d;
|
313
|
+
if(bs != null) $d =jQuery("<div />").append(bs(data));
|
314
|
+
else $d = jQuery("<div />").append(data.responseText);
|
315
|
+
$d.find("select").addClass("field" + field_num).hide();
|
316
|
+
jData.append($d.html());
|
317
|
+
if (iEvent) initData(".field" + i, iEvent);
|
318
|
+
if (dEvents) bindDataEvents(".field" + i, dEvents);
|
319
|
+
if (i == highest_late_setup) { // change should get called no more than twice when this searchFilter is constructed
|
320
|
+
jQ.find("tr.sf td.fields select[name='field']").change();
|
321
|
+
}
|
322
|
+
}
|
323
|
+
},opts.ajaxSelectOptions));
|
324
|
+
} else if (this.dataValues != null) {
|
325
|
+
has_custom_data = true;
|
326
|
+
var custom_data = "";
|
327
|
+
jQuery.each(this.dataValues, function() { custom_data += buildOpt(this.value, this.text); });
|
328
|
+
custom_data = buildSel("field" + field_num, custom_data, true);
|
329
|
+
jData.append(custom_data);
|
330
|
+
} else if (this.dataEvents != null || this.dataInit != null) {
|
331
|
+
has_custom_data = true;
|
332
|
+
var custom_data = "<input type='text' class='field" + field_num + "' />";
|
333
|
+
jData.append(custom_data);
|
334
|
+
}
|
335
|
+
// attach events to data if they exist
|
336
|
+
if (this.dataInit != null && i != highest_late_setup)
|
337
|
+
initData(".field" + i, this.dataInit);
|
338
|
+
if (this.dataEvents != null && i != highest_late_setup)
|
339
|
+
bindDataEvents(".field" + i, this.dataEvents);
|
340
|
+
});
|
341
|
+
fields_html = "<select name='field'>" + fields_html + "</select>";
|
342
|
+
jFields.append(fields_html);
|
343
|
+
|
344
|
+
// setup the field select with an on-change event if there are custom ops or data
|
345
|
+
var jFSelect = jFields.find("select[name='field']");
|
346
|
+
if (has_custom_ops) jFSelect.change(function(e) {
|
347
|
+
var index = e.target.selectedIndex;
|
348
|
+
var td = jQuery(e.target).parents("tr.sf").find("td.ops");
|
349
|
+
td.find("select").removeAttr("name").hide(); // disown and hide all elements
|
350
|
+
var jElem = td.find(".field" + index);
|
351
|
+
if (jElem[0] == null) jElem = td.find(".default"); // if there's not an element for that field, use the default one
|
352
|
+
jElem.attr("name", "op").show();
|
353
|
+
return false;
|
354
|
+
});
|
355
|
+
else jOps.find(".default").attr("name", "op").show();
|
356
|
+
if (has_custom_data) jFSelect.change(function(e) {
|
357
|
+
var index = e.target.selectedIndex;
|
358
|
+
var td = jQuery(e.target).parents("tr.sf").find("td.data");
|
359
|
+
td.find("select,input").removeClass("vdata").hide(); // disown and hide all elements
|
360
|
+
var jElem = td.find(".field" + index);
|
361
|
+
if (jElem[0] == null) jElem = td.find(".default"); // if there's not an element for that field, use the default one
|
362
|
+
jElem.show().addClass("vdata");
|
363
|
+
return false;
|
364
|
+
});
|
365
|
+
else jData.find(".default").show().addClass("vdata");
|
366
|
+
// go ahead and call the change event and setup the ops and data values
|
367
|
+
if (has_custom_ops || has_custom_data) jFSelect.change();
|
368
|
+
|
369
|
+
// bind events
|
370
|
+
jQ.find(".ui-state-default").hover(hover, hover).mousedown(active).mouseup(active); // add hover/active effects to all buttons
|
371
|
+
jQ.find(".ui-closer").click(function(e) {
|
372
|
+
opts.onClose(jQuery(jQ.selector));
|
373
|
+
return false;
|
374
|
+
});
|
375
|
+
jQ.find(".ui-del").click(function(e) {
|
376
|
+
var row = jQuery(e.target).parents(".sf");
|
377
|
+
if (row.siblings(".sf").length > 0) { // doesn't remove if there's only one filter left
|
378
|
+
if (opts.datepickerFix === true && jQuery.fn.datepicker !== undefined)
|
379
|
+
row.find(".hasDatepicker").datepicker("destroy"); // clean up datepicker's $.data mess
|
380
|
+
row.remove(); // also unbinds
|
381
|
+
} else { // resets the filter if it's the last one
|
382
|
+
row.find("select[name='field']")[0].selectedIndex = 0;
|
383
|
+
row.find("select[name='op']")[0].selectedIndex = 0;
|
384
|
+
row.find(".data input").val(""); // blank all input values
|
385
|
+
row.find(".data select").each(function() { this.selectedIndex = 0; }); // select first option on all selects
|
386
|
+
row.find("select[name='field']").change(function(event){event.stopPropagation();}); // trigger any change events
|
387
|
+
}
|
388
|
+
return false;
|
389
|
+
});
|
390
|
+
jQ.find(".ui-add").click(function(e) {
|
391
|
+
var row = jQuery(e.target).parents(".sf");
|
392
|
+
var newRow = row.clone(true).insertAfter(row);
|
393
|
+
newRow.find(".ui-state-default").removeClass("ui-state-hover ui-state-active");
|
394
|
+
if (opts.clone) {
|
395
|
+
newRow.find("select[name='field']")[0].selectedIndex = row.find("select[name='field']")[0].selectedIndex;
|
396
|
+
var stupid_browser = (newRow.find("select[name='op']")[0] == null); // true for IE6
|
397
|
+
if (!stupid_browser)
|
398
|
+
newRow.find("select[name='op']").focus()[0].selectedIndex = row.find("select[name='op']")[0].selectedIndex;
|
399
|
+
var jElem = newRow.find("select.vdata");
|
400
|
+
if (jElem[0] != null) // select doesn't copy it's selected index when cloned
|
401
|
+
jElem[0].selectedIndex = row.find("select.vdata")[0].selectedIndex;
|
402
|
+
} else {
|
403
|
+
newRow.find(".data input").val(""); // blank all input values
|
404
|
+
newRow.find("select[name='field']").focus();
|
405
|
+
}
|
406
|
+
if (opts.datepickerFix === true && jQuery.fn.datepicker !== undefined) { // using $.data to associate data with document elements is Not Good
|
407
|
+
row.find(".hasDatepicker").each(function() {
|
408
|
+
var settings = jQuery.data(this, "datepicker").settings;
|
409
|
+
newRow.find("#" + this.id).unbind().removeAttr("id").removeClass("hasDatepicker").datepicker(settings);
|
410
|
+
});
|
411
|
+
}
|
412
|
+
newRow.find("select[name='field']").change(function(event){event.stopPropagation();} );
|
413
|
+
return false;
|
414
|
+
});
|
415
|
+
jQ.find(".ui-search").click(function(e) {
|
416
|
+
var ui = jQuery(jQ.selector); // pointer to search box wrapper element
|
417
|
+
var ruleGroup;
|
418
|
+
var group_op = ui.find("select[name='groupOp'] :selected").val(); // puls "AND" or "OR"
|
419
|
+
if (!opts.stringResult) {
|
420
|
+
ruleGroup = {
|
421
|
+
groupOp: group_op,
|
422
|
+
rules: []
|
423
|
+
};
|
424
|
+
} else {
|
425
|
+
ruleGroup = "{\"groupOp\":\"" + group_op + "\",\"rules\":[";
|
426
|
+
}
|
427
|
+
ui.find(".sf").each(function(i) {
|
428
|
+
var tField = jQuery(this).find("select[name='field'] :selected").val();
|
429
|
+
var tOp = jQuery(this).find("select[name='op'] :selected").val();
|
430
|
+
var tData = jQuery(this).find("input.vdata,select.vdata :selected").val();
|
431
|
+
tData += "";
|
432
|
+
tData = tData.replace(/\\/g,'\\\\').replace(/\"/g,'\\"');
|
433
|
+
if (!opts.stringResult) {
|
434
|
+
ruleGroup.rules.push({
|
435
|
+
field: tField,
|
436
|
+
op: tOp,
|
437
|
+
data: tData
|
438
|
+
});
|
439
|
+
} else {
|
440
|
+
if (i > 0) ruleGroup += ",";
|
441
|
+
ruleGroup += "{\"field\":\"" + tField + "\",";
|
442
|
+
ruleGroup += "\"op\":\"" + tOp + "\",";
|
443
|
+
ruleGroup += "\"data\":\"" + tData + "\"}";
|
444
|
+
}
|
445
|
+
});
|
446
|
+
if (opts.stringResult) ruleGroup += "]}";
|
447
|
+
opts.onSearch(ruleGroup);
|
448
|
+
return false;
|
449
|
+
});
|
450
|
+
jQ.find(".ui-reset").click(function(e,op) {
|
451
|
+
var ui = jQuery(jQ.selector);
|
452
|
+
ui.find(".ui-del").click(); // removes all filters, resets the last one
|
453
|
+
ui.find("select[name='groupOp']")[0].selectedIndex = 0; // changes the op back to the default one
|
454
|
+
opts.onReset(op);
|
455
|
+
return false;
|
456
|
+
});
|
457
|
+
jQ.find(".ui-add-last").click(function() {
|
458
|
+
var row = jQuery(jQ.selector + " .sf:last");
|
459
|
+
var newRow = row.clone(true).insertAfter(row);
|
460
|
+
newRow.find(".ui-state-default").removeClass("ui-state-hover ui-state-active");
|
461
|
+
newRow.find(".data input").val(""); // blank all input values
|
462
|
+
newRow.find("select[name='field']").focus();
|
463
|
+
if (opts.datepickerFix === true && jQuery.fn.datepicker !== undefined) { // using $.data to associate data with document elements is Not Good
|
464
|
+
row.find(".hasDatepicker").each(function() {
|
465
|
+
var settings = jQuery.data(this, "datepicker").settings;
|
466
|
+
newRow.find("#" + this.id).unbind().removeAttr("id").removeClass("hasDatepicker").datepicker(settings);
|
467
|
+
});
|
468
|
+
}
|
469
|
+
newRow.find("select[name='field']").change(function(event){event.stopPropagation();});
|
470
|
+
return false;
|
471
|
+
});
|
472
|
+
|
473
|
+
this.setGroupOp = function(setting) {
|
474
|
+
/* a "setter" for groupping argument.
|
475
|
+
* ("AND" or "OR")
|
476
|
+
*
|
477
|
+
* Inputs:
|
478
|
+
* setting - a string
|
479
|
+
*
|
480
|
+
* Returns:
|
481
|
+
* Does not return anything. May add success / failure reporting in future versions.
|
482
|
+
*
|
483
|
+
* author: Daniel Dotsenko (dotsa@hotmail.com)
|
484
|
+
*/
|
485
|
+
selDOMobj = jQ.find("select[name='groupOp']")[0];
|
486
|
+
var indexmap = {}, l = selDOMobj.options.length, i;
|
487
|
+
for (i=0; i<l; i++) {
|
488
|
+
indexmap[selDOMobj.options[i].value] = i;
|
489
|
+
}
|
490
|
+
selDOMobj.selectedIndex = indexmap[setting];
|
491
|
+
jQuery(selDOMobj).change(function(event){event.stopPropagation();});
|
492
|
+
};
|
493
|
+
|
494
|
+
this.setFilter = function(settings) {
|
495
|
+
/* a "setter" for an arbitrary SearchFilter's filter line.
|
496
|
+
* designed to abstract the DOM manipulations required to infer
|
497
|
+
* a particular filter is a fit to the search box.
|
498
|
+
*
|
499
|
+
* Inputs:
|
500
|
+
* settings - an "object" (dictionary)
|
501
|
+
* index (optional*) (to be implemented in the future) : signed integer index (from top to bottom per DOM) of the filter line to fill.
|
502
|
+
* Negative integers (rooted in -1 and lower) denote position of the line from the bottom.
|
503
|
+
* sfref (optional*) : DOM object referencing individual '.sf' (normally a TR element) to be populated. (optional)
|
504
|
+
* filter (mandatory) : object (dictionary) of form {'field':'field_value','op':'op_value','data':'data value'}
|
505
|
+
*
|
506
|
+
* * It is mandatory to have either index or sfref defined.
|
507
|
+
*
|
508
|
+
* Returns:
|
509
|
+
* Does not return anything. May add success / failure reporting in future versions.
|
510
|
+
*
|
511
|
+
* author: Daniel Dotsenko (dotsa@hotmail.com)
|
512
|
+
*/
|
513
|
+
|
514
|
+
var o = settings['sfref'], filter = settings['filter'];
|
515
|
+
|
516
|
+
// setting up valueindexmap that we will need to manipulate SELECT elements.
|
517
|
+
var fields = [], i, j , l, lj, li,
|
518
|
+
valueindexmap = {};
|
519
|
+
// example of valueindexmap:
|
520
|
+
// {'field1':{'index':0,'ops':{'eq':0,'ne':1}},'fieldX':{'index':1,'ops':{'eq':0,'ne':1},'data':{'true':0,'false':1}}},
|
521
|
+
// if data is undefined it's a INPUT field. If defined, it's SELECT
|
522
|
+
selDOMobj = o.find("select[name='field']")[0];
|
523
|
+
for (i=0, l=selDOMobj.options.length; i<l; i++) {
|
524
|
+
valueindexmap[selDOMobj.options[i].value] = {'index':i,'ops':{}};
|
525
|
+
fields.push(selDOMobj.options[i].value);
|
526
|
+
}
|
527
|
+
for (i=0, li=fields.length; i < li; i++) {
|
528
|
+
selDOMobj = o.find(".ops > select[class='field"+i+"']")[0];
|
529
|
+
if (selDOMobj) {
|
530
|
+
for (j=0, lj=selDOMobj.options.length; j<lj; j++) {
|
531
|
+
valueindexmap[fields[i]]['ops'][selDOMobj.options[j].value] = j;
|
532
|
+
}
|
533
|
+
}
|
534
|
+
selDOMobj = o.find(".data > select[class='field"+i+"']")[0];
|
535
|
+
if (selDOMobj) {
|
536
|
+
valueindexmap[fields[i]]['data'] = {}; // this setting is the flag that 'data' is contained in a SELECT
|
537
|
+
for (j=0, lj=selDOMobj.options.length; j<lj; j++) {
|
538
|
+
valueindexmap[fields[i]]['data'][selDOMobj.options[j].value] = j;
|
539
|
+
}
|
540
|
+
}
|
541
|
+
} // done populating valueindexmap
|
542
|
+
|
543
|
+
// preparsing the index values for SELECT elements.
|
544
|
+
var fieldvalue, fieldindex, opindex, datavalue, dataindex;
|
545
|
+
fieldvalue = filter['field'];
|
546
|
+
if (valueindexmap[fieldvalue]) {
|
547
|
+
fieldindex = valueindexmap[fieldvalue]['index'];
|
548
|
+
}
|
549
|
+
if (fieldindex != null) {
|
550
|
+
opindex = valueindexmap[fieldvalue]['ops'][filter['op']];
|
551
|
+
if(opindex === undefined) {
|
552
|
+
for(i=0,li=options.operators.length; i<li;i++) {
|
553
|
+
if(options.operators[i].op == filter.op ){
|
554
|
+
opindex = i;
|
555
|
+
break;
|
556
|
+
}
|
557
|
+
}
|
558
|
+
}
|
559
|
+
datavalue = filter['data'];
|
560
|
+
if (valueindexmap[fieldvalue]['data'] == null) {
|
561
|
+
dataindex = -1; // 'data' is not SELECT, Making the var 'defined'
|
562
|
+
} else {
|
563
|
+
dataindex = valueindexmap[fieldvalue]['data'][datavalue]; // 'undefined' may come from here.
|
564
|
+
}
|
565
|
+
}
|
566
|
+
// only if values for 'field' and 'op' and 'data' are 'found' in mapping...
|
567
|
+
if (fieldindex != null && opindex != null && dataindex != null) {
|
568
|
+
o.find("select[name='field']")[0].selectedIndex = fieldindex;
|
569
|
+
o.find("select[name='field']").change();
|
570
|
+
o.find("select[name='op']")[0].selectedIndex = opindex;
|
571
|
+
o.find("input.vdata").val(datavalue); // if jquery does not find any INPUT, it does not set any. This means we deal with SELECT
|
572
|
+
o = o.find("select.vdata")[0];
|
573
|
+
if (o) {
|
574
|
+
o.selectedIndex = dataindex;
|
575
|
+
}
|
576
|
+
return true
|
577
|
+
} else {
|
578
|
+
return false
|
579
|
+
}
|
580
|
+
}; // end of this.setFilter fn
|
581
|
+
} // end of if fields != null
|
582
|
+
}
|
583
|
+
return new SearchFilter(this, fields, options);
|
584
|
+
};
|
585
|
+
|
586
|
+
jQuery.fn.searchFilter.version = '1.2.9';
|
587
|
+
|
588
|
+
/* This property contains the default options */
|
589
|
+
jQuery.fn.searchFilter.defaults = {
|
590
|
+
|
591
|
+
/*
|
592
|
+
* PROPERTY
|
593
|
+
* TYPE: boolean
|
594
|
+
* DESCRIPTION: clone a row if it is added from an existing row
|
595
|
+
* when false, any new added rows will be blank.
|
596
|
+
*/
|
597
|
+
clone: true,
|
598
|
+
|
599
|
+
/*
|
600
|
+
* PROPERTY
|
601
|
+
* TYPE: boolean
|
602
|
+
* DESCRIPTION: current version of datepicker uses a data store,
|
603
|
+
* which is incompatible with $().clone(true)
|
604
|
+
*/
|
605
|
+
datepickerFix: true,
|
606
|
+
|
607
|
+
/*
|
608
|
+
* FUNCTION
|
609
|
+
* DESCRIPTION: the function that will be called when the user clicks Reset
|
610
|
+
* INPUT TYPE: JS object if stringResult is false, otherwise is JSON string
|
611
|
+
*/
|
612
|
+
onReset: function(data) { alert("Reset Clicked. Data Returned: " + data) },
|
613
|
+
|
614
|
+
/*
|
615
|
+
* FUNCTION
|
616
|
+
* DESCRIPTION: the function that will be called when the user clicks Search
|
617
|
+
* INPUT TYPE: JS object if stringResult is false, otherwise is JSON string
|
618
|
+
*/
|
619
|
+
onSearch: function(data) { alert("Search Clicked. Data Returned: " + data) },
|
620
|
+
|
621
|
+
/*
|
622
|
+
* FUNCTION
|
623
|
+
* DESCRIPTION: the function that will be called when the user clicks the Closer icon
|
624
|
+
* or the close() function is called
|
625
|
+
* if left null, it simply does a .hide() on the searchFilter
|
626
|
+
* INPUT TYPE: a jQuery object for the searchFilter
|
627
|
+
*/
|
628
|
+
onClose: function(jElem) { jElem.hide(); },
|
629
|
+
|
630
|
+
/*
|
631
|
+
* PROPERTY
|
632
|
+
* TYPE: array of objects, each object has the properties op and text
|
633
|
+
* DESCRIPTION: the selectable operators that are applied between rules
|
634
|
+
* e.g. for {op:"AND", text:"all"}
|
635
|
+
* the search filter box will say: match all rules
|
636
|
+
* the server should interpret this as putting the AND op between each rule:
|
637
|
+
* rule1 AND rule2 AND rule3
|
638
|
+
* text will be the option text, and op will be the option value
|
639
|
+
*/
|
640
|
+
groupOps: [
|
641
|
+
{ op: "AND", text: "all" },
|
642
|
+
{ op: "OR", text: "any" }
|
643
|
+
],
|
644
|
+
|
645
|
+
|
646
|
+
/*
|
647
|
+
* PROPERTY
|
648
|
+
* TYPE: array of objects, each object has the properties op and text
|
649
|
+
* DESCRIPTION: the operators that will appear as drop-down options
|
650
|
+
* text will be the option text, and op will be the option value
|
651
|
+
*/
|
652
|
+
operators: [
|
653
|
+
{ op: "eq", text: "is equal to" },
|
654
|
+
{ op: "ne", text: "is not equal to" },
|
655
|
+
{ op: "lt", text: "is less than" },
|
656
|
+
{ op: "le", text: "is less or equal to" },
|
657
|
+
{ op: "gt", text: "is greater than" },
|
658
|
+
{ op: "ge", text: "is greater or equal to" },
|
659
|
+
{ op: "in", text: "is in" },
|
660
|
+
{ op: "ni", text: "is not in" },
|
661
|
+
{ op: "bw", text: "begins with" },
|
662
|
+
{ op: "bn", text: "does not begin with" },
|
663
|
+
{ op: "ew", text: "ends with" },
|
664
|
+
{ op: "en", text: "does not end with" },
|
665
|
+
{ op: "cn", text: "contains" },
|
666
|
+
{ op: "nc", text: "does not contain" }
|
667
|
+
],
|
668
|
+
|
669
|
+
/*
|
670
|
+
* PROPERTY
|
671
|
+
* TYPE: string
|
672
|
+
* DESCRIPTION: part of the phrase: _match_ ANY/ALL rules
|
673
|
+
*/
|
674
|
+
matchText: "match",
|
675
|
+
|
676
|
+
/*
|
677
|
+
* PROPERTY
|
678
|
+
* TYPE: string
|
679
|
+
* DESCRIPTION: part of the phrase: match ANY/ALL _rules_
|
680
|
+
*/
|
681
|
+
rulesText: "rules",
|
682
|
+
|
683
|
+
/*
|
684
|
+
* PROPERTY
|
685
|
+
* TYPE: string
|
686
|
+
* DESCRIPTION: the text that will be displayed in the reset button
|
687
|
+
*/
|
688
|
+
resetText: "Reset",
|
689
|
+
|
690
|
+
/*
|
691
|
+
* PROPERTY
|
692
|
+
* TYPE: string
|
693
|
+
* DESCRIPTION: the text that will be displayed in the search button
|
694
|
+
*/
|
695
|
+
searchText: "Search",
|
696
|
+
|
697
|
+
/*
|
698
|
+
* PROPERTY
|
699
|
+
* TYPE: boolean
|
700
|
+
* DESCRIPTION: a flag that, when set, will make the onSearch and onReset return strings instead of objects
|
701
|
+
*/
|
702
|
+
stringResult: true,
|
703
|
+
|
704
|
+
/*
|
705
|
+
* PROPERTY
|
706
|
+
* TYPE: string
|
707
|
+
* DESCRIPTION: the title of the searchFilter window
|
708
|
+
*/
|
709
|
+
windowTitle: "Search Rules",
|
710
|
+
/*
|
711
|
+
* PROPERTY
|
712
|
+
* TYPE: object
|
713
|
+
* DESCRIPTION: options to extend the ajax request
|
714
|
+
*/
|
715
|
+
ajaxSelectOptions : {}
|
716
|
+
}; /* end of searchFilter */
|