rails_jq_grid 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. data/COPYRIGHT.txt +17 -0
  2. data/GPL-LICENSE +675 -0
  3. data/README.rdoc +176 -0
  4. data/Rakefile +47 -0
  5. data/VERSION +1 -0
  6. data/app/helpers/rails_jq_grid/jq_grid_css_helper.rb +29 -0
  7. data/app/helpers/rails_jq_grid/jq_grid_helper.rb +21 -0
  8. data/app/helpers/rails_jq_grid/jq_grid_js_helper.rb +30 -0
  9. data/app/models/rails_jq_grid/jq_grid.rb +315 -0
  10. data/app/models/rails_jq_grid/jq_grid_column.rb +33 -0
  11. data/app/models/rails_jq_grid/jq_grid_method_missing.rb +50 -0
  12. data/app/models/rails_jq_grid/jq_grid_option_or_method.rb +46 -0
  13. data/lib/rails_jq_grid/acts_as_jq_grid_able.rb +76 -0
  14. data/lib/rails_jq_grid/acts_as_jq_grid_data_source.rb +34 -0
  15. data/lib/rails_jq_grid/engine.rb +23 -0
  16. data/lib/rails_jq_grid.rb +7 -0
  17. data/lib/tasks/rails_jq_grid.rake +1 -0
  18. data/public/javascripts/rails-jqgrid/Changes.txt +1160 -0
  19. data/public/javascripts/rails-jqgrid/i18n/grid.locale-bg.js +1 -0
  20. data/public/javascripts/rails-jqgrid/i18n/grid.locale-bg1251.js +1 -0
  21. data/public/javascripts/rails-jqgrid/i18n/grid.locale-cat.js +1 -0
  22. data/public/javascripts/rails-jqgrid/i18n/grid.locale-cn.js +1 -0
  23. data/public/javascripts/rails-jqgrid/i18n/grid.locale-cs.js +1 -0
  24. data/public/javascripts/rails-jqgrid/i18n/grid.locale-de.js +1 -0
  25. data/public/javascripts/rails-jqgrid/i18n/grid.locale-dk.js +1 -0
  26. data/public/javascripts/rails-jqgrid/i18n/grid.locale-el.js +1 -0
  27. data/public/javascripts/rails-jqgrid/i18n/grid.locale-en.js +1 -0
  28. data/public/javascripts/rails-jqgrid/i18n/grid.locale-es.js +1 -0
  29. data/public/javascripts/rails-jqgrid/i18n/grid.locale-fa.js +1 -0
  30. data/public/javascripts/rails-jqgrid/i18n/grid.locale-fi.js +1 -0
  31. data/public/javascripts/rails-jqgrid/i18n/grid.locale-fr.js +1 -0
  32. data/public/javascripts/rails-jqgrid/i18n/grid.locale-he.js +1 -0
  33. data/public/javascripts/rails-jqgrid/i18n/grid.locale-hu.js +1 -0
  34. data/public/javascripts/rails-jqgrid/i18n/grid.locale-is.js +1 -0
  35. data/public/javascripts/rails-jqgrid/i18n/grid.locale-it.js +1 -0
  36. data/public/javascripts/rails-jqgrid/i18n/grid.locale-ja.js +1 -0
  37. data/public/javascripts/rails-jqgrid/i18n/grid.locale-nl.js +1 -0
  38. data/public/javascripts/rails-jqgrid/i18n/grid.locale-no.js +1 -0
  39. data/public/javascripts/rails-jqgrid/i18n/grid.locale-pl.js +1 -0
  40. data/public/javascripts/rails-jqgrid/i18n/grid.locale-pt-br.js +1 -0
  41. data/public/javascripts/rails-jqgrid/i18n/grid.locale-pt.js +1 -0
  42. data/public/javascripts/rails-jqgrid/i18n/grid.locale-ro.js +1 -0
  43. data/public/javascripts/rails-jqgrid/i18n/grid.locale-ru.js +1 -0
  44. data/public/javascripts/rails-jqgrid/i18n/grid.locale-sk.js +1 -0
  45. data/public/javascripts/rails-jqgrid/i18n/grid.locale-sv.js +1 -0
  46. data/public/javascripts/rails-jqgrid/i18n/grid.locale-tr.js +1 -0
  47. data/public/javascripts/rails-jqgrid/i18n/grid.locale-ua.js +1 -0
  48. data/public/javascripts/rails-jqgrid/install.txt +43 -0
  49. data/public/javascripts/rails-jqgrid/jquery-1.4.2.min.js +154 -0
  50. data/public/javascripts/rails-jqgrid/jquery-ui-1.8.4.custom.min.js +763 -0
  51. data/public/javascripts/rails-jqgrid/jquery.jqGrid.min.js +445 -0
  52. data/public/javascripts/rails-jqgrid/src/JsonXml.js +330 -0
  53. data/public/javascripts/rails-jqgrid/src/css/ellipsis-xbl.xml +13 -0
  54. data/public/javascripts/rails-jqgrid/src/css/jquery.searchFilter.css +7 -0
  55. data/public/javascripts/rails-jqgrid/src/css/ui.jqgrid.css +129 -0
  56. data/public/javascripts/rails-jqgrid/src/css/ui.multiselect.css +30 -0
  57. data/public/javascripts/rails-jqgrid/src/grid.base.js +3003 -0
  58. data/public/javascripts/rails-jqgrid/src/grid.celledit.js +486 -0
  59. data/public/javascripts/rails-jqgrid/src/grid.common.js +636 -0
  60. data/public/javascripts/rails-jqgrid/src/grid.custom.js +818 -0
  61. data/public/javascripts/rails-jqgrid/src/grid.formedit.js +1872 -0
  62. data/public/javascripts/rails-jqgrid/src/grid.import.js +201 -0
  63. data/public/javascripts/rails-jqgrid/src/grid.inlinedit.js +250 -0
  64. data/public/javascripts/rails-jqgrid/src/grid.jqueryui.js +503 -0
  65. data/public/javascripts/rails-jqgrid/src/grid.loader.js +47 -0
  66. data/public/javascripts/rails-jqgrid/src/grid.postext.js +64 -0
  67. data/public/javascripts/rails-jqgrid/src/grid.setcolumns.js +126 -0
  68. data/public/javascripts/rails-jqgrid/src/grid.subgrid.js +260 -0
  69. data/public/javascripts/rails-jqgrid/src/grid.tbltogrid.js +106 -0
  70. data/public/javascripts/rails-jqgrid/src/grid.treegrid.js +483 -0
  71. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-bg.js +132 -0
  72. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-bg1251.js +132 -0
  73. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-cat.js +128 -0
  74. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-cn.js +132 -0
  75. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-cs.js +128 -0
  76. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-de.js +128 -0
  77. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-dk.js +128 -0
  78. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-el.js +126 -0
  79. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-en.js +128 -0
  80. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-es.js +128 -0
  81. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-fa.js +125 -0
  82. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-fi.js +130 -0
  83. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-fr.js +126 -0
  84. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-he.js +127 -0
  85. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-hu.js +129 -0
  86. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-is.js +126 -0
  87. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-it.js +1 -0
  88. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-ja.js +155 -0
  89. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-nl.js +149 -0
  90. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-no.js +1 -0
  91. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-pl.js +127 -0
  92. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-pt-br.js +127 -0
  93. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-pt.js +125 -0
  94. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-ro.js +139 -0
  95. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-ru.js +127 -0
  96. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-sk.js +127 -0
  97. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-sv.js +127 -0
  98. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-tr.js +126 -0
  99. data/public/javascripts/rails-jqgrid/src/i18n/grid.locale-ua.js +127 -0
  100. data/public/javascripts/rails-jqgrid/src/jqDnR.js +68 -0
  101. data/public/javascripts/rails-jqgrid/src/jqModal.js +69 -0
  102. data/public/javascripts/rails-jqgrid/src/jquery.fmatter.js +542 -0
  103. data/public/javascripts/rails-jqgrid/src/jquery.searchFilter.js +716 -0
  104. data/public/javascripts/rails-jqgrid/src/ui.multiselect.js +314 -0
  105. data/public/stylesheets/rails-jqgrid/ellipsis-xbl.xml +13 -0
  106. data/public/stylesheets/rails-jqgrid/themes/AUTHORS.txt +30 -0
  107. data/public/stylesheets/rails-jqgrid/themes/GPL-LICENSE.txt +278 -0
  108. data/public/stylesheets/rails-jqgrid/themes/MIT-LICENSE.txt +25 -0
  109. data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  110. data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  111. data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  112. data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  113. data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  114. data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  115. data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  116. data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  117. data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-icons_222222_256x240.png +0 -0
  118. data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  119. data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-icons_454545_256x240.png +0 -0
  120. data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-icons_888888_256x240.png +0 -0
  121. data/public/stylesheets/rails-jqgrid/themes/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  122. data/public/stylesheets/rails-jqgrid/themes/smoothness/jquery-ui-1.8.4.custom.css +572 -0
  123. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_flat_55_999999_40x100.png +0 -0
  124. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_flat_75_aaaaaa_40x100.png +0 -0
  125. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_glass_45_0078ae_1x400.png +0 -0
  126. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_glass_55_f8da4e_1x400.png +0 -0
  127. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_glass_75_79c9ec_1x400.png +0 -0
  128. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_gloss-wave_45_e14f1c_500x100.png +0 -0
  129. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_gloss-wave_50_6eac2c_500x100.png +0 -0
  130. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_gloss-wave_75_2191c0_500x100.png +0 -0
  131. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
  132. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-icons_0078ae_256x240.png +0 -0
  133. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-icons_056b93_256x240.png +0 -0
  134. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-icons_d8e7f3_256x240.png +0 -0
  135. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-icons_e0fdff_256x240.png +0 -0
  136. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-icons_f5e175_256x240.png +0 -0
  137. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-icons_f7a50d_256x240.png +0 -0
  138. data/public/stylesheets/rails-jqgrid/themes/start/images/ui-icons_fcd113_256x240.png +0 -0
  139. data/public/stylesheets/rails-jqgrid/themes/start/jquery-ui-1.8.4.custom.css +573 -0
  140. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_flat_30_cccccc_40x100.png +0 -0
  141. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_flat_50_5c5c5c_40x100.png +0 -0
  142. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_glass_20_555555_1x400.png +0 -0
  143. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_glass_40_0078a3_1x400.png +0 -0
  144. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_glass_40_ffc73d_1x400.png +0 -0
  145. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_gloss-wave_25_333333_500x100.png +0 -0
  146. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_highlight-soft_80_eeeeee_1x100.png +0 -0
  147. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_inset-soft_25_000000_1x100.png +0 -0
  148. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-bg_inset-soft_30_f58400_1x100.png +0 -0
  149. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-icons_222222_256x240.png +0 -0
  150. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-icons_4b8e0b_256x240.png +0 -0
  151. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-icons_a83300_256x240.png +0 -0
  152. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-icons_cccccc_256x240.png +0 -0
  153. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/images/ui-icons_ffffff_256x240.png +0 -0
  154. data/public/stylesheets/rails-jqgrid/themes/ui-darkness/jquery-ui-1.8.4.custom.css +572 -0
  155. data/public/stylesheets/rails-jqgrid/themes/version.txt +1 -0
  156. data/public/stylesheets/rails-jqgrid/ui.jqgrid.css +2 -0
  157. data/rails_jq_grid.gemspec +200 -0
  158. data/spec/spec.opts +1 -0
  159. data/spec/spec_helper.rb +8 -0
  160. 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'>&nbsp;</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>&nbsp;</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>&nbsp;</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'>&#160;</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>&#160;</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>&#160;</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 */