├── .gitignore
├── README.md
├── dist
├── jsonform.css
└── jsonform.js
├── examples
├── ajax.html
├── boolean.html
├── collectionobjects.html
├── index.html
├── javascripts
│ ├── chosen
│ │ ├── chosen-sprite.png
│ │ ├── chosen-sprite@2x.png
│ │ ├── chosen.css
│ │ ├── chosen.jquery.js
│ │ ├── chosen.jquery.min.js
│ │ ├── chosen.min.css
│ │ ├── chosen.proto.js
│ │ └── chosen.proto.min.js
│ ├── jquery.js
│ ├── jquery.sortable.js
│ └── underscore.js
├── select.html
├── selectajax.html
├── sortable.html
└── string.html
├── gulpfile.coffee
├── gulpfile.js
├── package.json
├── src
├── fields
│ ├── ajax.coffee
│ ├── ajax.jst
│ ├── ajax.scss
│ ├── boolean.coffee
│ ├── boolean.jst
│ ├── boolean.scss
│ ├── fieldcollection-del.jst
│ ├── fieldcollection-sort.jst
│ ├── fieldcollection.coffee
│ ├── fieldcollection.jst
│ ├── fieldcollection.scss
│ ├── fieldcollectionitem.coffee
│ ├── fieldcollectionitem.scss
│ ├── select.coffee
│ ├── select.jst
│ ├── selectajax.coffee
│ ├── selectajax.jst
│ ├── string.coffee
│ ├── string.jst
│ └── string.scss
├── jsonform.coffee
└── jsonform.scss
└── test
├── jsonform.css
└── jsonform.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | npm-debug.log
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JSON form
2 |
3 | 
4 |
5 | This is a javascript library that can auto-generate a form to help a user generate a JSON document.
6 |
7 | The library takes a textarea DOM element (empty or filled with existing JSON data), and a JSON object that describes the JSON you want to manipulate via the form.
8 |
9 | ```js
10 | var config = {
11 | ...
12 | }
13 | var jf = new jsonform.Form($("#myTextField")[0], config);
14 | ```
15 |
16 | ## The config object
17 |
18 | The config object defines the outline of the JSON object that the library should generate. You can use any type of object: The only requirement is that whereever you need dynamic data input, you create an object with the property `jsType` set to the type of field you want in the form.
19 |
20 | The following json config shows a single textfield to the user:
21 |
22 | ```js
23 | var config = {
24 | "name" : {
25 | "jfType" : "StringField"
26 | }
27 | }
28 | ```
29 |
30 | The user will then be presented with a single textfield, and the original textarea will automatically update with the latest JSON representation:
31 |
32 | ```html
33 |
38 | ```
39 |
40 | Although that's a very simple use-case, the library supports a number of advanced fields. Look in the field parameters guide below.
41 |
42 | But what if you want the user to add more than a single name? Easy. Wrap your `jfType` object in an array, and the UI will show buttons to add/remove multiple fields. For example, this is a more complex example where a user can add up to 7 names:
43 |
44 | ```js
45 | var config = {
46 | "names" : [
47 | {
48 | "jfType" : "StringField",
49 | "jfMax" : 7
50 | }
51 | ]
52 | }
53 | ```
54 |
55 | Corresponding output:
56 |
57 | ```html
58 |
69 | ```
70 |
71 | If the textarea has existing JSON data, and that data matches the schema of the JSON config, the existing JSON values will be pre-filled into the form.
72 |
73 | Look in `test/index.html` for a more complicated JSON config structure.
74 |
75 | ## Optional Configuration
76 |
77 | If you want the collection fields to be sortable, you just need to add `jquery.sortable` to the page. See `/examples/sortable.html` for an example.
78 |
79 | ## Field parameters
80 |
81 | There's a number of fields in this library, each of them with specific parameters. These params apply to all fields:
82 |
83 | ```js
84 | {
85 | "jfType" : "XXXXField", // name of field to use
86 | "jfTitle" : "My title", // label to show before the input field(s)
87 | "jfHelper" : "Do this, do that", // smaller help text to show before the input field(s)
88 | "jfValueType" : "int" // force the value to be integer over string. Helpful for text input, etc.
89 | }
90 | ```
91 |
92 | ### BooleanField
93 |
94 | No specific options. Will show a select box with `true` or `false`.
95 |
96 | ```js
97 | {
98 | "jfType" : "BooleanField"
99 | }
100 | ```
101 |
102 | ### StringField
103 |
104 | No specific options. Will show an input text field.
105 |
106 | ```js
107 | {
108 | "jfType" : "StringField"
109 | }
110 | ```
111 |
112 | ### SelectField
113 |
114 | Will show a select field with options set from `jfValues`.
115 |
116 | ```js
117 | {
118 | "jfType" : "SelectField",
119 | "jfValues" : [["first", "First Item"], ["second", "Second Item"]]
120 | }
121 | ```
122 |
123 | ### AjaxField
124 |
125 | Will show a search box that queries against an API endpoint, and populates the results in a dropdown box. It also supports parsing existing data into the dropdown, via the `jfReloadParam`.
126 |
127 | ```js
128 | {
129 | "jfType" : "AjaxField",
130 | "jfUrl" : "http://my.api", // URL for API endpoint
131 | "jfSearchParam" : "search", // query param to use for search query (http://my.api?search=QUERY)
132 | "jfParse" : function(data, vals) { }) // Parse function that receives the API response. Should return an array of [value, label] arrays for the select box. Takes an optional parameter with single values from existing JSON, to use for sorting. Look in test/index.html for an example.
133 | "jfReloadParam" : "uuid[]", // used to populate existing data. A single request will be made with all values set to this array param, and the parse function will be used to populate the fields from the response. Look in test/index.html for an example.
134 | }
135 | ```
136 |
137 | ### SelectAjaxField
138 |
139 | Will show a select dropdown box, and whenever a value is selected, an ajaxfield below that searches a specific endpoint. This makes it possible to make a fields where the user first selects the type of API endpoint, and then searches for a specific object in that endpoint. See examples for more info.
140 |
141 |
142 |
143 |
--------------------------------------------------------------------------------
/dist/jsonform.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: Helvetica, Arial, sans-serif; }
3 |
4 | .jfForm {
5 | margin: 20px 0px; }
6 |
7 | .jfTitle {
8 | font-size: 16px;
9 | display: block;
10 | margin-top: 10px;
11 | margin-bottom: 10px; }
12 |
13 | .jfHelper {
14 | display: block;
15 | margin-top: 10px;
16 | margin-bottom: 10px;
17 | font-size: 13px;
18 | color: #838383;
19 | letter-spacing: 0.5px;
20 | font-style: italic; }
21 |
22 | a.jfBtn, a.jfBtn:link {
23 | text-decoration: none;
24 | color: #282828;
25 | display: inline-block;
26 | background-color: #F7F7F7;
27 | text-align: center;
28 | border-radius: 50%;
29 | border: 1px solid #999;
30 | margin-bottom: 10px; }
31 |
32 | .chosen-container {
33 | margin-bottom: 10px; }
34 |
35 | .jfCollectionItem {
36 | background-color: #FAFAFA;
37 | padding: 10px;
38 | border: 1px solid #C7C7C7;
39 | border-radius: 5px;
40 | margin-bottom: 5px;
41 | max-width: 400px; }
42 |
43 | .jfAdd {
44 | width: 30px;
45 | height: 30px;
46 | line-height: 30px; }
47 |
48 | .jfAdd[disabled] {
49 | opacity: 0.4;
50 | pointer-events: none; }
51 |
52 | a.jfDel {
53 | font-size: 14px;
54 | text-decoration: none;
55 | padding: 3px 5px;
56 | margin-top: 10px;
57 | margin-left: 5px;
58 | color: #DA7D7D;
59 | display: inline-block;
60 | background-color: #ECC8C8; }
61 |
62 | .jfSort {
63 | font-size: 14px;
64 | margin-top: 10px;
65 | margin-right: 5px;
66 | color: #565555;
67 | display: inline-block;
68 | background-color: #DBDBDB;
69 | text-align: center;
70 | padding: 3px 5px;
71 | vertical-align: top;
72 | border-radius: 3px;
73 | cursor: pointer; }
74 |
75 | body.dragging, body.dragging * {
76 | cursor: move !important; }
77 |
78 | .dragged {
79 | position: absolute;
80 | opacity: 0.5;
81 | z-index: 2000; }
82 |
83 | div.jfCollection .placeholder {
84 | position: relative;
85 | margin: 0;
86 | padding: 0;
87 | border: none; }
88 | div.jfCollection .placeholder:before {
89 | position: absolute;
90 | content: "";
91 | width: 0;
92 | height: 0;
93 | margin-top: -5px;
94 | left: -5px;
95 | top: -4px;
96 | border: 5px solid transparent;
97 | border-left-color: red;
98 | border-right: none; }
99 |
100 | .jfField input[type="text"] {
101 | padding: 6px 10px;
102 | border: 1px solid #B0B0B0;
103 | border-radius: 5px;
104 | background-color: #F7F7F7;
105 | width: 300px;
106 | font-family: Helvetica, Arial, sans-serif;
107 | font-size: 13px;
108 | color: #444;
109 | outline: none;
110 | vertical-align: top; }
111 |
--------------------------------------------------------------------------------
/dist/jsonform.js:
--------------------------------------------------------------------------------
1 | window.jsonform = {};
2 |
3 | window.jsonform.helpers = {
4 | panic: function(msg) {
5 | console.error(msg);
6 | return alert(msg);
7 | },
8 | isJsonString: function(str) {
9 | var e;
10 | try {
11 | JSON.parse(str);
12 | } catch (_error) {
13 | e = _error;
14 | return false;
15 | }
16 | return true;
17 | },
18 | changed: function() {
19 | return jQuery.event.trigger('jf:change');
20 | },
21 | newField: function(jfObj) {
22 | var klass;
23 | klass = jsonform[jfObj.jfType];
24 | if (klass) {
25 | return new jsonform[jfObj.jfType](jfObj);
26 | } else {
27 | return console.error("jsonform field doesnt exist: " + jfObj.jfType);
28 | }
29 | }
30 | };
31 |
32 | jsonform.AjaxField = (function() {
33 | AjaxField.preloadValues = function(config, vals, success) {
34 | var query;
35 | vals = _.compact(vals);
36 | if (_.isEmpty(vals)) {
37 | return;
38 | }
39 | query = {};
40 | query[config.jfReloadParam] = vals;
41 | return $.ajax({
42 | url: config.jfUrl,
43 | data: query,
44 | type: 'GET',
45 | success: (function(_this) {
46 | return function(data) {
47 | return success(config.jfParse(data, vals));
48 | };
49 | })(this),
50 | error: function(data) {
51 | return console.log("error baby");
52 | }
53 | });
54 | };
55 |
56 | function AjaxField(config) {
57 | this.config = config;
58 | this.tmpl = JST["fields/ajax"];
59 | this.jel = $('
');
60 | this.el = this.jel[0];
61 | }
62 |
63 | AjaxField.prototype.render = function() {
64 | var timeout;
65 | timeout = void 0;
66 | this.jel.html(this.tmpl(this.config));
67 | this.chosen = this.jel.find(".chosen-select").chosen({
68 | width: "300px",
69 | allow_single_deselect: true,
70 | no_results_text: 'Searching for'
71 | });
72 | this.jel.find(".chosen-search input").on('input', (function(_this) {
73 | return function(e) {
74 | clearTimeout(timeout);
75 | return timeout = setTimeout(function() {
76 | return _this.loadAjax(e);
77 | }, 800);
78 | };
79 | })(this));
80 | return this.chosen.change(jsonform.helpers.changed);
81 | };
82 |
83 | AjaxField.prototype.getValue = function() {
84 | return this.jel.find(".chosen-select").val();
85 | };
86 |
87 | AjaxField.prototype.clearValues = function() {
88 | this.jel.find("select option").remove();
89 | this.jel.find("select").append("");
90 | return this.jel.find(".chosen-select").trigger("chosen:updated");
91 | };
92 |
93 | AjaxField.prototype.setValue = function(val) {
94 | if (!_.isObject(val)) {
95 | return this.constructor.preloadValues(this.config, [val], (function(_this) {
96 | return function(newVal) {
97 | return _this.setValue(newVal[0]);
98 | };
99 | })(this));
100 | } else {
101 | this.jel.find(".chosen-select").html('');
102 | this.jel.find(".chosen-select").val(val[0]);
103 | this.jel.find(".chosen-select").trigger("chosen:updated");
104 | return jsonform.helpers.changed();
105 | }
106 | };
107 |
108 | AjaxField.prototype.loadAjax = function(e) {
109 | var chosen, query, searchVal;
110 | chosen = this.jel.find(".chosen-container");
111 | query = {};
112 | searchVal = chosen.find(".chosen-search input").val();
113 | query[this.config.jfSearchParam] = searchVal;
114 | this.clearValues();
115 | return $.ajax({
116 | url: this.config.jfUrl,
117 | data: query,
118 | type: 'GET',
119 | success: (function(_this) {
120 | return function(data) {
121 | var results, select;
122 | results = _this.config.jfParse(data);
123 | if (results.length === 0) {
124 | return chosen.find(".chosen-results").html("No results matched \"" + searchVal + "\"");
125 | } else {
126 | select = _this.jel.find(".chosen-select");
127 | _.each(results, function(result) {
128 | return select.append('');
129 | });
130 | select.trigger("chosen:updated");
131 | return chosen.find(".chosen-search input").val(searchVal);
132 | }
133 | };
134 | })(this),
135 | error: function(data) {
136 | return console.log("error baby");
137 | }
138 | });
139 | };
140 |
141 | return AjaxField;
142 |
143 | })();
144 |
145 | jsonform.BooleanField = (function() {
146 | function BooleanField(config) {
147 | this.config = config;
148 | this.tmpl = JST["fields/boolean"];
149 | this.jel = $('');
150 | this.el = this.jel[0];
151 | }
152 |
153 | BooleanField.prototype.render = function() {
154 | this.jel.html(this.tmpl(this.config));
155 | return this.jel.find(".chosen-select").chosen({
156 | disable_search_threshold: 5,
157 | width: "300px"
158 | }).change(jsonform.helpers.changed);
159 | };
160 |
161 | BooleanField.prototype.getValue = function() {
162 | return this.jel.find(".chosen-select").val() === "true";
163 | };
164 |
165 | BooleanField.prototype.setValue = function(val) {
166 | this.jel.find(".chosen-select").val(val + "");
167 | return this.jel.find(".chosen-select").trigger("chosen:updated");
168 | };
169 |
170 | return BooleanField;
171 |
172 | })();
173 |
174 | jsonform.FieldCollection = (function() {
175 | function FieldCollection(config) {
176 | this.config = config;
177 | this.tmpl = JST["fields/fieldcollection"];
178 | this.jel = $("");
179 | this.el = this.jel[0];
180 | this.items = [];
181 | }
182 |
183 | FieldCollection.prototype.render = function() {
184 | this.jel.html(this.tmpl(this.config));
185 | this.jel.find(".jfAdd").click((function(_this) {
186 | return function(e) {
187 | if ($(_this).is("[disabled]")) {
188 | return;
189 | }
190 | e.preventDefault();
191 | return _this.addItem();
192 | };
193 | })(this));
194 | if ($().sortable) {
195 | return this.jel.find(".jfCollection").sortable({
196 | placeholder: ' ',
197 | itemSelector: '.jfCollectionItem',
198 | handle: 'i.jfSort',
199 | onDrop: (function(_this) {
200 | return function(item, container, _super) {
201 | _super(item, container);
202 | _this.items = _.sortBy(_this.items, function(item) {
203 | return item.jel.index();
204 | });
205 | return jsonform.helpers.changed();
206 | };
207 | })(this)
208 | });
209 | }
210 | };
211 |
212 | FieldCollection.prototype.getValues = function() {
213 | var results;
214 | results = _.map(this.items, function(item) {
215 | return item.getValue();
216 | });
217 | return _.without(results, "", void 0, null);
218 | };
219 |
220 | FieldCollection.prototype.addItem = function(jsonValue) {
221 | var item;
222 | item = new jsonform.FieldCollectionItem(this.config, jsonValue);
223 | this.jel.find(".jfCollection").append(item.el);
224 | item.render();
225 | this.items.push(item);
226 | item.jel.on("delete_clicked", (function(_this) {
227 | return function(e, item) {
228 | item.jel.remove();
229 | _this.items = _.without(_this.items, item);
230 | _this.checkAddState();
231 | return jsonform.helpers.changed();
232 | };
233 | })(this));
234 | this.checkAddState();
235 | if ($().sortable) {
236 | this.jel.find(".jfCollection").sortable("refresh");
237 | }
238 | return jsonform.helpers.changed();
239 | };
240 |
241 | FieldCollection.prototype.itemsFromValues = function(vals) {
242 | return _.each(vals, (function(_this) {
243 | return function(val) {
244 | return _this.addItem(val);
245 | };
246 | })(this));
247 | };
248 |
249 | FieldCollection.prototype.checkAddState = function() {
250 | if (this.config.jfMax) {
251 | if (this.items.length >= this.config.jfMax) {
252 | return this.jel.find(".jfAdd").attr("disabled", "disabled");
253 | } else {
254 | return this.jel.find(".jfAdd").removeAttr("disabled");
255 | }
256 | }
257 | };
258 |
259 | return FieldCollection;
260 |
261 | })();
262 |
263 | jsonform.FieldCollectionItem = (function() {
264 | function FieldCollectionItem(config, jsonValue) {
265 | this.jsonValue = jsonValue;
266 | this.deltmpl = JST["fields/fieldcollection-del"];
267 | this.sorttmpl = JST["fields/fieldcollection-sort"];
268 | this.jel = $('');
269 | this.el = this.jel[0];
270 | this.fields = [];
271 | this.config = {};
272 | jQuery.extend(true, this.config, config);
273 | delete this.config.jfTitle;
274 | delete this.config.jfHelper;
275 | delete this.config.jfCollection;
276 | delete this.config.jfMax;
277 | if (config.jfType) {
278 | this.fields.push(jsonform.helpers.newField(this.config));
279 | } else {
280 | _.each(this.config, (function(_this) {
281 | return function(v, k) {
282 | var field;
283 | if (v.jfType) {
284 | field = jsonform.helpers.newField(v);
285 | v.jfField = field;
286 | return _this.fields.push(field);
287 | }
288 | };
289 | })(this));
290 | }
291 | }
292 |
293 | FieldCollectionItem.prototype.render = function() {
294 | var del;
295 | this.jel.html("");
296 | _.each(this.fields, (function(_this) {
297 | return function(field) {
298 | _this.jel.append(field.el);
299 | return field.render();
300 | };
301 | })(this));
302 | if ($().sortable) {
303 | this.jel.append(this.sorttmpl());
304 | }
305 | del = $(this.deltmpl());
306 | this.jel.append(del);
307 | del.click((function(_this) {
308 | return function(e) {
309 | e.preventDefault();
310 | return _this.jel.trigger("delete_clicked", _this);
311 | };
312 | })(this));
313 | if (!_.isUndefined(this.jsonValue)) {
314 | if (this.config.jfType) {
315 | return this.fields[0].setValue(this.jsonValue);
316 | } else {
317 | return _.each(this.config, (function(_this) {
318 | return function(v, k) {
319 | if (v.jfField && _this.jsonValue[k]) {
320 | return v.jfField.setValue(_this.jsonValue[k]);
321 | }
322 | };
323 | })(this));
324 | }
325 | }
326 | };
327 |
328 | FieldCollectionItem.prototype.getValue = function() {
329 | var values;
330 | if (this.config.jfType) {
331 | return this.fields[0].getValue();
332 | } else {
333 | values = {};
334 | jQuery.extend(true, values, this.config);
335 | _.each(values, (function(_this) {
336 | return function(v, k) {
337 | if (v.jfField) {
338 | return values[k] = v.jfField.getValue();
339 | }
340 | };
341 | })(this));
342 | return values;
343 | }
344 | };
345 |
346 | return FieldCollectionItem;
347 |
348 | })();
349 |
350 | jsonform.SelectField = (function() {
351 | function SelectField(config) {
352 | this.config = config;
353 | this.tmpl = JST["fields/select"];
354 | this.jel = $('');
355 | this.el = this.jel[0];
356 | }
357 |
358 | SelectField.prototype.render = function() {
359 | this.jel.html(this.tmpl(this.config));
360 | return this.jel.find(".chosen-select").chosen({
361 | disable_search_threshold: 5,
362 | width: "300px"
363 | }).change((function(_this) {
364 | return function() {
365 | _this.jel.trigger("jf:changed");
366 | return jsonform.helpers.changed();
367 | };
368 | })(this));
369 | };
370 |
371 | SelectField.prototype.getValue = function() {
372 | return this.jel.find(".chosen-select").val();
373 | };
374 |
375 | SelectField.prototype.setValue = function(val) {
376 | this.jel.find(".chosen-select").val(val + "");
377 | return this.jel.find(".chosen-select").trigger("chosen:updated");
378 | };
379 |
380 | return SelectField;
381 |
382 | })();
383 |
384 | jsonform.SelectAjaxField = (function() {
385 | function SelectAjaxField(config) {
386 | this.config = config;
387 | this.jel = $('');
388 | this.el = this.jel[0];
389 | this.selectField = new jsonform.SelectField({
390 | jfValues: _.map(this.config.jfValues, function(val) {
391 | return val.jfValue;
392 | })
393 | });
394 | this.ajaxField = new jsonform.AjaxField(this.config.jfValues[0]);
395 | }
396 |
397 | SelectAjaxField.prototype.render = function() {
398 | this.jel.html("");
399 | this.jel.append(this.selectField.el);
400 | this.jel.append(this.ajaxField.el);
401 | this.selectField.render();
402 | this.ajaxField.render();
403 | return this.selectField.jel.on("jf:changed", (function(_this) {
404 | return function() {
405 | return _this.selectSwitched();
406 | };
407 | })(this));
408 | };
409 |
410 | SelectAjaxField.prototype.getValue = function() {
411 | var val;
412 | val = {};
413 | val[this.config.jfSelectKey] = this.selectField.getValue();
414 | val[this.config.jfAjaxKey] = this.ajaxField.getValue();
415 | return val;
416 | };
417 |
418 | SelectAjaxField.prototype.setValue = function(val) {
419 | var ajaxConfig;
420 | this.selectField.setValue(val[this.config.jfSelectKey]);
421 | ajaxConfig = this.getConfigBySelectKey(this.selectField.getValue());
422 | return jsonform.AjaxField.preloadValues(ajaxConfig, [val[this.config.jfAjaxKey]], (function(_this) {
423 | return function(data) {
424 | _this.ajaxField.config = ajaxConfig;
425 | return _this.ajaxField.setValue(data[0]);
426 | };
427 | })(this));
428 | };
429 |
430 | SelectAjaxField.prototype.selectSwitched = function() {
431 | var ajaxConfig;
432 | ajaxConfig = this.getConfigBySelectKey(this.selectField.getValue());
433 | this.ajaxField.config = ajaxConfig;
434 | return this.ajaxField.setValue(["", ""]);
435 | };
436 |
437 | SelectAjaxField.prototype.getConfigBySelectKey = function(key) {
438 | return _.find(this.config.jfValues, function(conf) {
439 | return conf.jfValue[0] === key;
440 | });
441 | };
442 |
443 | return SelectAjaxField;
444 |
445 | })();
446 |
447 | jsonform.StringField = (function() {
448 | function StringField(config) {
449 | this.config = config;
450 | this.tmpl = JST["fields/string"];
451 | this.jel = $('');
452 | this.el = this.jel[0];
453 | }
454 |
455 | StringField.prototype.render = function() {
456 | this.jel.html(this.tmpl(this.config));
457 | return this.jel.find("input").change(jsonform.helpers.changed);
458 | };
459 |
460 | StringField.prototype.getValue = function() {
461 | return this.jel.find("input").val();
462 | };
463 |
464 | StringField.prototype.setValue = function(val) {
465 | return this.jel.find("input").val(val);
466 | };
467 |
468 | return StringField;
469 |
470 | })();
471 |
472 | jsonform.Form = (function() {
473 | function Form(txtArea, jsonConfig) {
474 | var txtval;
475 | this.jel = $('');
476 | this.jtxt = $(txtArea);
477 | this.jtxt.hide();
478 | this.fields = [];
479 | this.jsonConfig = jsonConfig;
480 | this.parseJsonConfig(this.jsonConfig);
481 | _.each(this.fields, (function(_this) {
482 | return function(field) {
483 | _this.jel.append(field.el);
484 | return field.render();
485 | };
486 | })(this));
487 | $(document).bind('jf:change', (function(_this) {
488 | return function() {
489 | var json;
490 | json = _this.generateJson(_this.jsonConfig);
491 | return _this.jtxt.val(JSON.stringify(json, null, 2));
492 | };
493 | })(this));
494 | this.jtxt.after(this.jel);
495 | txtval = this.jtxt.val();
496 | if (!!txtval) {
497 | if (jsonform.helpers.isJsonString(txtval)) {
498 | this.fillFields(JSON.parse(txtval), this.jsonConfig);
499 | } else {
500 | jsonform.helpers.panic("Textarea has invalid JSON. jsonform will not work");
501 | }
502 | }
503 | }
504 |
505 | Form.prototype.generateJson = function(obj) {
506 | var newObj, val, vals;
507 | if (_.isArray(obj)) {
508 | if (obj.length === 1 && obj[0].jfCollection) {
509 | vals = obj[0].jfCollection.getValues();
510 | if (obj[0].jfCollection.config.jfValueType === "int") {
511 | vals = _.map(vals, function(val) {
512 | return parseInt(val);
513 | });
514 | }
515 | return vals;
516 | } else {
517 | return _.map(obj, (function(_this) {
518 | return function(v) {
519 | return _this.generateJson(v);
520 | };
521 | })(this));
522 | }
523 | } else {
524 | if (obj.jfField) {
525 | val = obj.jfField.getValue();
526 | if (obj.jfField.config.jfValueType === "int") {
527 | val = parseInt(val);
528 | }
529 | return val;
530 | } else {
531 | if (_.isObject(obj)) {
532 | newObj = {};
533 | _.each(obj, (function(_this) {
534 | return function(v, k) {
535 | return newObj[k] = _this.generateJson(v);
536 | };
537 | })(this));
538 | return newObj;
539 | } else {
540 | return obj;
541 | }
542 | }
543 | }
544 | };
545 |
546 | Form.prototype.parseJsonConfig = function(obj) {
547 | if (_.isArray(obj)) {
548 | if (obj.length === 1 && obj[0].jfCollection) {
549 | obj[0].jfCollection = new jsonform.FieldCollection(obj[0]);
550 | return this.fields.push(obj[0].jfCollection);
551 | } else {
552 | return _.each(obj, (function(_this) {
553 | return function(v) {
554 | return _this.parseJsonConfig(v);
555 | };
556 | })(this));
557 | }
558 | } else {
559 | if (obj.jfType) {
560 | obj.jfField = jsonform.helpers.newField(obj);
561 | return this.fields.push(obj.jfField);
562 | } else {
563 | return _.each(obj, (function(_this) {
564 | return function(v, k) {
565 | if (_.isObject(v)) {
566 | return _this.parseJsonConfig(v);
567 | }
568 | };
569 | })(this));
570 | }
571 | }
572 | };
573 |
574 | Form.prototype.fillFields = function(obj, jsonConfig) {
575 | if (obj === void 0 || jsonConfig === void 0) {
576 | jsonform.helpers.panic("Existing JSON doesnt match JSON config.");
577 | }
578 | if (_.isArray(obj)) {
579 | if (jsonConfig.length === 1 && jsonConfig[0].jfCollection) {
580 | return jsonConfig[0].jfCollection.itemsFromValues(obj);
581 | } else {
582 | return _.each(obj, (function(_this) {
583 | return function(v, i) {
584 | return _this.fillFields(obj[i], jsonConfig[i]);
585 | };
586 | })(this));
587 | }
588 | } else {
589 | if (jsonConfig.jfField) {
590 | return jsonConfig.jfField.setValue(obj);
591 | } else {
592 | if (_.isObject(obj)) {
593 | return _.each(obj, (function(_this) {
594 | return function(v, k) {
595 | if (jsonConfig[k]) {
596 | return _this.fillFields(v, jsonConfig[k]);
597 | } else {
598 | console.log("jsonConfig object not present:");
599 | console.log("key: ", k);
600 | return console.log("value: ", v);
601 | }
602 | };
603 | })(this));
604 | }
605 | }
606 | }
607 | };
608 |
609 | return Form;
610 |
611 | })();
612 |
613 | this.JST = {"fields/ajax": function(obj) {
614 | obj || (obj = {});
615 | var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
616 | function print() { __p += __j.call(arguments, '') }
617 | with (obj) {
618 |
619 | if(typeof(jfTitle)!== 'undefined') { ;
620 | __p += '' +
621 | ((__t = ( jfTitle )) == null ? '' : __t) +
622 | '';
623 | } ;
624 | __p += '\n';
625 | if(typeof(jfHelper)!== 'undefined') { ;
626 | __p += '' +
627 | ((__t = ( jfHelper )) == null ? '' : __t) +
628 | '';
629 | } ;
630 | __p += '\n\n';
631 |
632 | }
633 | return __p
634 | },
635 | "fields/boolean": function(obj) {
636 | obj || (obj = {});
637 | var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
638 | function print() { __p += __j.call(arguments, '') }
639 | with (obj) {
640 |
641 | if(typeof(jfTitle)!== 'undefined') { ;
642 | __p += '' +
643 | ((__t = ( jfTitle )) == null ? '' : __t) +
644 | '';
645 | } ;
646 | __p += '\n';
647 | if(typeof(jfHelper)!== 'undefined') { ;
648 | __p += '' +
649 | ((__t = ( jfHelper )) == null ? '' : __t) +
650 | '';
651 | } ;
652 | __p += '\n\n';
653 |
654 | }
655 | return __p
656 | },
657 | "fields/fieldcollection-del": function(obj) {
658 | obj || (obj = {});
659 | var __t, __p = '', __e = _.escape;
660 | with (obj) {
661 | __p += 'Delete';
662 |
663 | }
664 | return __p
665 | },
666 | "fields/fieldcollection-sort": function(obj) {
667 | obj || (obj = {});
668 | var __t, __p = '', __e = _.escape;
669 | with (obj) {
670 | __p += '↕';
671 |
672 | }
673 | return __p
674 | },
675 | "fields/fieldcollection": function(obj) {
676 | obj || (obj = {});
677 | var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
678 | function print() { __p += __j.call(arguments, '') }
679 | with (obj) {
680 |
681 | if(typeof(jfTitle)!== 'undefined') { ;
682 | __p += '' +
683 | ((__t = ( jfTitle )) == null ? '' : __t) +
684 | '';
685 | } ;
686 | __p += '\n';
687 | if(typeof(jfHelper)!== 'undefined') { ;
688 | __p += '' +
689 | ((__t = ( jfHelper )) == null ? '' : __t) +
690 | '';
691 | } ;
692 | __p += '\n\n+\n\n';
693 |
694 | }
695 | return __p
696 | },
697 | "fields/select": function(obj) {
698 | obj || (obj = {});
699 | var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
700 | function print() { __p += __j.call(arguments, '') }
701 | with (obj) {
702 |
703 | if(typeof(jfTitle)!== 'undefined') { ;
704 | __p += '' +
705 | ((__t = ( jfTitle )) == null ? '' : __t) +
706 | '';
707 | } ;
708 | __p += '\n';
709 | if(typeof(jfHelper)!== 'undefined') { ;
710 | __p += '' +
711 | ((__t = ( jfHelper )) == null ? '' : __t) +
712 | '';
713 | } ;
714 | __p += '\n\n';
723 |
724 | }
725 | return __p
726 | },
727 | "fields/selectajax": function(obj) {
728 | obj || (obj = {});
729 | var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
730 | function print() { __p += __j.call(arguments, '') }
731 | with (obj) {
732 |
733 | if(typeof(jfTitle)!== 'undefined') { ;
734 | __p += '' +
735 | ((__t = ( jfTitle )) == null ? '' : __t) +
736 | '';
737 | } ;
738 | __p += '\n';
739 | if(typeof(jfHelper)!== 'undefined') { ;
740 | __p += '' +
741 | ((__t = ( jfHelper )) == null ? '' : __t) +
742 | '';
743 | } ;
744 | __p += '\n\n';
753 |
754 | }
755 | return __p
756 | },
757 | "fields/string": function(obj) {
758 | obj || (obj = {});
759 | var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
760 | function print() { __p += __j.call(arguments, '') }
761 | with (obj) {
762 |
763 | if(typeof(jfTitle)!== 'undefined') { ;
764 | __p += '' +
765 | ((__t = ( jfTitle )) == null ? '' : __t) +
766 | '';
767 | } ;
768 | __p += '\n';
769 | if(typeof(jfHelper)!== 'undefined') { ;
770 | __p += '' +
771 | ((__t = ( jfHelper )) == null ? '' : __t) +
772 | '';
773 | } ;
774 | __p += '\n\n';
775 |
776 | }
777 | return __p
778 | }};
--------------------------------------------------------------------------------
/examples/ajax.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | JSON Form test
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
23 | JSON Form test
24 |
25 |
34 |
35 |
71 |
72 |
--------------------------------------------------------------------------------
/examples/boolean.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | JSON Form test
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
23 | JSON Form test
24 |
25 |
30 |
31 |
53 |
54 |
--------------------------------------------------------------------------------
/examples/collectionobjects.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | JSON Form test
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
21 |
22 |
23 |
24 | JSON Form test
25 |
26 |
51 |
52 |
88 |
89 |
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | JSON Form test
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
23 | JSON Form Examples
24 |
25 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/examples/javascripts/chosen/chosen-sprite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oreillymedia/jsonform/7d38b902dd458587c7d149ee2dde5e28e899160a/examples/javascripts/chosen/chosen-sprite.png
--------------------------------------------------------------------------------
/examples/javascripts/chosen/chosen-sprite@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oreillymedia/jsonform/7d38b902dd458587c7d149ee2dde5e28e899160a/examples/javascripts/chosen/chosen-sprite@2x.png
--------------------------------------------------------------------------------
/examples/javascripts/chosen/chosen.css:
--------------------------------------------------------------------------------
1 | /*!
2 | Chosen, a Select Box Enhancer for jQuery and Prototype
3 | by Patrick Filler for Harvest, http://getharvest.com
4 |
5 | Version 1.4.1
6 | Full source at https://github.com/harvesthq/chosen
7 | Copyright (c) 2011-2015 Harvest http://getharvest.com
8 |
9 | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10 | This file is generated by `grunt build`, do not edit it by hand.
11 | */
12 |
13 | /* @group Base */
14 | .chosen-container {
15 | position: relative;
16 | display: inline-block;
17 | vertical-align: middle;
18 | font-size: 13px;
19 | zoom: 1;
20 | *display: inline;
21 | -webkit-user-select: none;
22 | -moz-user-select: none;
23 | user-select: none;
24 | }
25 | .chosen-container * {
26 | -webkit-box-sizing: border-box;
27 | -moz-box-sizing: border-box;
28 | box-sizing: border-box;
29 | }
30 | .chosen-container .chosen-drop {
31 | position: absolute;
32 | top: 100%;
33 | left: -9999px;
34 | z-index: 1010;
35 | width: 100%;
36 | border: 1px solid #aaa;
37 | border-top: 0;
38 | background: #fff;
39 | box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
40 | }
41 | .chosen-container.chosen-with-drop .chosen-drop {
42 | left: 0;
43 | }
44 | .chosen-container a {
45 | cursor: pointer;
46 | }
47 | .chosen-container .search-choice .group-name, .chosen-container .chosen-single .group-name {
48 | margin-right: 4px;
49 | overflow: hidden;
50 | white-space: nowrap;
51 | text-overflow: ellipsis;
52 | font-weight: normal;
53 | color: #999999;
54 | }
55 | .chosen-container .search-choice .group-name:after, .chosen-container .chosen-single .group-name:after {
56 | content: ":";
57 | padding-left: 2px;
58 | vertical-align: top;
59 | }
60 |
61 | /* @end */
62 | /* @group Single Chosen */
63 | .chosen-container-single .chosen-single {
64 | position: relative;
65 | display: block;
66 | overflow: hidden;
67 | padding: 0 0 0 8px;
68 | height: 25px;
69 | border: 1px solid #aaa;
70 | border-radius: 5px;
71 | background-color: #fff;
72 | background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
73 | background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
74 | background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
75 | background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
76 | background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
77 | background-clip: padding-box;
78 | box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
79 | color: #444;
80 | text-decoration: none;
81 | white-space: nowrap;
82 | line-height: 24px;
83 | }
84 | .chosen-container-single .chosen-default {
85 | color: #999;
86 | }
87 | .chosen-container-single .chosen-single span {
88 | display: block;
89 | overflow: hidden;
90 | margin-right: 26px;
91 | text-overflow: ellipsis;
92 | white-space: nowrap;
93 | }
94 | .chosen-container-single .chosen-single-with-deselect span {
95 | margin-right: 38px;
96 | }
97 | .chosen-container-single .chosen-single abbr {
98 | position: absolute;
99 | top: 6px;
100 | right: 26px;
101 | display: block;
102 | width: 12px;
103 | height: 12px;
104 | background: url('chosen-sprite.png') -42px 1px no-repeat;
105 | font-size: 1px;
106 | }
107 | .chosen-container-single .chosen-single abbr:hover {
108 | background-position: -42px -10px;
109 | }
110 | .chosen-container-single.chosen-disabled .chosen-single abbr:hover {
111 | background-position: -42px -10px;
112 | }
113 | .chosen-container-single .chosen-single div {
114 | position: absolute;
115 | top: 0;
116 | right: 0;
117 | display: block;
118 | width: 18px;
119 | height: 100%;
120 | }
121 | .chosen-container-single .chosen-single div b {
122 | display: block;
123 | width: 100%;
124 | height: 100%;
125 | background: url('chosen-sprite.png') no-repeat 0px 2px;
126 | }
127 | .chosen-container-single .chosen-search {
128 | position: relative;
129 | z-index: 1010;
130 | margin: 0;
131 | padding: 3px 4px;
132 | white-space: nowrap;
133 | }
134 | .chosen-container-single .chosen-search input[type="text"] {
135 | margin: 1px 0;
136 | padding: 4px 20px 4px 5px;
137 | width: 100%;
138 | height: auto;
139 | outline: 0;
140 | border: 1px solid #aaa;
141 | background: white url('chosen-sprite.png') no-repeat 100% -20px;
142 | background: url('chosen-sprite.png') no-repeat 100% -20px;
143 | font-size: 1em;
144 | font-family: sans-serif;
145 | line-height: normal;
146 | border-radius: 0;
147 | }
148 | .chosen-container-single .chosen-drop {
149 | margin-top: -1px;
150 | border-radius: 0 0 4px 4px;
151 | background-clip: padding-box;
152 | }
153 | .chosen-container-single.chosen-container-single-nosearch .chosen-search {
154 | position: absolute;
155 | left: -9999px;
156 | }
157 |
158 | /* @end */
159 | /* @group Results */
160 | .chosen-container .chosen-results {
161 | color: #444;
162 | position: relative;
163 | overflow-x: hidden;
164 | overflow-y: auto;
165 | margin: 0 4px 4px 0;
166 | padding: 0 0 0 4px;
167 | max-height: 240px;
168 | -webkit-overflow-scrolling: touch;
169 | }
170 | .chosen-container .chosen-results li {
171 | display: none;
172 | margin: 0;
173 | padding: 5px 6px;
174 | list-style: none;
175 | line-height: 15px;
176 | word-wrap: break-word;
177 | -webkit-touch-callout: none;
178 | }
179 | .chosen-container .chosen-results li.active-result {
180 | display: list-item;
181 | cursor: pointer;
182 | }
183 | .chosen-container .chosen-results li.disabled-result {
184 | display: list-item;
185 | color: #ccc;
186 | cursor: default;
187 | }
188 | .chosen-container .chosen-results li.highlighted {
189 | background-color: #3875d7;
190 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
191 | background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
192 | background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
193 | background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
194 | background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
195 | color: #fff;
196 | }
197 | .chosen-container .chosen-results li.no-results {
198 | color: #777;
199 | display: list-item;
200 | background: #f4f4f4;
201 | }
202 | .chosen-container .chosen-results li.group-result {
203 | display: list-item;
204 | font-weight: bold;
205 | cursor: default;
206 | }
207 | .chosen-container .chosen-results li.group-option {
208 | padding-left: 15px;
209 | }
210 | .chosen-container .chosen-results li em {
211 | font-style: normal;
212 | text-decoration: underline;
213 | }
214 |
215 | /* @end */
216 | /* @group Multi Chosen */
217 | .chosen-container-multi .chosen-choices {
218 | position: relative;
219 | overflow: hidden;
220 | margin: 0;
221 | padding: 0 5px;
222 | width: 100%;
223 | height: auto !important;
224 | height: 1%;
225 | border: 1px solid #aaa;
226 | background-color: #fff;
227 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
228 | background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
229 | background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
230 | background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
231 | background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
232 | cursor: text;
233 | }
234 | .chosen-container-multi .chosen-choices li {
235 | float: left;
236 | list-style: none;
237 | }
238 | .chosen-container-multi .chosen-choices li.search-field {
239 | margin: 0;
240 | padding: 0;
241 | white-space: nowrap;
242 | }
243 | .chosen-container-multi .chosen-choices li.search-field input[type="text"] {
244 | margin: 1px 0;
245 | padding: 0;
246 | height: 25px;
247 | outline: 0;
248 | border: 0 !important;
249 | background: transparent !important;
250 | box-shadow: none;
251 | color: #999;
252 | font-size: 100%;
253 | font-family: sans-serif;
254 | line-height: normal;
255 | border-radius: 0;
256 | }
257 | .chosen-container-multi .chosen-choices li.search-choice {
258 | position: relative;
259 | margin: 3px 5px 3px 0;
260 | padding: 3px 20px 3px 5px;
261 | border: 1px solid #aaa;
262 | max-width: 100%;
263 | border-radius: 3px;
264 | background-color: #eeeeee;
265 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
266 | background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
267 | background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
268 | background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
269 | background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
270 | background-size: 100% 19px;
271 | background-repeat: repeat-x;
272 | background-clip: padding-box;
273 | box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
274 | color: #333;
275 | line-height: 13px;
276 | cursor: default;
277 | }
278 | .chosen-container-multi .chosen-choices li.search-choice span {
279 | word-wrap: break-word;
280 | }
281 | .chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
282 | position: absolute;
283 | top: 4px;
284 | right: 3px;
285 | display: block;
286 | width: 12px;
287 | height: 12px;
288 | background: url('chosen-sprite.png') -42px 1px no-repeat;
289 | font-size: 1px;
290 | }
291 | .chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
292 | background-position: -42px -10px;
293 | }
294 | .chosen-container-multi .chosen-choices li.search-choice-disabled {
295 | padding-right: 5px;
296 | border: 1px solid #ccc;
297 | background-color: #e4e4e4;
298 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
299 | background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
300 | background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
301 | background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
302 | background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
303 | color: #666;
304 | }
305 | .chosen-container-multi .chosen-choices li.search-choice-focus {
306 | background: #d4d4d4;
307 | }
308 | .chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
309 | background-position: -42px -10px;
310 | }
311 | .chosen-container-multi .chosen-results {
312 | margin: 0;
313 | padding: 0;
314 | }
315 | .chosen-container-multi .chosen-drop .result-selected {
316 | display: list-item;
317 | color: #ccc;
318 | cursor: default;
319 | }
320 |
321 | /* @end */
322 | /* @group Active */
323 | .chosen-container-active .chosen-single {
324 | border: 1px solid #5897fb;
325 | box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
326 | }
327 | .chosen-container-active.chosen-with-drop .chosen-single {
328 | border: 1px solid #aaa;
329 | -moz-border-radius-bottomright: 0;
330 | border-bottom-right-radius: 0;
331 | -moz-border-radius-bottomleft: 0;
332 | border-bottom-left-radius: 0;
333 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
334 | background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
335 | background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
336 | background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
337 | background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
338 | box-shadow: 0 1px 0 #fff inset;
339 | }
340 | .chosen-container-active.chosen-with-drop .chosen-single div {
341 | border-left: none;
342 | background: transparent;
343 | }
344 | .chosen-container-active.chosen-with-drop .chosen-single div b {
345 | background-position: -18px 2px;
346 | }
347 | .chosen-container-active .chosen-choices {
348 | border: 1px solid #5897fb;
349 | box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
350 | }
351 | .chosen-container-active .chosen-choices li.search-field input[type="text"] {
352 | color: #222 !important;
353 | }
354 |
355 | /* @end */
356 | /* @group Disabled Support */
357 | .chosen-disabled {
358 | opacity: 0.5 !important;
359 | cursor: default;
360 | }
361 | .chosen-disabled .chosen-single {
362 | cursor: default;
363 | }
364 | .chosen-disabled .chosen-choices .search-choice .search-choice-close {
365 | cursor: default;
366 | }
367 |
368 | /* @end */
369 | /* @group Right to Left */
370 | .chosen-rtl {
371 | text-align: right;
372 | }
373 | .chosen-rtl .chosen-single {
374 | overflow: visible;
375 | padding: 0 8px 0 0;
376 | }
377 | .chosen-rtl .chosen-single span {
378 | margin-right: 0;
379 | margin-left: 26px;
380 | direction: rtl;
381 | }
382 | .chosen-rtl .chosen-single-with-deselect span {
383 | margin-left: 38px;
384 | }
385 | .chosen-rtl .chosen-single div {
386 | right: auto;
387 | left: 3px;
388 | }
389 | .chosen-rtl .chosen-single abbr {
390 | right: auto;
391 | left: 26px;
392 | }
393 | .chosen-rtl .chosen-choices li {
394 | float: right;
395 | }
396 | .chosen-rtl .chosen-choices li.search-field input[type="text"] {
397 | direction: rtl;
398 | }
399 | .chosen-rtl .chosen-choices li.search-choice {
400 | margin: 3px 5px 3px 0;
401 | padding: 3px 5px 3px 19px;
402 | }
403 | .chosen-rtl .chosen-choices li.search-choice .search-choice-close {
404 | right: auto;
405 | left: 4px;
406 | }
407 | .chosen-rtl.chosen-container-single-nosearch .chosen-search,
408 | .chosen-rtl .chosen-drop {
409 | left: 9999px;
410 | }
411 | .chosen-rtl.chosen-container-single .chosen-results {
412 | margin: 0 0 4px 4px;
413 | padding: 0 4px 0 0;
414 | }
415 | .chosen-rtl .chosen-results li.group-option {
416 | padding-right: 15px;
417 | padding-left: 0;
418 | }
419 | .chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
420 | border-right: none;
421 | }
422 | .chosen-rtl .chosen-search input[type="text"] {
423 | padding: 4px 5px 4px 20px;
424 | background: white url('chosen-sprite.png') no-repeat -30px -20px;
425 | background: url('chosen-sprite.png') no-repeat -30px -20px;
426 | direction: rtl;
427 | }
428 | .chosen-rtl.chosen-container-single .chosen-single div b {
429 | background-position: 6px 2px;
430 | }
431 | .chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
432 | background-position: -12px 2px;
433 | }
434 |
435 | /* @end */
436 | /* @group Retina compatibility */
437 | @media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi), only screen and (min-resolution: 1.5dppx) {
438 | .chosen-rtl .chosen-search input[type="text"],
439 | .chosen-container-single .chosen-single abbr,
440 | .chosen-container-single .chosen-single div b,
441 | .chosen-container-single .chosen-search input[type="text"],
442 | .chosen-container-multi .chosen-choices .search-choice .search-choice-close,
443 | .chosen-container .chosen-results-scroll-down span,
444 | .chosen-container .chosen-results-scroll-up span {
445 | background-image: url('chosen-sprite@2x.png') !important;
446 | background-size: 52px 37px !important;
447 | background-repeat: no-repeat !important;
448 | }
449 | }
450 | /* @end */
451 |
--------------------------------------------------------------------------------
/examples/javascripts/chosen/chosen.jquery.min.js:
--------------------------------------------------------------------------------
1 | /* Chosen v1.4.1 | (c) 2011-2015 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
2 | (function(){var a,AbstractChosen,Chosen,SelectParser,b,c={}.hasOwnProperty,d=function(a,b){function d(){this.constructor=a}for(var e in b)c.call(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a};SelectParser=function(){function SelectParser(){this.options_index=0,this.parsed=[]}return SelectParser.prototype.add_node=function(a){return"OPTGROUP"===a.nodeName.toUpperCase()?this.add_group(a):this.add_option(a)},SelectParser.prototype.add_group=function(a){var b,c,d,e,f,g;for(b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:this.escapeExpression(a.label),title:a.title?a.title:void 0,children:0,disabled:a.disabled,classes:a.className}),f=a.childNodes,g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},SelectParser.prototype.add_option=function(a,b,c){return"OPTION"===a.nodeName.toUpperCase()?(""!==a.text?(null!=b&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,title:a.title?a.title:void 0,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,group_label:null!=b?this.parsed[b].label:null,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1):void 0},SelectParser.prototype.escapeExpression=function(a){var b,c;return null==a||a===!1?"":/[\&\<\>\"\'\`]/.test(a)?(b={"<":"<",">":">",'"':""","'":"'","`":"`"},c=/&(?!\w+;)|[\<\>\"\'\`]/g,a.replace(c,function(a){return b[a]||"&"})):a},SelectParser}(),SelectParser.select_to_array=function(a){var b,c,d,e,f;for(c=new SelectParser,f=a.childNodes,d=0,e=f.length;e>d;d++)b=f[d],c.add_node(b);return c.parsed},AbstractChosen=function(){function AbstractChosen(a,b){this.form_field=a,this.options=null!=b?b:{},AbstractChosen.browser_is_supported()&&(this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers(),this.on_ready())}return AbstractChosen.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.allow_single_deselect=null!=this.options.allow_single_deselect&&null!=this.form_field.options[0]&&""===this.form_field.options[0].text?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.enable_split_word_search=null!=this.options.enable_split_word_search?this.options.enable_split_word_search:!0,this.group_search=null!=this.options.group_search?this.options.group_search:!0,this.search_contains=this.options.search_contains||!1,this.single_backstroke_delete=null!=this.options.single_backstroke_delete?this.options.single_backstroke_delete:!0,this.max_selected_options=this.options.max_selected_options||1/0,this.inherit_select_classes=this.options.inherit_select_classes||!1,this.display_selected_options=null!=this.options.display_selected_options?this.options.display_selected_options:!0,this.display_disabled_options=null!=this.options.display_disabled_options?this.options.display_disabled_options:!0,this.include_group_label_in_selected=this.options.include_group_label_in_selected||!1},AbstractChosen.prototype.set_default_text=function(){return this.default_text=this.form_field.getAttribute("data-placeholder")?this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.options.placeholder_text_multiple||this.options.placeholder_text||AbstractChosen.default_multiple_text:this.options.placeholder_text_single||this.options.placeholder_text||AbstractChosen.default_single_text,this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||AbstractChosen.default_no_result_text},AbstractChosen.prototype.choice_label=function(a){return this.include_group_label_in_selected&&null!=a.group_label?""+a.group_label+""+a.html:a.html},AbstractChosen.prototype.mouse_enter=function(){return this.mouse_on_container=!0},AbstractChosen.prototype.mouse_leave=function(){return this.mouse_on_container=!1},AbstractChosen.prototype.input_focus=function(){var a=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return a.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},AbstractChosen.prototype.input_blur=function(){var a=this;return this.mouse_on_container?void 0:(this.active_field=!1,setTimeout(function(){return a.blur_test()},100))},AbstractChosen.prototype.results_option_build=function(a){var b,c,d,e,f;for(b="",f=this.results_data,d=0,e=f.length;e>d;d++)c=f[d],b+=c.group?this.result_add_group(c):this.result_add_option(c),(null!=a?a.first:void 0)&&(c.selected&&this.is_multiple?this.choice_build(c):c.selected&&!this.is_multiple&&this.single_set_selected_text(this.choice_label(c)));return b},AbstractChosen.prototype.result_add_option=function(a){var b,c;return a.search_match?this.include_option_in_results(a)?(b=[],a.disabled||a.selected&&this.is_multiple||b.push("active-result"),!a.disabled||a.selected&&this.is_multiple||b.push("disabled-result"),a.selected&&b.push("result-selected"),null!=a.group_array_index&&b.push("group-option"),""!==a.classes&&b.push(a.classes),c=document.createElement("li"),c.className=b.join(" "),c.style.cssText=a.style,c.setAttribute("data-option-array-index",a.array_index),c.innerHTML=a.search_text,a.title&&(c.title=a.title),this.outerHTML(c)):"":""},AbstractChosen.prototype.result_add_group=function(a){var b,c;return a.search_match||a.group_match?a.active_options>0?(b=[],b.push("group-result"),a.classes&&b.push(a.classes),c=document.createElement("li"),c.className=b.join(" "),c.innerHTML=a.search_text,a.title&&(c.title=a.title),this.outerHTML(c)):"":""},AbstractChosen.prototype.results_update_field=function(){return this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.results_build(),this.results_showing?this.winnow_results():void 0},AbstractChosen.prototype.reset_single_select_options=function(){var a,b,c,d,e;for(d=this.results_data,e=[],b=0,c=d.length;c>b;b++)a=d[b],a.selected?e.push(a.selected=!1):e.push(void 0);return e},AbstractChosen.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},AbstractChosen.prototype.results_search=function(){return this.results_showing?this.winnow_results():this.results_show()},AbstractChosen.prototype.winnow_results=function(){var a,b,c,d,e,f,g,h,i,j,k,l;for(this.no_results_clear(),d=0,f=this.get_search_text(),a=f.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),i=new RegExp(a,"i"),c=this.get_search_regex(a),l=this.results_data,j=0,k=l.length;k>j;j++)b=l[j],b.search_match=!1,e=null,this.include_option_in_results(b)&&(b.group&&(b.group_match=!1,b.active_options=0),null!=b.group_array_index&&this.results_data[b.group_array_index]&&(e=this.results_data[b.group_array_index],0===e.active_options&&e.search_match&&(d+=1),e.active_options+=1),b.search_text=b.group?b.label:b.html,(!b.group||this.group_search)&&(b.search_match=this.search_string_match(b.search_text,c),b.search_match&&!b.group&&(d+=1),b.search_match?(f.length&&(g=b.search_text.search(i),h=b.search_text.substr(0,g+f.length)+""+b.search_text.substr(g+f.length),b.search_text=h.substr(0,g)+""+h.substr(g)),null!=e&&(e.group_match=!0)):null!=b.group_array_index&&this.results_data[b.group_array_index].search_match&&(b.search_match=!0)));return this.result_clear_highlight(),1>d&&f.length?(this.update_results_content(""),this.no_results(f)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight())},AbstractChosen.prototype.get_search_regex=function(a){var b;return b=this.search_contains?"":"^",new RegExp(b+a,"i")},AbstractChosen.prototype.search_string_match=function(a,b){var c,d,e,f;if(b.test(a))return!0;if(this.enable_split_word_search&&(a.indexOf(" ")>=0||0===a.indexOf("["))&&(d=a.replace(/\[|\]/g,"").split(" "),d.length))for(e=0,f=d.length;f>e;e++)if(c=d[e],b.test(c))return!0},AbstractChosen.prototype.choices_count=function(){var a,b,c,d;if(null!=this.selected_option_count)return this.selected_option_count;for(this.selected_option_count=0,d=this.form_field.options,b=0,c=d.length;c>b;b++)a=d[b],a.selected&&(this.selected_option_count+=1);return this.selected_option_count},AbstractChosen.prototype.choices_click=function(a){return a.preventDefault(),this.results_showing||this.is_disabled?void 0:this.results_show()},AbstractChosen.prototype.keyup_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices_count()>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(a.preventDefault(),this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},AbstractChosen.prototype.clipboard_event_checker=function(){var a=this;return setTimeout(function(){return a.results_search()},50)},AbstractChosen.prototype.container_width=function(){return null!=this.options.width?this.options.width:""+this.form_field.offsetWidth+"px"},AbstractChosen.prototype.include_option_in_results=function(a){return this.is_multiple&&!this.display_selected_options&&a.selected?!1:!this.display_disabled_options&&a.disabled?!1:a.empty?!1:!0},AbstractChosen.prototype.search_results_touchstart=function(a){return this.touch_started=!0,this.search_results_mouseover(a)},AbstractChosen.prototype.search_results_touchmove=function(a){return this.touch_started=!1,this.search_results_mouseout(a)},AbstractChosen.prototype.search_results_touchend=function(a){return this.touch_started?this.search_results_mouseup(a):void 0},AbstractChosen.prototype.outerHTML=function(a){var b;return a.outerHTML?a.outerHTML:(b=document.createElement("div"),b.appendChild(a),b.innerHTML)},AbstractChosen.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:/iP(od|hone)/i.test(window.navigator.userAgent)?!1:/Android/i.test(window.navigator.userAgent)&&/Mobile/i.test(window.navigator.userAgent)?!1:!0},AbstractChosen.default_multiple_text="Select Some Options",AbstractChosen.default_single_text="Select an Option",AbstractChosen.default_no_result_text="No results match",AbstractChosen}(),a=jQuery,a.fn.extend({chosen:function(b){return AbstractChosen.browser_is_supported()?this.each(function(){var c,d;c=a(this),d=c.data("chosen"),"destroy"===b&&d instanceof Chosen?d.destroy():d instanceof Chosen||c.data("chosen",new Chosen(this,b))}):this}}),Chosen=function(c){function Chosen(){return b=Chosen.__super__.constructor.apply(this,arguments)}return d(Chosen,c),Chosen.prototype.setup=function(){return this.form_field_jq=a(this.form_field),this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field_jq.hasClass("chosen-rtl")},Chosen.prototype.set_up_html=function(){var b,c;return b=["chosen-container"],b.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&b.push(this.form_field.className),this.is_rtl&&b.push("chosen-rtl"),c={"class":b.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(c.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=a("",c),this.is_multiple?this.container.html(''):this.container.html(''+this.default_text+'
'),this.form_field_jq.hide().after(this.container),this.dropdown=this.container.find("div.chosen-drop").first(),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chosen-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chosen-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chosen-search").first(),this.selected_item=this.container.find(".chosen-single").first()),this.results_build(),this.set_tab_index(),this.set_label_behavior()},Chosen.prototype.on_ready=function(){return this.form_field_jq.trigger("chosen:ready",{chosen:this})},Chosen.prototype.register_observers=function(){var a=this;return this.container.bind("touchstart.chosen",function(b){return a.container_mousedown(b),b.preventDefault()}),this.container.bind("touchend.chosen",function(b){return a.container_mouseup(b),b.preventDefault()}),this.container.bind("mousedown.chosen",function(b){a.container_mousedown(b)}),this.container.bind("mouseup.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mouseenter.chosen",function(b){a.mouse_enter(b)}),this.container.bind("mouseleave.chosen",function(b){a.mouse_leave(b)}),this.search_results.bind("mouseup.chosen",function(b){a.search_results_mouseup(b)}),this.search_results.bind("mouseover.chosen",function(b){a.search_results_mouseover(b)}),this.search_results.bind("mouseout.chosen",function(b){a.search_results_mouseout(b)}),this.search_results.bind("mousewheel.chosen DOMMouseScroll.chosen",function(b){a.search_results_mousewheel(b)}),this.search_results.bind("touchstart.chosen",function(b){a.search_results_touchstart(b)}),this.search_results.bind("touchmove.chosen",function(b){a.search_results_touchmove(b)}),this.search_results.bind("touchend.chosen",function(b){a.search_results_touchend(b)}),this.form_field_jq.bind("chosen:updated.chosen",function(b){a.results_update_field(b)}),this.form_field_jq.bind("chosen:activate.chosen",function(b){a.activate_field(b)}),this.form_field_jq.bind("chosen:open.chosen",function(b){a.container_mousedown(b)}),this.form_field_jq.bind("chosen:close.chosen",function(b){a.input_blur(b)}),this.search_field.bind("blur.chosen",function(b){a.input_blur(b)}),this.search_field.bind("keyup.chosen",function(b){a.keyup_checker(b)}),this.search_field.bind("keydown.chosen",function(b){a.keydown_checker(b)}),this.search_field.bind("focus.chosen",function(b){a.input_focus(b)}),this.search_field.bind("cut.chosen",function(b){a.clipboard_event_checker(b)}),this.search_field.bind("paste.chosen",function(b){a.clipboard_event_checker(b)}),this.is_multiple?this.search_choices.bind("click.chosen",function(b){a.choices_click(b)}):this.container.bind("click.chosen",function(a){a.preventDefault()})},Chosen.prototype.destroy=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.search_field[0].tabIndex&&(this.form_field_jq[0].tabIndex=this.search_field[0].tabIndex),this.container.remove(),this.form_field_jq.removeData("chosen"),this.form_field_jq.show()},Chosen.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field_jq[0].disabled,this.is_disabled?(this.container.addClass("chosen-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus.chosen",this.activate_action),this.close_field()):(this.container.removeClass("chosen-disabled"),this.search_field[0].disabled=!1,this.is_multiple?void 0:this.selected_item.bind("focus.chosen",this.activate_action))},Chosen.prototype.container_mousedown=function(b){return this.is_disabled||(b&&"mousedown"===b.type&&!this.results_showing&&b.preventDefault(),null!=b&&a(b.target).hasClass("search-choice-close"))?void 0:(this.active_field?this.is_multiple||!b||a(b.target)[0]!==this.selected_item[0]&&!a(b.target).parents("a.chosen-single").length||(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(this.container[0].ownerDocument).bind("click.chosen",this.click_test_action),this.results_show()),this.activate_field())},Chosen.prototype.container_mouseup=function(a){return"ABBR"!==a.target.nodeName||this.is_disabled?void 0:this.results_reset(a)},Chosen.prototype.search_results_mousewheel=function(a){var b;return a.originalEvent&&(b=a.originalEvent.deltaY||-a.originalEvent.wheelDelta||a.originalEvent.detail),null!=b?(a.preventDefault(),"DOMMouseScroll"===a.type&&(b=40*b),this.search_results.scrollTop(b+this.search_results.scrollTop())):void 0},Chosen.prototype.blur_test=function(){return!this.active_field&&this.container.hasClass("chosen-container-active")?this.close_field():void 0},Chosen.prototype.close_field=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},Chosen.prototype.activate_field=function(){return this.container.addClass("chosen-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},Chosen.prototype.test_active_click=function(b){var c;return c=a(b.target).closest(".chosen-container"),c.length&&this.container[0]===c[0]?this.active_field=!0:this.close_field()},Chosen.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=SelectParser.select_to_array(this.form_field),this.is_multiple?this.search_choices.find("li.search-choice").remove():this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field[0].readOnly=!0,this.container.addClass("chosen-container-single-nosearch")):(this.search_field[0].readOnly=!1,this.container.removeClass("chosen-container-single-nosearch"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},Chosen.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){if(this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight(),b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(f>c)return this.search_results.scrollTop(c)}},Chosen.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},Chosen.prototype.results_show=function(){return this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.container.addClass("chosen-with-drop"),this.results_showing=!0,this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results(),this.form_field_jq.trigger("chosen:showing_dropdown",{chosen:this}))},Chosen.prototype.update_results_content=function(a){return this.search_results.html(a)},Chosen.prototype.results_hide=function(){return this.results_showing&&(this.result_clear_highlight(),this.container.removeClass("chosen-with-drop"),this.form_field_jq.trigger("chosen:hiding_dropdown",{chosen:this})),this.results_showing=!1},Chosen.prototype.set_tab_index=function(){var a;return this.form_field.tabIndex?(a=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field[0].tabIndex=a):void 0},Chosen.prototype.set_label_behavior=function(){var b=this;return this.form_field_label=this.form_field_jq.parents("label"),!this.form_field_label.length&&this.form_field.id.length&&(this.form_field_label=a("label[for='"+this.form_field.id+"']")),this.form_field_label.length>0?this.form_field_label.bind("click.chosen",function(a){return b.is_multiple?b.container_mousedown(a):b.activate_field()}):void 0},Chosen.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},Chosen.prototype.search_results_mouseup=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c.length?(this.result_highlight=c,this.result_select(b),this.search_field.focus()):void 0},Chosen.prototype.search_results_mouseover=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c?this.result_do_highlight(c):void 0},Chosen.prototype.search_results_mouseout=function(b){return a(b.target).hasClass("active-result")?this.result_clear_highlight():void 0},Chosen.prototype.choice_build=function(b){var c,d,e=this;return c=a("",{"class":"search-choice"}).html(""+this.choice_label(b)+""),b.disabled?c.addClass("search-choice-disabled"):(d=a("",{"class":"search-choice-close","data-option-array-index":b.array_index}),d.bind("click.chosen",function(a){return e.choice_destroy_link_click(a)}),c.append(d)),this.search_container.before(c)},Chosen.prototype.choice_destroy_link_click=function(b){return b.preventDefault(),b.stopPropagation(),this.is_disabled?void 0:this.choice_destroy(a(b.target))},Chosen.prototype.choice_destroy=function(a){return this.result_deselect(a[0].getAttribute("data-option-array-index"))?(this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.val().length<1&&this.results_hide(),a.parents("li").first().remove(),this.search_field_scale()):void 0},Chosen.prototype.results_reset=function(){return this.reset_single_select_options(),this.form_field.options[0].selected=!0,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup(),this.form_field_jq.trigger("change"),this.active_field?this.results_hide():void 0},Chosen.prototype.results_reset_cleanup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.selected_item.find("abbr").remove()},Chosen.prototype.result_select=function(a){var b,c;return this.result_highlight?(b=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?b.removeClass("active-result"):this.reset_single_select_options(),c=this.results_data[b[0].getAttribute("data-option-array-index")],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(c):this.single_set_selected_text(this.choice_label(c)),(a.metaKey||a.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field.selectedIndex!==this.current_selectedIndex)&&this.form_field_jq.trigger("change",{selected:this.form_field.options[c.options_index].value}),this.current_selectedIndex=this.form_field.selectedIndex,a.preventDefault(),this.search_field_scale())):void 0},Chosen.prototype.single_set_selected_text=function(a){return null==a&&(a=this.default_text),a===this.default_text?this.selected_item.addClass("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClass("chosen-default")),this.selected_item.find("span").html(a)},Chosen.prototype.result_deselect=function(a){var b;return b=this.results_data[a],this.form_field.options[b.options_index].disabled?!1:(b.selected=!1,this.form_field.options[b.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[b.options_index].value}),this.search_field_scale(),!0)},Chosen.prototype.single_deselect_control_build=function(){return this.allow_single_deselect?(this.selected_item.find("abbr").length||this.selected_item.find("span").first().after(''),this.selected_item.addClass("chosen-single-with-deselect")):void 0},Chosen.prototype.get_search_text=function(){return a("").text(a.trim(this.search_field.val())).html()},Chosen.prototype.winnow_results_set_highlight=function(){var a,b;return b=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),a=b.length?b.first():this.search_results.find(".active-result").first(),null!=a?this.result_do_highlight(a):void 0},Chosen.prototype.no_results=function(b){var c;return c=a(''+this.results_none_found+' ""'),c.find("span").first().html(b),this.search_results.append(c),this.form_field_jq.trigger("chosen:no_results",{chosen:this})},Chosen.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},Chosen.prototype.keydown_arrow=function(){var a;return this.results_showing&&this.result_highlight?(a=this.result_highlight.nextAll("li.active-result").first())?this.result_do_highlight(a):void 0:this.results_show()},Chosen.prototype.keyup_arrow=function(){var a;return this.results_showing||this.is_multiple?this.result_highlight?(a=this.result_highlight.prevAll("li.active-result"),a.length?this.result_do_highlight(a.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},Chosen.prototype.keydown_backstroke=function(){var a;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(a=this.search_container.siblings("li.search-choice").last(),a.length&&!a.hasClass("search-choice-disabled")?(this.pending_backstroke=a,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")):void 0)},Chosen.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},Chosen.prototype.keydown_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),8!==b&&this.pending_backstroke&&this.clear_backstroke(),b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:this.results_showing&&a.preventDefault();break;case 32:this.disable_search&&a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:a.preventDefault(),this.keydown_arrow()}},Chosen.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){for(d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],i=0,j=g.length;j>i;i++)e=g[i],f+=e+":"+this.search_field.css(e)+";";return b=a("",{style:f}),b.text(this.search_field.val()),a("body").append(b),h=b.width()+25,b.remove(),c=this.container.outerWidth(),h>c-10&&(h=c-10),this.search_field.css({width:h+"px"})}},Chosen}(AbstractChosen)}).call(this);
--------------------------------------------------------------------------------
/examples/javascripts/chosen/chosen.min.css:
--------------------------------------------------------------------------------
1 | /* Chosen v1.4.1 | (c) 2011-2015 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
2 |
3 | .chosen-container{position:relative;display:inline-block;vertical-align:middle;font-size:13px;zoom:1;*display:inline;-webkit-user-select:none;-moz-user-select:none;user-select:none}.chosen-container *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.chosen-container .chosen-drop{position:absolute;top:100%;left:-9999px;z-index:1010;width:100%;border:1px solid #aaa;border-top:0;background:#fff;box-shadow:0 4px 5px rgba(0,0,0,.15)}.chosen-container.chosen-with-drop .chosen-drop{left:0}.chosen-container a{cursor:pointer}.chosen-container .search-choice .group-name,.chosen-container .chosen-single .group-name{margin-right:4px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-weight:400;color:#999}.chosen-container .search-choice .group-name:after,.chosen-container .chosen-single .group-name:after{content:":";padding-left:2px;vertical-align:top}.chosen-container-single .chosen-single{position:relative;display:block;overflow:hidden;padding:0 0 0 8px;height:25px;border:1px solid #aaa;border-radius:5px;background-color:#fff;background:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#fff),color-stop(50%,#f6f6f6),color-stop(52%,#eee),color-stop(100%,#f4f4f4));background:-webkit-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-moz-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-o-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background-clip:padding-box;box-shadow:0 0 3px #fff inset,0 1px 1px rgba(0,0,0,.1);color:#444;text-decoration:none;white-space:nowrap;line-height:24px}.chosen-container-single .chosen-default{color:#999}.chosen-container-single .chosen-single span{display:block;overflow:hidden;margin-right:26px;text-overflow:ellipsis;white-space:nowrap}.chosen-container-single .chosen-single-with-deselect span{margin-right:38px}.chosen-container-single .chosen-single abbr{position:absolute;top:6px;right:26px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-single .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single.chosen-disabled .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single .chosen-single div{position:absolute;top:0;right:0;display:block;width:18px;height:100%}.chosen-container-single .chosen-single div b{display:block;width:100%;height:100%;background:url(chosen-sprite.png) no-repeat 0 2px}.chosen-container-single .chosen-search{position:relative;z-index:1010;margin:0;padding:3px 4px;white-space:nowrap}.chosen-container-single .chosen-search input[type=text]{margin:1px 0;padding:4px 20px 4px 5px;width:100%;height:auto;outline:0;border:1px solid #aaa;background:#fff url(chosen-sprite.png) no-repeat 100% -20px;background:url(chosen-sprite.png) no-repeat 100% -20px;font-size:1em;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-single .chosen-drop{margin-top:-1px;border-radius:0 0 4px 4px;background-clip:padding-box}.chosen-container-single.chosen-container-single-nosearch .chosen-search{position:absolute;left:-9999px}.chosen-container .chosen-results{color:#444;position:relative;overflow-x:hidden;overflow-y:auto;margin:0 4px 4px 0;padding:0 0 0 4px;max-height:240px;-webkit-overflow-scrolling:touch}.chosen-container .chosen-results li{display:none;margin:0;padding:5px 6px;list-style:none;line-height:15px;word-wrap:break-word;-webkit-touch-callout:none}.chosen-container .chosen-results li.active-result{display:list-item;cursor:pointer}.chosen-container .chosen-results li.disabled-result{display:list-item;color:#ccc;cursor:default}.chosen-container .chosen-results li.highlighted{background-color:#3875d7;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#3875d7),color-stop(90%,#2a62bc));background-image:-webkit-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-moz-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-o-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:linear-gradient(#3875d7 20%,#2a62bc 90%);color:#fff}.chosen-container .chosen-results li.no-results{color:#777;display:list-item;background:#f4f4f4}.chosen-container .chosen-results li.group-result{display:list-item;font-weight:700;cursor:default}.chosen-container .chosen-results li.group-option{padding-left:15px}.chosen-container .chosen-results li em{font-style:normal;text-decoration:underline}.chosen-container-multi .chosen-choices{position:relative;overflow:hidden;margin:0;padding:0 5px;width:100%;height:auto!important;height:1%;border:1px solid #aaa;background-color:#fff;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(1%,#eee),color-stop(15%,#fff));background-image:-webkit-linear-gradient(#eee 1%,#fff 15%);background-image:-moz-linear-gradient(#eee 1%,#fff 15%);background-image:-o-linear-gradient(#eee 1%,#fff 15%);background-image:linear-gradient(#eee 1%,#fff 15%);cursor:text}.chosen-container-multi .chosen-choices li{float:left;list-style:none}.chosen-container-multi .chosen-choices li.search-field{margin:0;padding:0;white-space:nowrap}.chosen-container-multi .chosen-choices li.search-field input[type=text]{margin:1px 0;padding:0;height:25px;outline:0;border:0!important;background:transparent!important;box-shadow:none;color:#999;font-size:100%;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-multi .chosen-choices li.search-choice{position:relative;margin:3px 5px 3px 0;padding:3px 20px 3px 5px;border:1px solid #aaa;max-width:100%;border-radius:3px;background-color:#eee;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-size:100% 19px;background-repeat:repeat-x;background-clip:padding-box;box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,.05);color:#333;line-height:13px;cursor:default}.chosen-container-multi .chosen-choices li.search-choice span{word-wrap:break-word}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close{position:absolute;top:4px;right:3px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover{background-position:-42px -10px}.chosen-container-multi .chosen-choices li.search-choice-disabled{padding-right:5px;border:1px solid #ccc;background-color:#e4e4e4;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);color:#666}.chosen-container-multi .chosen-choices li.search-choice-focus{background:#d4d4d4}.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close{background-position:-42px -10px}.chosen-container-multi .chosen-results{margin:0;padding:0}.chosen-container-multi .chosen-drop .result-selected{display:list-item;color:#ccc;cursor:default}.chosen-container-active .chosen-single{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active.chosen-with-drop .chosen-single{border:1px solid #aaa;-moz-border-radius-bottomright:0;border-bottom-right-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#eee),color-stop(80%,#fff));background-image:-webkit-linear-gradient(#eee 20%,#fff 80%);background-image:-moz-linear-gradient(#eee 20%,#fff 80%);background-image:-o-linear-gradient(#eee 20%,#fff 80%);background-image:linear-gradient(#eee 20%,#fff 80%);box-shadow:0 1px 0 #fff inset}.chosen-container-active.chosen-with-drop .chosen-single div{border-left:0;background:transparent}.chosen-container-active.chosen-with-drop .chosen-single div b{background-position:-18px 2px}.chosen-container-active .chosen-choices{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active .chosen-choices li.search-field input[type=text]{color:#222!important}.chosen-disabled{opacity:.5!important;cursor:default}.chosen-disabled .chosen-single{cursor:default}.chosen-disabled .chosen-choices .search-choice .search-choice-close{cursor:default}.chosen-rtl{text-align:right}.chosen-rtl .chosen-single{overflow:visible;padding:0 8px 0 0}.chosen-rtl .chosen-single span{margin-right:0;margin-left:26px;direction:rtl}.chosen-rtl .chosen-single-with-deselect span{margin-left:38px}.chosen-rtl .chosen-single div{right:auto;left:3px}.chosen-rtl .chosen-single abbr{right:auto;left:26px}.chosen-rtl .chosen-choices li{float:right}.chosen-rtl .chosen-choices li.search-field input[type=text]{direction:rtl}.chosen-rtl .chosen-choices li.search-choice{margin:3px 5px 3px 0;padding:3px 5px 3px 19px}.chosen-rtl .chosen-choices li.search-choice .search-choice-close{right:auto;left:4px}.chosen-rtl.chosen-container-single-nosearch .chosen-search,.chosen-rtl .chosen-drop{left:9999px}.chosen-rtl.chosen-container-single .chosen-results{margin:0 0 4px 4px;padding:0 4px 0 0}.chosen-rtl .chosen-results li.group-option{padding-right:15px;padding-left:0}.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div{border-right:0}.chosen-rtl .chosen-search input[type=text]{padding:4px 5px 4px 20px;background:#fff url(chosen-sprite.png) no-repeat -30px -20px;background:url(chosen-sprite.png) no-repeat -30px -20px;direction:rtl}.chosen-rtl.chosen-container-single .chosen-single div b{background-position:6px 2px}.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b{background-position:-12px 2px}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:144dpi),only screen and (min-resolution:1.5dppx){.chosen-rtl .chosen-search input[type=text],.chosen-container-single .chosen-single abbr,.chosen-container-single .chosen-single div b,.chosen-container-single .chosen-search input[type=text],.chosen-container-multi .chosen-choices .search-choice .search-choice-close,.chosen-container .chosen-results-scroll-down span,.chosen-container .chosen-results-scroll-up span{background-image:url(chosen-sprite@2x.png)!important;background-size:52px 37px!important;background-repeat:no-repeat!important}}
--------------------------------------------------------------------------------
/examples/javascripts/chosen/chosen.proto.min.js:
--------------------------------------------------------------------------------
1 | /* Chosen v1.4.1 | (c) 2011-2015 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
2 | (function(){var AbstractChosen,SelectParser,a,b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};SelectParser=function(){function SelectParser(){this.options_index=0,this.parsed=[]}return SelectParser.prototype.add_node=function(a){return"OPTGROUP"===a.nodeName.toUpperCase()?this.add_group(a):this.add_option(a)},SelectParser.prototype.add_group=function(a){var b,c,d,e,f,g;for(b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:this.escapeExpression(a.label),title:a.title?a.title:void 0,children:0,disabled:a.disabled,classes:a.className}),f=a.childNodes,g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},SelectParser.prototype.add_option=function(a,b,c){return"OPTION"===a.nodeName.toUpperCase()?(""!==a.text?(null!=b&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,title:a.title?a.title:void 0,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,group_label:null!=b?this.parsed[b].label:null,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1):void 0},SelectParser.prototype.escapeExpression=function(a){var b,c;return null==a||a===!1?"":/[\&\<\>\"\'\`]/.test(a)?(b={"<":"<",">":">",'"':""","'":"'","`":"`"},c=/&(?!\w+;)|[\<\>\"\'\`]/g,a.replace(c,function(a){return b[a]||"&"})):a},SelectParser}(),SelectParser.select_to_array=function(a){var b,c,d,e,f;for(c=new SelectParser,f=a.childNodes,d=0,e=f.length;e>d;d++)b=f[d],c.add_node(b);return c.parsed},AbstractChosen=function(){function AbstractChosen(a,b){this.form_field=a,this.options=null!=b?b:{},AbstractChosen.browser_is_supported()&&(this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers(),this.on_ready())}return AbstractChosen.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.allow_single_deselect=null!=this.options.allow_single_deselect&&null!=this.form_field.options[0]&&""===this.form_field.options[0].text?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.enable_split_word_search=null!=this.options.enable_split_word_search?this.options.enable_split_word_search:!0,this.group_search=null!=this.options.group_search?this.options.group_search:!0,this.search_contains=this.options.search_contains||!1,this.single_backstroke_delete=null!=this.options.single_backstroke_delete?this.options.single_backstroke_delete:!0,this.max_selected_options=this.options.max_selected_options||1/0,this.inherit_select_classes=this.options.inherit_select_classes||!1,this.display_selected_options=null!=this.options.display_selected_options?this.options.display_selected_options:!0,this.display_disabled_options=null!=this.options.display_disabled_options?this.options.display_disabled_options:!0,this.include_group_label_in_selected=this.options.include_group_label_in_selected||!1},AbstractChosen.prototype.set_default_text=function(){return this.default_text=this.form_field.getAttribute("data-placeholder")?this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.options.placeholder_text_multiple||this.options.placeholder_text||AbstractChosen.default_multiple_text:this.options.placeholder_text_single||this.options.placeholder_text||AbstractChosen.default_single_text,this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||AbstractChosen.default_no_result_text},AbstractChosen.prototype.choice_label=function(a){return this.include_group_label_in_selected&&null!=a.group_label?""+a.group_label+""+a.html:a.html},AbstractChosen.prototype.mouse_enter=function(){return this.mouse_on_container=!0},AbstractChosen.prototype.mouse_leave=function(){return this.mouse_on_container=!1},AbstractChosen.prototype.input_focus=function(){var a=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return a.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},AbstractChosen.prototype.input_blur=function(){var a=this;return this.mouse_on_container?void 0:(this.active_field=!1,setTimeout(function(){return a.blur_test()},100))},AbstractChosen.prototype.results_option_build=function(a){var b,c,d,e,f;for(b="",f=this.results_data,d=0,e=f.length;e>d;d++)c=f[d],b+=c.group?this.result_add_group(c):this.result_add_option(c),(null!=a?a.first:void 0)&&(c.selected&&this.is_multiple?this.choice_build(c):c.selected&&!this.is_multiple&&this.single_set_selected_text(this.choice_label(c)));return b},AbstractChosen.prototype.result_add_option=function(a){var b,c;return a.search_match?this.include_option_in_results(a)?(b=[],a.disabled||a.selected&&this.is_multiple||b.push("active-result"),!a.disabled||a.selected&&this.is_multiple||b.push("disabled-result"),a.selected&&b.push("result-selected"),null!=a.group_array_index&&b.push("group-option"),""!==a.classes&&b.push(a.classes),c=document.createElement("li"),c.className=b.join(" "),c.style.cssText=a.style,c.setAttribute("data-option-array-index",a.array_index),c.innerHTML=a.search_text,a.title&&(c.title=a.title),this.outerHTML(c)):"":""},AbstractChosen.prototype.result_add_group=function(a){var b,c;return a.search_match||a.group_match?a.active_options>0?(b=[],b.push("group-result"),a.classes&&b.push(a.classes),c=document.createElement("li"),c.className=b.join(" "),c.innerHTML=a.search_text,a.title&&(c.title=a.title),this.outerHTML(c)):"":""},AbstractChosen.prototype.results_update_field=function(){return this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.results_build(),this.results_showing?this.winnow_results():void 0},AbstractChosen.prototype.reset_single_select_options=function(){var a,b,c,d,e;for(d=this.results_data,e=[],b=0,c=d.length;c>b;b++)a=d[b],a.selected?e.push(a.selected=!1):e.push(void 0);return e},AbstractChosen.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},AbstractChosen.prototype.results_search=function(){return this.results_showing?this.winnow_results():this.results_show()},AbstractChosen.prototype.winnow_results=function(){var a,b,c,d,e,f,g,h,i,j,k,l;for(this.no_results_clear(),d=0,f=this.get_search_text(),a=f.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),i=new RegExp(a,"i"),c=this.get_search_regex(a),l=this.results_data,j=0,k=l.length;k>j;j++)b=l[j],b.search_match=!1,e=null,this.include_option_in_results(b)&&(b.group&&(b.group_match=!1,b.active_options=0),null!=b.group_array_index&&this.results_data[b.group_array_index]&&(e=this.results_data[b.group_array_index],0===e.active_options&&e.search_match&&(d+=1),e.active_options+=1),b.search_text=b.group?b.label:b.html,(!b.group||this.group_search)&&(b.search_match=this.search_string_match(b.search_text,c),b.search_match&&!b.group&&(d+=1),b.search_match?(f.length&&(g=b.search_text.search(i),h=b.search_text.substr(0,g+f.length)+""+b.search_text.substr(g+f.length),b.search_text=h.substr(0,g)+""+h.substr(g)),null!=e&&(e.group_match=!0)):null!=b.group_array_index&&this.results_data[b.group_array_index].search_match&&(b.search_match=!0)));return this.result_clear_highlight(),1>d&&f.length?(this.update_results_content(""),this.no_results(f)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight())},AbstractChosen.prototype.get_search_regex=function(a){var b;return b=this.search_contains?"":"^",new RegExp(b+a,"i")},AbstractChosen.prototype.search_string_match=function(a,b){var c,d,e,f;if(b.test(a))return!0;if(this.enable_split_word_search&&(a.indexOf(" ")>=0||0===a.indexOf("["))&&(d=a.replace(/\[|\]/g,"").split(" "),d.length))for(e=0,f=d.length;f>e;e++)if(c=d[e],b.test(c))return!0},AbstractChosen.prototype.choices_count=function(){var a,b,c,d;if(null!=this.selected_option_count)return this.selected_option_count;for(this.selected_option_count=0,d=this.form_field.options,b=0,c=d.length;c>b;b++)a=d[b],a.selected&&(this.selected_option_count+=1);return this.selected_option_count},AbstractChosen.prototype.choices_click=function(a){return a.preventDefault(),this.results_showing||this.is_disabled?void 0:this.results_show()},AbstractChosen.prototype.keyup_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices_count()>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(a.preventDefault(),this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},AbstractChosen.prototype.clipboard_event_checker=function(){var a=this;return setTimeout(function(){return a.results_search()},50)},AbstractChosen.prototype.container_width=function(){return null!=this.options.width?this.options.width:""+this.form_field.offsetWidth+"px"},AbstractChosen.prototype.include_option_in_results=function(a){return this.is_multiple&&!this.display_selected_options&&a.selected?!1:!this.display_disabled_options&&a.disabled?!1:a.empty?!1:!0},AbstractChosen.prototype.search_results_touchstart=function(a){return this.touch_started=!0,this.search_results_mouseover(a)},AbstractChosen.prototype.search_results_touchmove=function(a){return this.touch_started=!1,this.search_results_mouseout(a)},AbstractChosen.prototype.search_results_touchend=function(a){return this.touch_started?this.search_results_mouseup(a):void 0},AbstractChosen.prototype.outerHTML=function(a){var b;return a.outerHTML?a.outerHTML:(b=document.createElement("div"),b.appendChild(a),b.innerHTML)},AbstractChosen.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:/iP(od|hone)/i.test(window.navigator.userAgent)?!1:/Android/i.test(window.navigator.userAgent)&&/Mobile/i.test(window.navigator.userAgent)?!1:!0},AbstractChosen.default_multiple_text="Select Some Options",AbstractChosen.default_single_text="Select an Option",AbstractChosen.default_no_result_text="No results match",AbstractChosen}(),this.Chosen=function(b){function Chosen(){return a=Chosen.__super__.constructor.apply(this,arguments)}return c(Chosen,b),Chosen.prototype.setup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field.hasClassName("chosen-rtl")},Chosen.prototype.set_default_values=function(){return Chosen.__super__.set_default_values.call(this),this.single_temp=new Template('#{default}
'),this.multi_temp=new Template(''),this.no_results_temp=new Template(''+this.results_none_found+' "#{terms}"')},Chosen.prototype.set_up_html=function(){var a,b;return a=["chosen-container"],a.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&a.push(this.form_field.className),this.is_rtl&&a.push("chosen-rtl"),b={"class":a.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(b.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=this.is_multiple?new Element("div",b).update(this.multi_temp.evaluate({"default":this.default_text})):new Element("div",b).update(this.single_temp.evaluate({"default":this.default_text})),this.form_field.hide().insert({after:this.container}),this.dropdown=this.container.down("div.chosen-drop"),this.search_field=this.container.down("input"),this.search_results=this.container.down("ul.chosen-results"),this.search_field_scale(),this.search_no_results=this.container.down("li.no-results"),this.is_multiple?(this.search_choices=this.container.down("ul.chosen-choices"),this.search_container=this.container.down("li.search-field")):(this.search_container=this.container.down("div.chosen-search"),this.selected_item=this.container.down(".chosen-single")),this.results_build(),this.set_tab_index(),this.set_label_behavior()},Chosen.prototype.on_ready=function(){return this.form_field.fire("chosen:ready",{chosen:this})},Chosen.prototype.register_observers=function(){var a=this;return this.container.observe("touchstart",function(b){return a.container_mousedown(b),b.preventDefault()}),this.container.observe("touchend",function(b){return a.container_mouseup(b),b.preventDefault()}),this.container.observe("mousedown",function(b){return a.container_mousedown(b)}),this.container.observe("mouseup",function(b){return a.container_mouseup(b)}),this.container.observe("mouseenter",function(b){return a.mouse_enter(b)}),this.container.observe("mouseleave",function(b){return a.mouse_leave(b)}),this.search_results.observe("mouseup",function(b){return a.search_results_mouseup(b)}),this.search_results.observe("mouseover",function(b){return a.search_results_mouseover(b)}),this.search_results.observe("mouseout",function(b){return a.search_results_mouseout(b)}),this.search_results.observe("mousewheel",function(b){return a.search_results_mousewheel(b)}),this.search_results.observe("DOMMouseScroll",function(b){return a.search_results_mousewheel(b)}),this.search_results.observe("touchstart",function(b){return a.search_results_touchstart(b)}),this.search_results.observe("touchmove",function(b){return a.search_results_touchmove(b)}),this.search_results.observe("touchend",function(b){return a.search_results_touchend(b)}),this.form_field.observe("chosen:updated",function(b){return a.results_update_field(b)}),this.form_field.observe("chosen:activate",function(b){return a.activate_field(b)}),this.form_field.observe("chosen:open",function(b){return a.container_mousedown(b)}),this.form_field.observe("chosen:close",function(b){return a.input_blur(b)}),this.search_field.observe("blur",function(b){return a.input_blur(b)}),this.search_field.observe("keyup",function(b){return a.keyup_checker(b)}),this.search_field.observe("keydown",function(b){return a.keydown_checker(b)}),this.search_field.observe("focus",function(b){return a.input_focus(b)}),this.search_field.observe("cut",function(b){return a.clipboard_event_checker(b)}),this.search_field.observe("paste",function(b){return a.clipboard_event_checker(b)}),this.is_multiple?this.search_choices.observe("click",function(b){return a.choices_click(b)}):this.container.observe("click",function(a){return a.preventDefault()})},Chosen.prototype.destroy=function(){return this.container.ownerDocument.stopObserving("click",this.click_test_action),this.form_field.stopObserving(),this.container.stopObserving(),this.search_results.stopObserving(),this.search_field.stopObserving(),null!=this.form_field_label&&this.form_field_label.stopObserving(),this.is_multiple?(this.search_choices.stopObserving(),this.container.select(".search-choice-close").each(function(a){return a.stopObserving()})):this.selected_item.stopObserving(),this.search_field.tabIndex&&(this.form_field.tabIndex=this.search_field.tabIndex),this.container.remove(),this.form_field.show()},Chosen.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field.disabled,this.is_disabled?(this.container.addClassName("chosen-disabled"),this.search_field.disabled=!0,this.is_multiple||this.selected_item.stopObserving("focus",this.activate_action),this.close_field()):(this.container.removeClassName("chosen-disabled"),this.search_field.disabled=!1,this.is_multiple?void 0:this.selected_item.observe("focus",this.activate_action))},Chosen.prototype.container_mousedown=function(a){return this.is_disabled||(a&&"mousedown"===a.type&&!this.results_showing&&a.stop(),null!=a&&a.target.hasClassName("search-choice-close"))?void 0:(this.active_field?this.is_multiple||!a||a.target!==this.selected_item&&!a.target.up("a.chosen-single")||this.results_toggle():(this.is_multiple&&this.search_field.clear(),this.container.ownerDocument.observe("click",this.click_test_action),this.results_show()),this.activate_field())},Chosen.prototype.container_mouseup=function(a){return"ABBR"!==a.target.nodeName||this.is_disabled?void 0:this.results_reset(a)},Chosen.prototype.search_results_mousewheel=function(a){var b;return b=a.deltaY||-a.wheelDelta||a.detail,null!=b?(a.preventDefault(),"DOMMouseScroll"===a.type&&(b=40*b),this.search_results.scrollTop=b+this.search_results.scrollTop):void 0},Chosen.prototype.blur_test=function(){return!this.active_field&&this.container.hasClassName("chosen-container-active")?this.close_field():void 0},Chosen.prototype.close_field=function(){return this.container.ownerDocument.stopObserving("click",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClassName("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},Chosen.prototype.activate_field=function(){return this.container.addClassName("chosen-container-active"),this.active_field=!0,this.search_field.value=this.search_field.value,this.search_field.focus()},Chosen.prototype.test_active_click=function(a){return a.target.up(".chosen-container")===this.container?this.active_field=!0:this.close_field()},Chosen.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=SelectParser.select_to_array(this.form_field),this.is_multiple?this.search_choices.select("li.search-choice").invoke("remove"):this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field.readOnly=!0,this.container.addClassName("chosen-container-single-nosearch")):(this.search_field.readOnly=!1,this.container.removeClassName("chosen-container-single-nosearch"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},Chosen.prototype.result_do_highlight=function(a){var b,c,d,e,f;return this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClassName("highlighted"),d=parseInt(this.search_results.getStyle("maxHeight"),10),f=this.search_results.scrollTop,e=d+f,c=this.result_highlight.positionedOffset().top,b=c+this.result_highlight.getHeight(),b>=e?this.search_results.scrollTop=b-d>0?b-d:0:f>c?this.search_results.scrollTop=c:void 0},Chosen.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClassName("highlighted"),this.result_highlight=null},Chosen.prototype.results_show=function(){return this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field.fire("chosen:maxselected",{chosen:this}),!1):(this.container.addClassName("chosen-with-drop"),this.results_showing=!0,this.search_field.focus(),this.search_field.value=this.search_field.value,this.winnow_results(),this.form_field.fire("chosen:showing_dropdown",{chosen:this}))},Chosen.prototype.update_results_content=function(a){return this.search_results.update(a)},Chosen.prototype.results_hide=function(){return this.results_showing&&(this.result_clear_highlight(),this.container.removeClassName("chosen-with-drop"),this.form_field.fire("chosen:hiding_dropdown",{chosen:this})),this.results_showing=!1},Chosen.prototype.set_tab_index=function(){var a;return this.form_field.tabIndex?(a=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field.tabIndex=a):void 0},Chosen.prototype.set_label_behavior=function(){var a=this;return this.form_field_label=this.form_field.up("label"),null==this.form_field_label&&(this.form_field_label=$$("label[for='"+this.form_field.id+"']").first()),null!=this.form_field_label?this.form_field_label.observe("click",function(b){return a.is_multiple?a.container_mousedown(b):a.activate_field()}):void 0},Chosen.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.value=this.default_text,this.search_field.addClassName("default")):(this.search_field.value="",this.search_field.removeClassName("default"))},Chosen.prototype.search_results_mouseup=function(a){var b;return b=a.target.hasClassName("active-result")?a.target:a.target.up(".active-result"),b?(this.result_highlight=b,this.result_select(a),this.search_field.focus()):void 0},Chosen.prototype.search_results_mouseover=function(a){var b;return b=a.target.hasClassName("active-result")?a.target:a.target.up(".active-result"),b?this.result_do_highlight(b):void 0},Chosen.prototype.search_results_mouseout=function(a){return a.target.hasClassName("active-result")||a.target.up(".active-result")?this.result_clear_highlight():void 0},Chosen.prototype.choice_build=function(a){var b,c,d=this;return b=new Element("li",{"class":"search-choice"}).update(""+this.choice_label(a)+""),a.disabled?b.addClassName("search-choice-disabled"):(c=new Element("a",{href:"#","class":"search-choice-close",rel:a.array_index}),c.observe("click",function(a){return d.choice_destroy_link_click(a)}),b.insert(c)),this.search_container.insert({before:b})},Chosen.prototype.choice_destroy_link_click=function(a){return a.preventDefault(),a.stopPropagation(),this.is_disabled?void 0:this.choice_destroy(a.target)},Chosen.prototype.choice_destroy=function(a){return this.result_deselect(a.readAttribute("rel"))?(this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.value.length<1&&this.results_hide(),a.up("li").remove(),this.search_field_scale()):void 0},Chosen.prototype.results_reset=function(){return this.reset_single_select_options(),this.form_field.options[0].selected=!0,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup(),"function"==typeof Event.simulate&&this.form_field.simulate("change"),this.active_field?this.results_hide():void 0},Chosen.prototype.results_reset_cleanup=function(){var a;return this.current_selectedIndex=this.form_field.selectedIndex,a=this.selected_item.down("abbr"),a?a.remove():void 0},Chosen.prototype.result_select=function(a){var b,c;return this.result_highlight?(b=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field.fire("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?b.removeClassName("active-result"):this.reset_single_select_options(),b.addClassName("result-selected"),c=this.results_data[b.getAttribute("data-option-array-index")],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(c):this.single_set_selected_text(this.choice_label(c)),(a.metaKey||a.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.value="","function"!=typeof Event.simulate||!this.is_multiple&&this.form_field.selectedIndex===this.current_selectedIndex||this.form_field.simulate("change"),this.current_selectedIndex=this.form_field.selectedIndex,a.preventDefault(),this.search_field_scale())):void 0},Chosen.prototype.single_set_selected_text=function(a){return null==a&&(a=this.default_text),a===this.default_text?this.selected_item.addClassName("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClassName("chosen-default")),this.selected_item.down("span").update(a)},Chosen.prototype.result_deselect=function(a){var b;return b=this.results_data[a],this.form_field.options[b.options_index].disabled?!1:(b.selected=!1,this.form_field.options[b.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),"function"==typeof Event.simulate&&this.form_field.simulate("change"),this.search_field_scale(),!0)},Chosen.prototype.single_deselect_control_build=function(){return this.allow_single_deselect?(this.selected_item.down("abbr")||this.selected_item.down("span").insert({after:''}),this.selected_item.addClassName("chosen-single-with-deselect")):void 0},Chosen.prototype.get_search_text=function(){return this.search_field.value.strip().escapeHTML()},Chosen.prototype.winnow_results_set_highlight=function(){var a;return this.is_multiple||(a=this.search_results.down(".result-selected.active-result")),null==a&&(a=this.search_results.down(".active-result")),null!=a?this.result_do_highlight(a):void 0},Chosen.prototype.no_results=function(a){return this.search_results.insert(this.no_results_temp.evaluate({terms:a})),this.form_field.fire("chosen:no_results",{chosen:this})},Chosen.prototype.no_results_clear=function(){var a,b;for(a=null,b=[];a=this.search_results.down(".no-results");)b.push(a.remove());return b},Chosen.prototype.keydown_arrow=function(){var a;return this.results_showing&&this.result_highlight?(a=this.result_highlight.next(".active-result"))?this.result_do_highlight(a):void 0:this.results_show()},Chosen.prototype.keyup_arrow=function(){var a,b,c;return this.results_showing||this.is_multiple?this.result_highlight?(c=this.result_highlight.previousSiblings(),a=this.search_results.select("li.active-result"),b=c.intersect(a),b.length?this.result_do_highlight(b.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},Chosen.prototype.keydown_backstroke=function(){var a;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.down("a")),this.clear_backstroke()):(a=this.search_container.siblings().last(),a&&a.hasClassName("search-choice")&&!a.hasClassName("search-choice-disabled")?(this.pending_backstroke=a,this.pending_backstroke&&this.pending_backstroke.addClassName("search-choice-focus"),this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClassName("search-choice-focus")):void 0)},Chosen.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClassName("search-choice-focus"),this.pending_backstroke=null},Chosen.prototype.keydown_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),8!==b&&this.pending_backstroke&&this.clear_backstroke(),b){case 8:this.backstroke_length=this.search_field.value.length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:this.results_showing&&a.preventDefault();break;case 32:this.disable_search&&a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:a.preventDefault(),this.keydown_arrow()}},Chosen.prototype.search_field_scale=function(){var a,b,c,d,e,f,g,h,i;if(this.is_multiple){for(c=0,g=0,e="position:absolute; left: -1000px; top: -1000px; display:none;",f=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],h=0,i=f.length;i>h;h++)d=f[h],e+=d+":"+this.search_field.getStyle(d)+";";return a=new Element("div",{style:e}).update(this.search_field.value.escapeHTML()),document.body.appendChild(a),g=Element.measure(a,"width")+25,a.remove(),b=this.container.getWidth(),g>b-10&&(g=b-10),this.search_field.setStyle({width:g+"px"})}},Chosen}(AbstractChosen)}).call(this);
--------------------------------------------------------------------------------
/examples/javascripts/jquery.sortable.js:
--------------------------------------------------------------------------------
1 | /* ===================================================
2 | * jquery-sortable.js v0.9.12
3 | * http://johnny.github.com/jquery-sortable/
4 | * ===================================================
5 | * Copyright (c) 2012 Jonas von Andrian
6 | * All rights reserved.
7 | *
8 | * Redistribution and use in source and binary forms, with or without
9 | * modification, are permitted provided that the following conditions are met:
10 | * * Redistributions of source code must retain the above copyright
11 | * notice, this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * The name of the author may not be used to endorse or promote products
16 | * derived from this software without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 | * ========================================================== */
29 |
30 |
31 | !function ( $, window, pluginName, undefined){
32 | var eventNames,
33 | containerDefaults = {
34 | // If true, items can be dragged from this container
35 | drag: true,
36 | // If true, items can be droped onto this container
37 | drop: true,
38 | // Exclude items from being draggable, if the
39 | // selector matches the item
40 | exclude: "",
41 | // If true, search for nested containers within an item
42 | nested: true,
43 | // If true, the items are assumed to be arranged vertically
44 | vertical: true
45 | }, // end container defaults
46 | groupDefaults = {
47 | // This is executed after the placeholder has been moved.
48 | // $closestItemOrContainer contains the closest item, the placeholder
49 | // has been put at or the closest empty Container, the placeholder has
50 | // been appended to.
51 | afterMove: function ($placeholder, container, $closestItemOrContainer) {
52 | },
53 | // The exact css path between the container and its items, e.g. "> tbody"
54 | containerPath: "",
55 | // The css selector of the containers
56 | containerSelector: "ol, ul",
57 | // Distance the mouse has to travel to start dragging
58 | distance: 0,
59 | // Time in milliseconds after mousedown until dragging should start.
60 | // This option can be used to prevent unwanted drags when clicking on an element.
61 | delay: 0,
62 | // The css selector of the drag handle
63 | handle: "",
64 | // The exact css path between the item and its subcontainers
65 | itemPath: "",
66 | // The css selector of the items
67 | itemSelector: "li",
68 | // Check if the dragged item may be inside the container.
69 | // Use with care, since the search for a valid container entails a depth first search
70 | // and may be quite expensive.
71 | isValidTarget: function ($item, container) {
72 | return true
73 | },
74 | // Executed before onDrop if placeholder is detached.
75 | // This happens if pullPlaceholder is set to false and the drop occurs outside a container.
76 | onCancel: function ($item, container, _super, event) {
77 | },
78 | // Executed at the beginning of a mouse move event.
79 | // The Placeholder has not been moved yet.
80 | onDrag: function ($item, position, _super, event) {
81 | $item.css(position)
82 | },
83 | // Called after the drag has been started,
84 | // that is the mouse button is beeing held down and
85 | // the mouse is moving.
86 | // The container is the closest initialized container.
87 | // Therefore it might not be the container, that actually contains the item.
88 | onDragStart: function ($item, container, _super, event) {
89 | $item.css({
90 | height: $item.height(),
91 | width: $item.width()
92 | })
93 | $item.addClass("dragged")
94 | $("body").addClass("dragging")
95 | },
96 | // Called when the mouse button is beeing released
97 | onDrop: function ($item, container, _super, event) {
98 | $item.removeClass("dragged").removeAttr("style")
99 | $("body").removeClass("dragging")
100 | },
101 | // Called on mousedown. If falsy value is returned, the dragging will not start.
102 | // If clicked on input element, ignore
103 | onMousedown: function ($item, _super, event) {
104 | if (!event.target.nodeName.match(/^(input|select)$/i)) {
105 | event.preventDefault()
106 | return true
107 | }
108 | },
109 | // Template for the placeholder. Can be any valid jQuery input
110 | // e.g. a string, a DOM element.
111 | // The placeholder must have the class "placeholder"
112 | placeholder: '',
113 | // If true, the position of the placeholder is calculated on every mousemove.
114 | // If false, it is only calculated when the mouse is above a container.
115 | pullPlaceholder: true,
116 | // Specifies serialization of the container group.
117 | // The pair $parent/$children is either container/items or item/subcontainers.
118 | serialize: function ($parent, $children, parentIsContainer) {
119 | var result = $.extend({}, $parent.data())
120 |
121 | if(parentIsContainer)
122 | return [$children]
123 | else if ($children[0]){
124 | result.children = $children
125 | }
126 |
127 | delete result.subContainers
128 | delete result.sortable
129 |
130 | return result
131 | },
132 | // Set tolerance while dragging. Positive values decrease sensitivity,
133 | // negative values increase it.
134 | tolerance: 0
135 | }, // end group defaults
136 | containerGroups = {},
137 | groupCounter = 0,
138 | emptyBox = {
139 | left: 0,
140 | top: 0,
141 | bottom: 0,
142 | right:0
143 | },
144 | eventNames = {
145 | start: "touchstart.sortable mousedown.sortable",
146 | drop: "touchend.sortable touchcancel.sortable mouseup.sortable",
147 | drag: "touchmove.sortable mousemove.sortable",
148 | scroll: "scroll.sortable"
149 | },
150 | subContainerKey = "subContainers"
151 |
152 | /*
153 | * a is Array [left, right, top, bottom]
154 | * b is array [left, top]
155 | */
156 | function d(a,b) {
157 | var x = Math.max(0, a[0] - b[0], b[0] - a[1]),
158 | y = Math.max(0, a[2] - b[1], b[1] - a[3])
159 | return x+y;
160 | }
161 |
162 | function setDimensions(array, dimensions, tolerance, useOffset) {
163 | var i = array.length,
164 | offsetMethod = useOffset ? "offset" : "position"
165 | tolerance = tolerance || 0
166 |
167 | while(i--){
168 | var el = array[i].el ? array[i].el : $(array[i]),
169 | // use fitting method
170 | pos = el[offsetMethod]()
171 | pos.left += parseInt(el.css('margin-left'), 10)
172 | pos.top += parseInt(el.css('margin-top'),10)
173 | dimensions[i] = [
174 | pos.left - tolerance,
175 | pos.left + el.outerWidth() + tolerance,
176 | pos.top - tolerance,
177 | pos.top + el.outerHeight() + tolerance
178 | ]
179 | }
180 | }
181 |
182 | function getRelativePosition(pointer, element) {
183 | var offset = element.offset()
184 | return {
185 | left: pointer.left - offset.left,
186 | top: pointer.top - offset.top
187 | }
188 | }
189 |
190 | function sortByDistanceDesc(dimensions, pointer, lastPointer) {
191 | pointer = [pointer.left, pointer.top]
192 | lastPointer = lastPointer && [lastPointer.left, lastPointer.top]
193 |
194 | var dim,
195 | i = dimensions.length,
196 | distances = []
197 |
198 | while(i--){
199 | dim = dimensions[i]
200 | distances[i] = [i,d(dim,pointer), lastPointer && d(dim, lastPointer)]
201 | }
202 | distances = distances.sort(function (a,b) {
203 | return b[1] - a[1] || b[2] - a[2] || b[0] - a[0]
204 | })
205 |
206 | // last entry is the closest
207 | return distances
208 | }
209 |
210 | function ContainerGroup(options) {
211 | this.options = $.extend({}, groupDefaults, options)
212 | this.containers = []
213 |
214 | if(!this.options.rootGroup){
215 | this.scrollProxy = $.proxy(this.scroll, this)
216 | this.dragProxy = $.proxy(this.drag, this)
217 | this.dropProxy = $.proxy(this.drop, this)
218 | this.placeholder = $(this.options.placeholder)
219 |
220 | if(!options.isValidTarget)
221 | this.options.isValidTarget = undefined
222 | }
223 | }
224 |
225 | ContainerGroup.get = function (options) {
226 | if(!containerGroups[options.group]) {
227 | if(options.group === undefined)
228 | options.group = groupCounter ++
229 |
230 | containerGroups[options.group] = new ContainerGroup(options)
231 | }
232 |
233 | return containerGroups[options.group]
234 | }
235 |
236 | ContainerGroup.prototype = {
237 | dragInit: function (e, itemContainer) {
238 | this.$document = $(itemContainer.el[0].ownerDocument)
239 |
240 | // get item to drag
241 | this.item = $(e.target).closest(this.options.itemSelector)
242 | this.itemContainer = itemContainer
243 |
244 | if(this.item.is(this.options.exclude) ||
245 | !this.options.onMousedown(this.item, groupDefaults.onMousedown, e)){
246 | return
247 | }
248 |
249 | this.setPointer(e)
250 | this.toggleListeners('on')
251 |
252 | this.setupDelayTimer()
253 | this.dragInitDone = true
254 | },
255 | drag: function (e) {
256 | if(!this.dragging){
257 | if(!this.distanceMet(e) || !this.delayMet)
258 | return
259 |
260 | this.options.onDragStart(this.item, this.itemContainer, groupDefaults.onDragStart, e)
261 | this.item.before(this.placeholder)
262 | this.dragging = true
263 | }
264 |
265 | this.setPointer(e)
266 | // place item under the cursor
267 | this.options.onDrag(this.item,
268 | getRelativePosition(this.pointer, this.item.offsetParent()),
269 | groupDefaults.onDrag,
270 | e)
271 |
272 | var x = e.pageX || e.originalEvent.pageX,
273 | y = e.pageY || e.originalEvent.pageY,
274 | box = this.sameResultBox,
275 | t = this.options.tolerance
276 |
277 | if(!box || box.top - t > y || box.bottom + t < y || box.left - t > x || box.right + t < x)
278 | if(!this.searchValidTarget())
279 | this.placeholder.detach()
280 | },
281 | drop: function (e) {
282 | this.toggleListeners('off')
283 |
284 | this.dragInitDone = false
285 |
286 | if(this.dragging){
287 | // processing Drop, check if placeholder is detached
288 | if(this.placeholder.closest("html")[0])
289 | this.placeholder.before(this.item).detach()
290 | else
291 | this.options.onCancel(this.item, this.itemContainer, groupDefaults.onCancel, e)
292 |
293 | this.options.onDrop(this.item, this.getContainer(this.item), groupDefaults.onDrop, e)
294 |
295 | // cleanup
296 | this.clearDimensions()
297 | this.clearOffsetParent()
298 | this.lastAppendedItem = this.sameResultBox = undefined
299 | this.dragging = false
300 | }
301 | },
302 | searchValidTarget: function (pointer, lastPointer) {
303 | if(!pointer){
304 | pointer = this.relativePointer || this.pointer
305 | lastPointer = this.lastRelativePointer || this.lastPointer
306 | }
307 |
308 | var distances = sortByDistanceDesc(this.getContainerDimensions(),
309 | pointer,
310 | lastPointer),
311 | i = distances.length
312 |
313 | while(i--){
314 | var index = distances[i][0],
315 | distance = distances[i][1]
316 |
317 | if(!distance || this.options.pullPlaceholder){
318 | var container = this.containers[index]
319 | if(!container.disabled){
320 | if(!this.$getOffsetParent()){
321 | var offsetParent = container.getItemOffsetParent()
322 | pointer = getRelativePosition(pointer, offsetParent)
323 | lastPointer = getRelativePosition(lastPointer, offsetParent)
324 | }
325 | if(container.searchValidTarget(pointer, lastPointer))
326 | return true
327 | }
328 | }
329 | }
330 | if(this.sameResultBox)
331 | this.sameResultBox = undefined
332 | },
333 | movePlaceholder: function (container, item, method, sameResultBox) {
334 | var lastAppendedItem = this.lastAppendedItem
335 | if(!sameResultBox && lastAppendedItem && lastAppendedItem[0] === item[0])
336 | return;
337 |
338 | item[method](this.placeholder)
339 | this.lastAppendedItem = item
340 | this.sameResultBox = sameResultBox
341 | this.options.afterMove(this.placeholder, container, item)
342 | },
343 | getContainerDimensions: function () {
344 | if(!this.containerDimensions)
345 | setDimensions(this.containers, this.containerDimensions = [], this.options.tolerance, !this.$getOffsetParent())
346 | return this.containerDimensions
347 | },
348 | getContainer: function (element) {
349 | return element.closest(this.options.containerSelector).data(pluginName)
350 | },
351 | $getOffsetParent: function () {
352 | if(this.offsetParent === undefined){
353 | var i = this.containers.length - 1,
354 | offsetParent = this.containers[i].getItemOffsetParent()
355 |
356 | if(!this.options.rootGroup){
357 | while(i--){
358 | if(offsetParent[0] != this.containers[i].getItemOffsetParent()[0]){
359 | // If every container has the same offset parent,
360 | // use position() which is relative to this parent,
361 | // otherwise use offset()
362 | // compare #setDimensions
363 | offsetParent = false
364 | break;
365 | }
366 | }
367 | }
368 |
369 | this.offsetParent = offsetParent
370 | }
371 | return this.offsetParent
372 | },
373 | setPointer: function (e) {
374 | var pointer = this.getPointer(e)
375 |
376 | if(this.$getOffsetParent()){
377 | var relativePointer = getRelativePosition(pointer, this.$getOffsetParent())
378 | this.lastRelativePointer = this.relativePointer
379 | this.relativePointer = relativePointer
380 | }
381 |
382 | this.lastPointer = this.pointer
383 | this.pointer = pointer
384 | },
385 | distanceMet: function (e) {
386 | var currentPointer = this.getPointer(e)
387 | return (Math.max(
388 | Math.abs(this.pointer.left - currentPointer.left),
389 | Math.abs(this.pointer.top - currentPointer.top)
390 | ) >= this.options.distance)
391 | },
392 | getPointer: function(e) {
393 | return {
394 | left: e.pageX || e.originalEvent.pageX,
395 | top: e.pageY || e.originalEvent.pageY
396 | }
397 | },
398 | setupDelayTimer: function () {
399 | var that = this
400 | this.delayMet = !this.options.delay
401 |
402 | // init delay timer if needed
403 | if (!this.delayMet) {
404 | clearTimeout(this._mouseDelayTimer);
405 | this._mouseDelayTimer = setTimeout(function() {
406 | that.delayMet = true
407 | }, this.options.delay)
408 | }
409 | },
410 | scroll: function (e) {
411 | this.clearDimensions()
412 | this.clearOffsetParent() // TODO is this needed?
413 | },
414 | toggleListeners: function (method) {
415 | var that = this,
416 | events = ['drag','drop','scroll']
417 |
418 | $.each(events,function (i,event) {
419 | that.$document[method](eventNames[event], that[event + 'Proxy'])
420 | })
421 | },
422 | clearOffsetParent: function () {
423 | this.offsetParent = undefined
424 | },
425 | // Recursively clear container and item dimensions
426 | clearDimensions: function () {
427 | this.traverse(function(object){
428 | object._clearDimensions()
429 | })
430 | },
431 | traverse: function(callback) {
432 | callback(this)
433 | var i = this.containers.length
434 | while(i--){
435 | this.containers[i].traverse(callback)
436 | }
437 | },
438 | _clearDimensions: function(){
439 | this.containerDimensions = undefined
440 | },
441 | _destroy: function () {
442 | containerGroups[this.options.group] = undefined
443 | }
444 | }
445 |
446 | function Container(element, options) {
447 | this.el = element
448 | this.options = $.extend( {}, containerDefaults, options)
449 |
450 | this.group = ContainerGroup.get(this.options)
451 | this.rootGroup = this.options.rootGroup || this.group
452 | this.handle = this.rootGroup.options.handle || this.rootGroup.options.itemSelector
453 |
454 | var itemPath = this.rootGroup.options.itemPath
455 | this.target = itemPath ? this.el.find(itemPath) : this.el
456 |
457 | this.target.on(eventNames.start, this.handle, $.proxy(this.dragInit, this))
458 |
459 | if(this.options.drop)
460 | this.group.containers.push(this)
461 | }
462 |
463 | Container.prototype = {
464 | dragInit: function (e) {
465 | var rootGroup = this.rootGroup
466 |
467 | if( !this.disabled &&
468 | !rootGroup.dragInitDone &&
469 | this.options.drag &&
470 | this.isValidDrag(e)) {
471 | rootGroup.dragInit(e, this)
472 | }
473 | },
474 | isValidDrag: function(e) {
475 | return e.which == 1 ||
476 | e.type == "touchstart" && e.originalEvent.touches.length == 1
477 | },
478 | searchValidTarget: function (pointer, lastPointer) {
479 | var distances = sortByDistanceDesc(this.getItemDimensions(),
480 | pointer,
481 | lastPointer),
482 | i = distances.length,
483 | rootGroup = this.rootGroup,
484 | validTarget = !rootGroup.options.isValidTarget ||
485 | rootGroup.options.isValidTarget(rootGroup.item, this)
486 |
487 | if(!i && validTarget){
488 | rootGroup.movePlaceholder(this, this.target, "append")
489 | return true
490 | } else
491 | while(i--){
492 | var index = distances[i][0],
493 | distance = distances[i][1]
494 | if(!distance && this.hasChildGroup(index)){
495 | var found = this.getContainerGroup(index).searchValidTarget(pointer, lastPointer)
496 | if(found)
497 | return true
498 | }
499 | else if(validTarget){
500 | this.movePlaceholder(index, pointer)
501 | return true
502 | }
503 | }
504 | },
505 | movePlaceholder: function (index, pointer) {
506 | var item = $(this.items[index]),
507 | dim = this.itemDimensions[index],
508 | method = "after",
509 | width = item.outerWidth(),
510 | height = item.outerHeight(),
511 | offset = item.offset(),
512 | sameResultBox = {
513 | left: offset.left,
514 | right: offset.left + width,
515 | top: offset.top,
516 | bottom: offset.top + height
517 | }
518 | if(this.options.vertical){
519 | var yCenter = (dim[2] + dim[3]) / 2,
520 | inUpperHalf = pointer.top <= yCenter
521 | if(inUpperHalf){
522 | method = "before"
523 | sameResultBox.bottom -= height / 2
524 | } else
525 | sameResultBox.top += height / 2
526 | } else {
527 | var xCenter = (dim[0] + dim[1]) / 2,
528 | inLeftHalf = pointer.left <= xCenter
529 | if(inLeftHalf){
530 | method = "before"
531 | sameResultBox.right -= width / 2
532 | } else
533 | sameResultBox.left += width / 2
534 | }
535 | if(this.hasChildGroup(index))
536 | sameResultBox = emptyBox
537 | this.rootGroup.movePlaceholder(this, item, method, sameResultBox)
538 | },
539 | getItemDimensions: function () {
540 | if(!this.itemDimensions){
541 | this.items = this.$getChildren(this.el, "item").filter(":not(.placeholder, .dragged)").get()
542 | setDimensions(this.items, this.itemDimensions = [], this.options.tolerance)
543 | }
544 | return this.itemDimensions
545 | },
546 | getItemOffsetParent: function () {
547 | var offsetParent,
548 | el = this.el
549 | // Since el might be empty we have to check el itself and
550 | // can not do something like el.children().first().offsetParent()
551 | if(el.css("position") === "relative" || el.css("position") === "absolute" || el.css("position") === "fixed")
552 | offsetParent = el
553 | else
554 | offsetParent = el.offsetParent()
555 | return offsetParent
556 | },
557 | hasChildGroup: function (index) {
558 | return this.options.nested && this.getContainerGroup(index)
559 | },
560 | getContainerGroup: function (index) {
561 | var childGroup = $.data(this.items[index], subContainerKey)
562 | if( childGroup === undefined){
563 | var childContainers = this.$getChildren(this.items[index], "container")
564 | childGroup = false
565 |
566 | if(childContainers[0]){
567 | var options = $.extend({}, this.options, {
568 | rootGroup: this.rootGroup,
569 | group: groupCounter ++
570 | })
571 | childGroup = childContainers[pluginName](options).data(pluginName).group
572 | }
573 | $.data(this.items[index], subContainerKey, childGroup)
574 | }
575 | return childGroup
576 | },
577 | $getChildren: function (parent, type) {
578 | var options = this.rootGroup.options,
579 | path = options[type + "Path"],
580 | selector = options[type + "Selector"]
581 |
582 | parent = $(parent)
583 | if(path)
584 | parent = parent.find(path)
585 |
586 | return parent.children(selector)
587 | },
588 | _serialize: function (parent, isContainer) {
589 | var that = this,
590 | childType = isContainer ? "item" : "container",
591 |
592 | children = this.$getChildren(parent, childType).not(this.options.exclude).map(function () {
593 | return that._serialize($(this), !isContainer)
594 | }).get()
595 |
596 | return this.rootGroup.options.serialize(parent, children, isContainer)
597 | },
598 | traverse: function(callback) {
599 | $.each(this.items || [], function(item){
600 | var group = $.data(this, subContainerKey)
601 | if(group)
602 | group.traverse(callback)
603 | });
604 |
605 | callback(this)
606 | },
607 | _clearDimensions: function () {
608 | this.itemDimensions = undefined
609 | },
610 | _destroy: function() {
611 | var that = this;
612 |
613 | this.target.off(eventNames.start, this.handle);
614 | this.el.removeData(pluginName)
615 |
616 | if(this.options.drop)
617 | this.group.containers = $.grep(this.group.containers, function(val){
618 | return val != that
619 | })
620 |
621 | $.each(this.items || [], function(){
622 | $.removeData(this, subContainerKey)
623 | })
624 | }
625 | }
626 |
627 | var API = {
628 | enable: function() {
629 | this.traverse(function(object){
630 | object.disabled = false
631 | })
632 | },
633 | disable: function (){
634 | this.traverse(function(object){
635 | object.disabled = true
636 | })
637 | },
638 | serialize: function () {
639 | return this._serialize(this.el, true)
640 | },
641 | refresh: function() {
642 | this.traverse(function(object){
643 | object._clearDimensions()
644 | })
645 | },
646 | destroy: function () {
647 | this.traverse(function(object){
648 | object._destroy();
649 | })
650 | }
651 | }
652 |
653 | $.extend(Container.prototype, API)
654 |
655 | /**
656 | * jQuery API
657 | *
658 | * Parameters are
659 | * either options on init
660 | * or a method name followed by arguments to pass to the method
661 | */
662 | $.fn[pluginName] = function(methodOrOptions) {
663 | var args = Array.prototype.slice.call(arguments, 1)
664 |
665 | return this.map(function(){
666 | var $t = $(this),
667 | object = $t.data(pluginName)
668 |
669 | if(object && API[methodOrOptions])
670 | return API[methodOrOptions].apply(object, args) || this
671 | else if(!object && (methodOrOptions === undefined ||
672 | typeof methodOrOptions === "object"))
673 | $t.data(pluginName, new Container($t, methodOrOptions))
674 |
675 | return this
676 | });
677 | };
678 |
679 | }(jQuery, window, 'sortable');
--------------------------------------------------------------------------------
/examples/select.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | JSON Form test
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
23 | JSON Form test
24 |
25 |
30 |
31 |
55 |
56 |
--------------------------------------------------------------------------------
/examples/selectajax.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | JSON Form test
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
23 | JSON Form test
24 |
25 |
42 |
43 |
110 |
111 |
--------------------------------------------------------------------------------
/examples/sortable.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | JSON Form test
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
21 |
22 |
23 |
24 | JSON Form test
25 |
26 |
34 |
35 |
61 |
62 |
--------------------------------------------------------------------------------
/examples/string.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | JSON Form test
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
23 | JSON Form test
24 |
25 |
30 |
31 |
53 |
54 |
--------------------------------------------------------------------------------
/gulpfile.coffee:
--------------------------------------------------------------------------------
1 | gulp = require("gulp")
2 | connect = require("gulp-connect")
3 | sass = require("gulp-sass")
4 | coffee = require("gulp-coffee")
5 | include = require("gulp-include")
6 | gulpMerge = require('gulp-merge')
7 | jstConcat = require('gulp-jst-concat')
8 | concat = require('gulp-concat')
9 | _ = require("underscore")
10 |
11 | gulp.task "build", ->
12 |
13 | # JS and JST
14 | gulpMerge(
15 | gulp.src("src/jsonform.coffee")
16 | .pipe(include())
17 | .pipe(coffee({bare: true}))
18 | ,
19 | gulp.src('src/fields/*.jst')
20 | .pipe(jstConcat('jst.js', {
21 | renameKeys: ['^.*src/(.*).jst$', '$1']
22 | }))
23 | ).pipe(concat('jsonform.js'))
24 | .pipe(gulp.dest("dist"))
25 | .pipe(gulp.dest("test"))
26 |
27 | # CSS
28 | gulp.src("src/jsonform.scss")
29 | .pipe(sass())
30 | .pipe(gulp.dest("dist"))
31 | .pipe(gulp.dest("test"))
32 |
33 |
34 | gulp.task "server", ["build"], ->
35 | connect.server
36 | port: 8002
37 | fallback: 'examples/index.html'
38 | gulp.watch(['src/**/*.coffee', 'src/**/*.jst', 'src/**/*.scss'], ['build'])
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | require('coffee-script/register');
2 | require('./gulpfile.coffee');
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jsonform",
3 | "repository": {
4 | "type": "git",
5 | "url": "git://github.com/oreillymedia/jsonform"
6 | },
7 | "devDependencies": {
8 | "coffee-script": "^1.9.1",
9 | "gulp": "^3.8.6",
10 | "gulp-coffee": "^2.1.1",
11 | "gulp-sass": "^0.7.2",
12 | "gulp-connect": "^2.0.6",
13 | "gulp-include": "^1.1.0",
14 | "gulp-merge": "^0.1.0",
15 | "gulp-jst-concat": "^0.0.1",
16 | "gulp-concat": "^2.5.2",
17 | "underscore": "^1.7.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/fields/ajax.coffee:
--------------------------------------------------------------------------------
1 | class jsonform.AjaxField
2 |
3 | @preloadValues: (config, vals, success) ->
4 |
5 | # remove null values
6 | vals = _.compact(vals)
7 | return if _.isEmpty(vals)
8 |
9 | query = {}
10 | query[config.jfReloadParam] = vals
11 |
12 | $.ajax(
13 | url: config.jfUrl
14 | data: query
15 | type: 'GET'
16 | success: (data) =>
17 | success(config.jfParse(data, vals))
18 | error: (data) ->
19 | console.log("error baby")
20 | )
21 |
22 | constructor: (config) ->
23 | @config = config
24 | @tmpl = JST["fields/ajax"]
25 | @jel = $('')
26 | @el = @jel[0]
27 |
28 | render: ->
29 |
30 | timeout = undefined
31 |
32 | @jel.html(@tmpl(@config))
33 | @chosen = @jel.find(".chosen-select")
34 | .chosen(
35 | width:"300px"
36 | allow_single_deselect: true
37 | no_results_text: 'Searching for'
38 | )
39 | @jel.find(".chosen-search input").on('input', (e) =>
40 | clearTimeout(timeout)
41 | timeout = setTimeout(=>
42 | @loadAjax(e)
43 | , 800)
44 | )
45 |
46 | @chosen.change(jsonform.helpers.changed)
47 |
48 | getValue: ->
49 | @jel.find(".chosen-select").val()
50 |
51 | clearValues: ->
52 | @jel.find("select option").remove()
53 | @jel.find("select").append("")
54 | @jel.find(".chosen-select").trigger("chosen:updated")
55 |
56 | setValue: (val) ->
57 |
58 | # if val is a primitive, we have to load the value to
59 | # use as label in the select box. This makes a HTTP request per
60 | # field, which is annoying for hundreds of fields. However, it
61 | # was too hard to implement for collections with nexted objects, so
62 | # that's how it is right now.
63 | if !_.isObject(val)
64 | @constructor.preloadValues(@config, [val], (newVal) =>
65 | @setValue(newVal[0])
66 | )
67 | else
68 | @jel.find(".chosen-select").html('')
69 | @jel.find(".chosen-select").val(val[0])
70 | @jel.find(".chosen-select").trigger("chosen:updated")
71 | jsonform.helpers.changed()
72 |
73 | loadAjax: (e) ->
74 |
75 | chosen = @jel.find(".chosen-container")
76 |
77 | query = {}
78 | searchVal = chosen.find(".chosen-search input").val()
79 | query[@config.jfSearchParam] = searchVal
80 | @clearValues()
81 |
82 | $.ajax(
83 | url: @config.jfUrl
84 | data: query
85 | type: 'GET'
86 | success: (data) =>
87 | results = @config.jfParse(data)
88 | if results.length is 0
89 | chosen.find(".chosen-results").html("No results matched \"#{searchVal}\"")
90 | else
91 | select = @jel.find(".chosen-select")
92 | _.each(results, (result) =>
93 | select.append('')
94 | )
95 | select.trigger("chosen:updated")
96 | chosen.find(".chosen-search input").val(searchVal)
97 | error: (data) ->
98 | console.log("error baby")
99 | )
100 |
101 |
--------------------------------------------------------------------------------
/src/fields/ajax.jst:
--------------------------------------------------------------------------------
1 | <% if(typeof(jfTitle)!== 'undefined') { %><%= jfTitle %><% } %>
2 | <% if(typeof(jfHelper)!== 'undefined') { %><%= jfHelper %><% } %>
3 |
4 |
--------------------------------------------------------------------------------
/src/fields/ajax.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oreillymedia/jsonform/7d38b902dd458587c7d149ee2dde5e28e899160a/src/fields/ajax.scss
--------------------------------------------------------------------------------
/src/fields/boolean.coffee:
--------------------------------------------------------------------------------
1 | class jsonform.BooleanField
2 |
3 | constructor: (config) ->
4 | @config = config
5 | @tmpl = JST["fields/boolean"]
6 | @jel = $('')
7 | @el = @jel[0]
8 |
9 | render: ->
10 | @jel.html(@tmpl(@config))
11 | @jel.find(".chosen-select")
12 | .chosen({disable_search_threshold: 5, width:"300px"})
13 | .change(jsonform.helpers.changed)
14 |
15 | getValue: ->
16 | @jel.find(".chosen-select").val() == "true"
17 |
18 | setValue: (val) ->
19 | @jel.find(".chosen-select").val(val + "")
20 | @jel.find(".chosen-select").trigger("chosen:updated")
--------------------------------------------------------------------------------
/src/fields/boolean.jst:
--------------------------------------------------------------------------------
1 | <% if(typeof(jfTitle)!== 'undefined') { %><%= jfTitle %><% } %>
2 | <% if(typeof(jfHelper)!== 'undefined') { %><%= jfHelper %><% } %>
3 |
4 |
--------------------------------------------------------------------------------
/src/fields/boolean.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oreillymedia/jsonform/7d38b902dd458587c7d149ee2dde5e28e899160a/src/fields/boolean.scss
--------------------------------------------------------------------------------
/src/fields/fieldcollection-del.jst:
--------------------------------------------------------------------------------
1 | Delete
--------------------------------------------------------------------------------
/src/fields/fieldcollection-sort.jst:
--------------------------------------------------------------------------------
1 | ↕
--------------------------------------------------------------------------------
/src/fields/fieldcollection.coffee:
--------------------------------------------------------------------------------
1 | class jsonform.FieldCollection
2 |
3 | constructor: (config) ->
4 | @config = config
5 | @tmpl = JST["fields/fieldcollection"]
6 | @jel = $("")
7 | @el = @jel[0]
8 |
9 | # Array that itself holds an array of fields. This makes
10 | # the field collection work for a single field or a set of fields.
11 | @items = []
12 |
13 | render: ->
14 |
15 | @jel.html(@tmpl(@config))
16 |
17 | @jel.find(".jfAdd").click( (e) =>
18 | return if $(this).is("[disabled]")
19 | e.preventDefault()
20 | @addItem()
21 | )
22 |
23 | if $().sortable
24 | @jel.find(".jfCollection").sortable(
25 | placeholder: ' '
26 | itemSelector: '.jfCollectionItem'
27 | handle: 'i.jfSort'
28 | onDrop: (item, container, _super) =>
29 | _super(item, container)
30 |
31 | # sort by what number of child the el is
32 | @items = _.sortBy(@items, (item) -> item.jel.index())
33 |
34 | jsonform.helpers.changed()
35 | )
36 |
37 | getValues: ->
38 | results = _.map(@items, (item) -> item.getValue())
39 | _.without(results, "", undefined, null)
40 |
41 | addItem: (jsonValue) ->
42 |
43 | item = new jsonform.FieldCollectionItem(@config, jsonValue)
44 | @jel.find(".jfCollection").append(item.el)
45 | item.render()
46 | @items.push(item)
47 |
48 | # listen for click on del
49 | item.jel.on("delete_clicked", (e, item) =>
50 | item.jel.remove()
51 | @items = _.without(@items, item)
52 | @checkAddState()
53 | jsonform.helpers.changed()
54 | )
55 |
56 | # check if we hide or show the add button
57 | @checkAddState()
58 |
59 | # update sortable
60 | if $().sortable
61 | @jel.find(".jfCollection").sortable("refresh")
62 |
63 | # call changed to update json
64 | jsonform.helpers.changed()
65 |
66 | itemsFromValues: (vals) ->
67 | _.each(vals, (val) => @addItem(val))
68 |
69 | checkAddState: ->
70 | if @config.jfMax
71 | if @items.length >= @config.jfMax
72 | @jel.find(".jfAdd").attr("disabled", "disabled")
73 | else
74 | @jel.find(".jfAdd").removeAttr("disabled")
75 |
--------------------------------------------------------------------------------
/src/fields/fieldcollection.jst:
--------------------------------------------------------------------------------
1 | <% if(typeof(jfTitle)!== 'undefined') { %><%= jfTitle %><% } %>
2 | <% if(typeof(jfHelper)!== 'undefined') { %><%= jfHelper %><% } %>
3 |
4 | +
5 |
6 |
--------------------------------------------------------------------------------
/src/fields/fieldcollection.scss:
--------------------------------------------------------------------------------
1 | .jfCollectionItem {
2 | background-color: #FAFAFA;
3 | padding: 10px;
4 | border: 1px solid #C7C7C7;
5 | border-radius: 5px;
6 | margin-bottom: 5px;
7 | max-width: 400px;
8 | }
9 |
10 | .jfAdd {
11 | width: 30px;
12 | height: 30px;
13 | line-height: 30px;
14 | }
15 |
16 | .jfAdd[disabled] {
17 | opacity: 0.4;
18 | pointer-events: none;
19 | }
20 |
21 | a.jfDel {
22 | font-size: 14px;
23 | text-decoration: none;
24 | padding: 3px 5px;
25 | margin-top: 10px;
26 | margin-left: 5px;
27 | color: #DA7D7D;
28 | display: inline-block;
29 | background-color: #ECC8C8;
30 | }
31 |
32 | .jfSort {
33 | font-size: 14px;
34 | margin-top: 10px;
35 | margin-right: 5px;
36 | color: #565555;
37 | display: inline-block;
38 | background-color: #DBDBDB;
39 | text-align: center;
40 | padding: 3px 5px;
41 | vertical-align: top;
42 | border-radius: 3px;
43 | cursor: pointer;
44 | }
45 |
46 | // Draggable
47 |
48 | body.dragging, body.dragging * {
49 | cursor: move !important;
50 | }
51 |
52 | .dragged {
53 | position: absolute;
54 | opacity: 0.5;
55 | z-index: 2000;
56 | }
57 |
58 | div.jfCollection .placeholder {
59 | position: relative;
60 | margin: 0;
61 | padding: 0;
62 | border: none;
63 | &:before {
64 | position: absolute;
65 | content: "";
66 | width: 0;
67 | height: 0;
68 | margin-top: -5px;
69 | left: -5px;
70 | top: -4px;
71 | border: 5px solid transparent;
72 | border-left-color: red;
73 | border-right: none;
74 | }
75 | }
76 |
77 |
--------------------------------------------------------------------------------
/src/fields/fieldcollectionitem.coffee:
--------------------------------------------------------------------------------
1 | class jsonform.FieldCollectionItem
2 |
3 | constructor: (config, jsonValue) ->
4 |
5 | @jsonValue = jsonValue
6 | @deltmpl = JST["fields/fieldcollection-del"]
7 | @sorttmpl = JST["fields/fieldcollection-sort"]
8 | @jel = $('')
9 | @el = @jel[0]
10 | @fields = []
11 |
12 | @config = {}
13 | jQuery.extend(true, @config, config)
14 | delete @config.jfTitle
15 | delete @config.jfHelper
16 | delete @config.jfCollection
17 | delete @config.jfMax
18 |
19 | # if there is a jfType on the root config object,
20 | # this will be a collection holding only single values:
21 | # [1, 2, 3, 4]
22 | if config.jfType
23 | @fields.push jsonform.helpers.newField(@config)
24 |
25 | # otherwise it will be a collection where each collection
26 | # item has a number of fields that become objects in the output:
27 | # [{..}, {..}, {..}]
28 | else
29 | _.each(@config, (v, k) =>
30 | if v.jfType
31 | field = jsonform.helpers.newField(v)
32 | v.jfField = field
33 | @fields.push field
34 | )
35 |
36 | render: ->
37 |
38 | @jel.html("")
39 |
40 | # first append all fields in this item, then render.
41 | # this makes is possible for them to instantiate chosen in render
42 | _.each(@fields, (field) =>
43 | @jel.append(field.el)
44 | field.render()
45 | )
46 |
47 | # if sortable, add sort handle
48 | if $().sortable
49 | @jel.append(@sorttmpl())
50 |
51 | # delete button
52 | del = $(@deltmpl())
53 | @jel.append(del)
54 | del.click( (e) =>
55 | e.preventDefault()
56 | @jel.trigger("delete_clicked", @)
57 | )
58 |
59 | # If we have values to set.
60 | if !_.isUndefined(@jsonValue)
61 |
62 | # if this is just a single field
63 | if @config.jfType
64 | @fields[0].setValue(@jsonValue)
65 |
66 | # otherwise loop through json values and
67 | # assign to fields.
68 | else
69 | _.each(@config, (v, k) =>
70 | if v.jfField && @jsonValue[k]
71 | v.jfField.setValue(@jsonValue[k])
72 | )
73 |
74 | getValue: ->
75 |
76 | # if this is just a single field
77 | if @config.jfType
78 | @fields[0].getValue()
79 |
80 | # otherwise generate js object from the values.
81 | else
82 | values = {}
83 | jQuery.extend(true, values, @config)
84 | _.each(values, (v, k) =>
85 | if v.jfField
86 | values[k] = v.jfField.getValue()
87 | )
88 | values
89 |
--------------------------------------------------------------------------------
/src/fields/fieldcollectionitem.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oreillymedia/jsonform/7d38b902dd458587c7d149ee2dde5e28e899160a/src/fields/fieldcollectionitem.scss
--------------------------------------------------------------------------------
/src/fields/select.coffee:
--------------------------------------------------------------------------------
1 | class jsonform.SelectField
2 |
3 | constructor: (config) ->
4 | @config = config
5 | @tmpl = JST["fields/select"]
6 | @jel = $('')
7 | @el = @jel[0]
8 |
9 | render: ->
10 | @jel.html(@tmpl(@config))
11 | @jel.find(".chosen-select")
12 | .chosen({disable_search_threshold: 5, width:"300px"})
13 | .change(=>
14 | @jel.trigger("jf:changed")
15 | jsonform.helpers.changed()
16 | )
17 |
18 | getValue: ->
19 | @jel.find(".chosen-select").val()
20 |
21 | setValue: (val) ->
22 | @jel.find(".chosen-select").val(val + "")
23 | @jel.find(".chosen-select").trigger("chosen:updated")
--------------------------------------------------------------------------------
/src/fields/select.jst:
--------------------------------------------------------------------------------
1 | <% if(typeof(jfTitle)!== 'undefined') { %><%= jfTitle %><% } %>
2 | <% if(typeof(jfHelper)!== 'undefined') { %><%= jfHelper %><% } %>
3 |
4 |
--------------------------------------------------------------------------------
/src/fields/selectajax.coffee:
--------------------------------------------------------------------------------
1 | class jsonform.SelectAjaxField
2 |
3 | constructor: (config) ->
4 | @config = config
5 | @jel = $('')
6 | @el = @jel[0]
7 | @selectField = new jsonform.SelectField(jfValues: _.map(@config.jfValues, (val) -> val.jfValue))
8 | @ajaxField = new jsonform.AjaxField(@config.jfValues[0])
9 |
10 | render: ->
11 | @jel.html("")
12 | @jel.append(@selectField.el)
13 | @jel.append(@ajaxField.el)
14 | @selectField.render()
15 | @ajaxField.render()
16 | @selectField.jel.on("jf:changed", => @selectSwitched())
17 |
18 | getValue: ->
19 | val = {}
20 | val[@config.jfSelectKey] = @selectField.getValue()
21 | val[@config.jfAjaxKey] = @ajaxField.getValue()
22 | val
23 |
24 | setValue: (val) ->
25 | @selectField.setValue(val[@config.jfSelectKey])
26 |
27 | # find config based on selected key and load the
28 | # needed extra values using that config
29 | ajaxConfig = @getConfigBySelectKey(@selectField.getValue())
30 | jsonform.AjaxField.preloadValues(ajaxConfig, [val[@config.jfAjaxKey]], (data) =>
31 | @ajaxField.config = ajaxConfig
32 | @ajaxField.setValue(data[0])
33 | )
34 |
35 | selectSwitched: ->
36 | ajaxConfig = @getConfigBySelectKey(@selectField.getValue())
37 | @ajaxField.config = ajaxConfig
38 | @ajaxField.setValue(["", ""])
39 |
40 | getConfigBySelectKey: (key) ->
41 | _.find(@config.jfValues, (conf) ->
42 | conf.jfValue[0] is key
43 | )
--------------------------------------------------------------------------------
/src/fields/selectajax.jst:
--------------------------------------------------------------------------------
1 | <% if(typeof(jfTitle)!== 'undefined') { %><%= jfTitle %><% } %>
2 | <% if(typeof(jfHelper)!== 'undefined') { %><%= jfHelper %><% } %>
3 |
4 |
--------------------------------------------------------------------------------
/src/fields/string.coffee:
--------------------------------------------------------------------------------
1 | class jsonform.StringField
2 |
3 | constructor: (config) ->
4 | @config = config
5 | @tmpl = JST["fields/string"]
6 | @jel = $('')
7 | @el = @jel[0]
8 |
9 | render: ->
10 | @jel.html(@tmpl(@config))
11 | @jel.find("input").change(jsonform.helpers.changed)
12 |
13 | getValue: ->
14 | @jel.find("input").val()
15 |
16 | setValue: (val) ->
17 | @jel.find("input").val(val)
--------------------------------------------------------------------------------
/src/fields/string.jst:
--------------------------------------------------------------------------------
1 | <% if(typeof(jfTitle)!== 'undefined') { %><%= jfTitle %><% } %>
2 | <% if(typeof(jfHelper)!== 'undefined') { %><%= jfHelper %><% } %>
3 |
4 |
--------------------------------------------------------------------------------
/src/fields/string.scss:
--------------------------------------------------------------------------------
1 | .jfField input[type="text"] {
2 | padding: 6px 10px;
3 | border: 1px solid #B0B0B0;
4 | border-radius: 5px;
5 | background-color: #F7F7F7;
6 | width: 300px;
7 | font-family: Helvetica, Arial, sans-serif;
8 | font-size: 13px;
9 | color: #444;
10 | outline: none;
11 | vertical-align: top;
12 | }
--------------------------------------------------------------------------------
/src/jsonform.coffee:
--------------------------------------------------------------------------------
1 | window.jsonform = {}
2 |
3 | window.jsonform.helpers = {
4 |
5 | panic: (msg) ->
6 | console.error(msg)
7 | alert(msg)
8 |
9 | isJsonString: (str) ->
10 | try
11 | JSON.parse str
12 | catch e
13 | return false
14 | true
15 |
16 | changed: -> jQuery.event.trigger('jf:change');
17 |
18 | newField : (jfObj) ->
19 | klass = jsonform[jfObj.jfType]
20 | if klass
21 | return new jsonform[jfObj.jfType](jfObj)
22 | else
23 | console.error "jsonform field doesnt exist: " + jfObj.jfType
24 | }
25 |
26 | #= require fields/*.coffee
27 |
28 | class jsonform.Form
29 |
30 | constructor: (txtArea, jsonConfig) ->
31 |
32 | @jel = $('')
33 | @jtxt = $(txtArea)
34 | @jtxt.hide()
35 |
36 | @fields = []
37 | @jsonConfig = jsonConfig
38 | @parseJsonConfig(@jsonConfig)
39 |
40 | # first append field elements so they are a part of the dom
41 | # this makes is possible for them to instantiate chosen in render
42 | _.each(@fields, (field) =>
43 | @jel.append(field.el)
44 | field.render()
45 | )
46 |
47 | # listen to global change events
48 | $(document).bind('jf:change', =>
49 | json = @generateJson(@jsonConfig)
50 | @jtxt.val(JSON.stringify(json, null, 2))
51 | )
52 |
53 | @jtxt.after(@jel)
54 |
55 | # if textarea has data
56 | txtval = @jtxt.val()
57 | if !!txtval
58 | # if value is valid json
59 | if jsonform.helpers.isJsonString(txtval)
60 | @fillFields(JSON.parse(txtval), @jsonConfig)
61 | else
62 | jsonform.helpers.panic("Textarea has invalid JSON. jsonform will not work")
63 |
64 | # Recursive.
65 | generateJson: (obj) ->
66 |
67 | if _.isArray(obj)
68 |
69 | # if array has single item and it has jfCollection
70 | # get values form collection
71 | if obj.length == 1 && obj[0].jfCollection
72 | vals = obj[0].jfCollection.getValues()
73 | if obj[0].jfCollection.config.jfValueType is "int"
74 | vals = _.map(vals, (val) -> parseInt(val))
75 | return vals
76 | else
77 | return _.map(obj, (v) => @generateJson(v))
78 | else
79 | # if this object has a jfType
80 | if obj.jfField
81 | val = obj.jfField.getValue()
82 | if obj.jfField.config.jfValueType is "int"
83 | val = parseInt(val)
84 | val
85 | # else go deeper through the object.
86 | else
87 | # if this is an object, loop through and generate
88 | # json from all values in the object into new object
89 | if _.isObject(obj)
90 | newObj = {}
91 | _.each(obj, (v,k) =>
92 | newObj[k] = @generateJson(v)
93 | )
94 | return newObj
95 | # if not an object (string, number, etc), just return that
96 | else
97 | return obj
98 |
99 | # Recursive.
100 | parseJsonConfig: (obj) ->
101 |
102 | if _.isArray(obj)
103 |
104 | # if array has single item and it has jfCollection
105 | # convert it to a fieldcollection
106 | if obj.length == 1 && obj[0].jfCollection
107 | obj[0].jfCollection = new jsonform.FieldCollection(obj[0])
108 | @fields.push(obj[0].jfCollection)
109 |
110 | # else parse each object in the array
111 | else
112 | _.each(obj, (v) => @parseJsonConfig(v))
113 |
114 | else
115 |
116 | # if this object has a jfType, create this
117 | # type of field
118 | if obj.jfType
119 | obj.jfField = jsonform.helpers.newField(obj)
120 | @fields.push(obj.jfField)
121 |
122 | # else go deeper through the object.
123 | else
124 | _.each(obj, (v,k) =>
125 | if _.isObject(v)
126 | @parseJsonConfig(v)
127 | )
128 |
129 | # Recursive. This function takes an existing json object (that was generated with this library)
130 | # and loads the data into the fields.
131 | fillFields: (obj, jsonConfig) ->
132 |
133 | # basic sanity check to prevent most configuration errors
134 | if obj is undefined || jsonConfig is undefined
135 | jsonform.helpers.panic("Existing JSON doesnt match JSON config.")
136 |
137 | if _.isArray(obj)
138 |
139 | # if config has single item and it has jfCollection
140 | # create collection items with values.
141 | if jsonConfig.length == 1 && jsonConfig[0].jfCollection
142 | jsonConfig[0].jfCollection.itemsFromValues(obj)
143 | else
144 | _.each(obj, (v, i) =>
145 | @fillFields(obj[i], jsonConfig[i])
146 | )
147 | else
148 | # if this object has a field, set value.
149 | if jsonConfig.jfField
150 | jsonConfig.jfField.setValue(obj)
151 | # else go deeper through the object.
152 | else
153 | # if this is an object, and the same object exist in the json config
154 | # loop through and fill fields inside those object values
155 | if _.isObject(obj)
156 | _.each(obj, (v,k) =>
157 | if jsonConfig[k]
158 | @fillFields(v, jsonConfig[k])
159 | else
160 | console.log "jsonConfig object not present:"
161 | console.log "key: ", k
162 | console.log "value: ", v
163 | )
--------------------------------------------------------------------------------
/src/jsonform.scss:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: Helvetica, Arial, sans-serif;
3 | }
4 |
5 | // general styles for forms
6 |
7 | .jfForm {
8 | margin: 20px 0px;
9 | }
10 |
11 | .jfField {
12 | }
13 |
14 | .jfTitle {
15 | font-size: 16px;
16 | display: block;
17 | margin-top: 10px;
18 | margin-bottom: 10px;
19 | }
20 |
21 | .jfHelper {
22 | display: block;
23 | margin-top: 10px;
24 | margin-bottom: 10px;
25 | font-size: 13px;
26 | color: #838383;
27 | letter-spacing: 0.5px;
28 | font-style: italic;
29 | }
30 |
31 | a.jfBtn, a.jfBtn:link {
32 | text-decoration: none;
33 | color: #282828;
34 | display: inline-block;
35 | background-color: #F7F7F7;
36 | text-align: center;
37 | border-radius: 50%;
38 | border: 1px solid #999;
39 | margin-bottom: 10px;
40 | }
41 |
42 | // General styles for chosen
43 |
44 | .chosen-container {
45 | margin-bottom: 10px;
46 | }
47 |
48 | @import "fields/fieldcollection";
49 | @import "fields/fieldcollectionitem";
50 | @import "fields/boolean";
51 | @import "fields/ajax";
52 | @import "fields/string";
--------------------------------------------------------------------------------
/test/jsonform.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: Helvetica, Arial, sans-serif; }
3 |
4 | .jfForm {
5 | margin: 20px 0px; }
6 |
7 | .jfTitle {
8 | font-size: 16px;
9 | display: block;
10 | margin-top: 10px;
11 | margin-bottom: 10px; }
12 |
13 | .jfHelper {
14 | display: block;
15 | margin-top: 10px;
16 | margin-bottom: 10px;
17 | font-size: 13px;
18 | color: #838383;
19 | letter-spacing: 0.5px;
20 | font-style: italic; }
21 |
22 | a.jfBtn, a.jfBtn:link {
23 | text-decoration: none;
24 | color: #282828;
25 | display: inline-block;
26 | background-color: #F7F7F7;
27 | text-align: center;
28 | border-radius: 50%;
29 | border: 1px solid #999;
30 | margin-bottom: 10px; }
31 |
32 | .chosen-container {
33 | margin-bottom: 10px; }
34 |
35 | .jfCollectionItem {
36 | background-color: #FAFAFA;
37 | padding: 10px;
38 | border: 1px solid #C7C7C7;
39 | border-radius: 5px;
40 | margin-bottom: 5px;
41 | max-width: 400px; }
42 |
43 | .jfAdd {
44 | width: 30px;
45 | height: 30px;
46 | line-height: 30px; }
47 |
48 | .jfAdd[disabled] {
49 | opacity: 0.4;
50 | pointer-events: none; }
51 |
52 | a.jfDel {
53 | font-size: 14px;
54 | text-decoration: none;
55 | padding: 3px 5px;
56 | margin-top: 10px;
57 | margin-left: 5px;
58 | color: #DA7D7D;
59 | display: inline-block;
60 | background-color: #ECC8C8; }
61 |
62 | .jfSort {
63 | font-size: 14px;
64 | margin-top: 10px;
65 | margin-right: 5px;
66 | color: #565555;
67 | display: inline-block;
68 | background-color: #DBDBDB;
69 | text-align: center;
70 | padding: 3px 5px;
71 | vertical-align: top;
72 | border-radius: 3px;
73 | cursor: pointer; }
74 |
75 | body.dragging, body.dragging * {
76 | cursor: move !important; }
77 |
78 | .dragged {
79 | position: absolute;
80 | opacity: 0.5;
81 | z-index: 2000; }
82 |
83 | div.jfCollection .placeholder {
84 | position: relative;
85 | margin: 0;
86 | padding: 0;
87 | border: none; }
88 | div.jfCollection .placeholder:before {
89 | position: absolute;
90 | content: "";
91 | width: 0;
92 | height: 0;
93 | margin-top: -5px;
94 | left: -5px;
95 | top: -4px;
96 | border: 5px solid transparent;
97 | border-left-color: red;
98 | border-right: none; }
99 |
100 | .jfField input[type="text"] {
101 | padding: 6px 10px;
102 | border: 1px solid #B0B0B0;
103 | border-radius: 5px;
104 | background-color: #F7F7F7;
105 | width: 300px;
106 | font-family: Helvetica, Arial, sans-serif;
107 | font-size: 13px;
108 | color: #444;
109 | outline: none;
110 | vertical-align: top; }
111 |
--------------------------------------------------------------------------------
/test/jsonform.js:
--------------------------------------------------------------------------------
1 | window.jsonform = {};
2 |
3 | window.jsonform.helpers = {
4 | panic: function(msg) {
5 | console.error(msg);
6 | return alert(msg);
7 | },
8 | isJsonString: function(str) {
9 | var e;
10 | try {
11 | JSON.parse(str);
12 | } catch (_error) {
13 | e = _error;
14 | return false;
15 | }
16 | return true;
17 | },
18 | changed: function() {
19 | return jQuery.event.trigger('jf:change');
20 | },
21 | newField: function(jfObj) {
22 | var klass;
23 | klass = jsonform[jfObj.jfType];
24 | if (klass) {
25 | return new jsonform[jfObj.jfType](jfObj);
26 | } else {
27 | return console.error("jsonform field doesnt exist: " + jfObj.jfType);
28 | }
29 | }
30 | };
31 |
32 | jsonform.AjaxField = (function() {
33 | AjaxField.preloadValues = function(config, vals, success) {
34 | var query;
35 | vals = _.compact(vals);
36 | if (_.isEmpty(vals)) {
37 | return;
38 | }
39 | query = {};
40 | query[config.jfReloadParam] = vals;
41 | return $.ajax({
42 | url: config.jfUrl,
43 | data: query,
44 | type: 'GET',
45 | success: (function(_this) {
46 | return function(data) {
47 | return success(config.jfParse(data, vals));
48 | };
49 | })(this),
50 | error: function(data) {
51 | return console.log("error baby");
52 | }
53 | });
54 | };
55 |
56 | function AjaxField(config) {
57 | this.config = config;
58 | this.tmpl = JST["fields/ajax"];
59 | this.jel = $('');
60 | this.el = this.jel[0];
61 | }
62 |
63 | AjaxField.prototype.render = function() {
64 | var timeout;
65 | timeout = void 0;
66 | this.jel.html(this.tmpl(this.config));
67 | this.chosen = this.jel.find(".chosen-select").chosen({
68 | width: "300px",
69 | allow_single_deselect: true,
70 | no_results_text: 'Searching for'
71 | });
72 | this.jel.find(".chosen-search input").on('input', (function(_this) {
73 | return function(e) {
74 | clearTimeout(timeout);
75 | return timeout = setTimeout(function() {
76 | return _this.loadAjax(e);
77 | }, 800);
78 | };
79 | })(this));
80 | return this.chosen.change(jsonform.helpers.changed);
81 | };
82 |
83 | AjaxField.prototype.getValue = function() {
84 | return this.jel.find(".chosen-select").val();
85 | };
86 |
87 | AjaxField.prototype.clearValues = function() {
88 | this.jel.find("select option").remove();
89 | this.jel.find("select").append("");
90 | return this.jel.find(".chosen-select").trigger("chosen:updated");
91 | };
92 |
93 | AjaxField.prototype.setValue = function(val) {
94 | if (!_.isObject(val)) {
95 | return this.constructor.preloadValues(this.config, [val], (function(_this) {
96 | return function(newVal) {
97 | return _this.setValue(newVal[0]);
98 | };
99 | })(this));
100 | } else {
101 | this.jel.find(".chosen-select").html('');
102 | this.jel.find(".chosen-select").val(val[0]);
103 | this.jel.find(".chosen-select").trigger("chosen:updated");
104 | return jsonform.helpers.changed();
105 | }
106 | };
107 |
108 | AjaxField.prototype.loadAjax = function(e) {
109 | var chosen, query, searchVal;
110 | chosen = this.jel.find(".chosen-container");
111 | query = {};
112 | searchVal = chosen.find(".chosen-search input").val();
113 | query[this.config.jfSearchParam] = searchVal;
114 | this.clearValues();
115 | return $.ajax({
116 | url: this.config.jfUrl,
117 | data: query,
118 | type: 'GET',
119 | success: (function(_this) {
120 | return function(data) {
121 | var results, select;
122 | results = _this.config.jfParse(data);
123 | if (results.length === 0) {
124 | return chosen.find(".chosen-results").html("No results matched \"" + searchVal + "\"");
125 | } else {
126 | select = _this.jel.find(".chosen-select");
127 | _.each(results, function(result) {
128 | return select.append('');
129 | });
130 | select.trigger("chosen:updated");
131 | return chosen.find(".chosen-search input").val(searchVal);
132 | }
133 | };
134 | })(this),
135 | error: function(data) {
136 | return console.log("error baby");
137 | }
138 | });
139 | };
140 |
141 | return AjaxField;
142 |
143 | })();
144 |
145 | jsonform.BooleanField = (function() {
146 | function BooleanField(config) {
147 | this.config = config;
148 | this.tmpl = JST["fields/boolean"];
149 | this.jel = $('');
150 | this.el = this.jel[0];
151 | }
152 |
153 | BooleanField.prototype.render = function() {
154 | this.jel.html(this.tmpl(this.config));
155 | return this.jel.find(".chosen-select").chosen({
156 | disable_search_threshold: 5,
157 | width: "300px"
158 | }).change(jsonform.helpers.changed);
159 | };
160 |
161 | BooleanField.prototype.getValue = function() {
162 | return this.jel.find(".chosen-select").val() === "true";
163 | };
164 |
165 | BooleanField.prototype.setValue = function(val) {
166 | this.jel.find(".chosen-select").val(val + "");
167 | return this.jel.find(".chosen-select").trigger("chosen:updated");
168 | };
169 |
170 | return BooleanField;
171 |
172 | })();
173 |
174 | jsonform.FieldCollection = (function() {
175 | function FieldCollection(config) {
176 | this.config = config;
177 | this.tmpl = JST["fields/fieldcollection"];
178 | this.jel = $("");
179 | this.el = this.jel[0];
180 | this.items = [];
181 | }
182 |
183 | FieldCollection.prototype.render = function() {
184 | this.jel.html(this.tmpl(this.config));
185 | this.jel.find(".jfAdd").click((function(_this) {
186 | return function(e) {
187 | if ($(_this).is("[disabled]")) {
188 | return;
189 | }
190 | e.preventDefault();
191 | return _this.addItem();
192 | };
193 | })(this));
194 | if ($().sortable) {
195 | return this.jel.find(".jfCollection").sortable({
196 | placeholder: ' ',
197 | itemSelector: '.jfCollectionItem',
198 | handle: 'i.jfSort',
199 | onDrop: (function(_this) {
200 | return function(item, container, _super) {
201 | _super(item, container);
202 | _this.items = _.sortBy(_this.items, function(item) {
203 | return item.jel.index();
204 | });
205 | return jsonform.helpers.changed();
206 | };
207 | })(this)
208 | });
209 | }
210 | };
211 |
212 | FieldCollection.prototype.getValues = function() {
213 | var results;
214 | results = _.map(this.items, function(item) {
215 | return item.getValue();
216 | });
217 | return _.without(results, "", void 0, null);
218 | };
219 |
220 | FieldCollection.prototype.addItem = function(jsonValue) {
221 | var item;
222 | item = new jsonform.FieldCollectionItem(this.config, jsonValue);
223 | this.jel.find(".jfCollection").append(item.el);
224 | item.render();
225 | this.items.push(item);
226 | item.jel.on("delete_clicked", (function(_this) {
227 | return function(e, item) {
228 | item.jel.remove();
229 | _this.items = _.without(_this.items, item);
230 | _this.checkAddState();
231 | return jsonform.helpers.changed();
232 | };
233 | })(this));
234 | this.checkAddState();
235 | if ($().sortable) {
236 | this.jel.find(".jfCollection").sortable("refresh");
237 | }
238 | return jsonform.helpers.changed();
239 | };
240 |
241 | FieldCollection.prototype.itemsFromValues = function(vals) {
242 | return _.each(vals, (function(_this) {
243 | return function(val) {
244 | return _this.addItem(val);
245 | };
246 | })(this));
247 | };
248 |
249 | FieldCollection.prototype.checkAddState = function() {
250 | if (this.config.jfMax) {
251 | if (this.items.length >= this.config.jfMax) {
252 | return this.jel.find(".jfAdd").attr("disabled", "disabled");
253 | } else {
254 | return this.jel.find(".jfAdd").removeAttr("disabled");
255 | }
256 | }
257 | };
258 |
259 | return FieldCollection;
260 |
261 | })();
262 |
263 | jsonform.FieldCollectionItem = (function() {
264 | function FieldCollectionItem(config, jsonValue) {
265 | this.jsonValue = jsonValue;
266 | this.deltmpl = JST["fields/fieldcollection-del"];
267 | this.sorttmpl = JST["fields/fieldcollection-sort"];
268 | this.jel = $('');
269 | this.el = this.jel[0];
270 | this.fields = [];
271 | this.config = {};
272 | jQuery.extend(true, this.config, config);
273 | delete this.config.jfTitle;
274 | delete this.config.jfHelper;
275 | delete this.config.jfCollection;
276 | delete this.config.jfMax;
277 | if (config.jfType) {
278 | this.fields.push(jsonform.helpers.newField(this.config));
279 | } else {
280 | _.each(this.config, (function(_this) {
281 | return function(v, k) {
282 | var field;
283 | if (v.jfType) {
284 | field = jsonform.helpers.newField(v);
285 | v.jfField = field;
286 | return _this.fields.push(field);
287 | }
288 | };
289 | })(this));
290 | }
291 | }
292 |
293 | FieldCollectionItem.prototype.render = function() {
294 | var del;
295 | this.jel.html("");
296 | _.each(this.fields, (function(_this) {
297 | return function(field) {
298 | _this.jel.append(field.el);
299 | return field.render();
300 | };
301 | })(this));
302 | if ($().sortable) {
303 | this.jel.append(this.sorttmpl());
304 | }
305 | del = $(this.deltmpl());
306 | this.jel.append(del);
307 | del.click((function(_this) {
308 | return function(e) {
309 | e.preventDefault();
310 | return _this.jel.trigger("delete_clicked", _this);
311 | };
312 | })(this));
313 | if (!_.isUndefined(this.jsonValue)) {
314 | if (this.config.jfType) {
315 | return this.fields[0].setValue(this.jsonValue);
316 | } else {
317 | return _.each(this.config, (function(_this) {
318 | return function(v, k) {
319 | if (v.jfField && _this.jsonValue[k]) {
320 | return v.jfField.setValue(_this.jsonValue[k]);
321 | }
322 | };
323 | })(this));
324 | }
325 | }
326 | };
327 |
328 | FieldCollectionItem.prototype.getValue = function() {
329 | var values;
330 | if (this.config.jfType) {
331 | return this.fields[0].getValue();
332 | } else {
333 | values = {};
334 | jQuery.extend(true, values, this.config);
335 | _.each(values, (function(_this) {
336 | return function(v, k) {
337 | if (v.jfField) {
338 | return values[k] = v.jfField.getValue();
339 | }
340 | };
341 | })(this));
342 | return values;
343 | }
344 | };
345 |
346 | return FieldCollectionItem;
347 |
348 | })();
349 |
350 | jsonform.SelectField = (function() {
351 | function SelectField(config) {
352 | this.config = config;
353 | this.tmpl = JST["fields/select"];
354 | this.jel = $('');
355 | this.el = this.jel[0];
356 | }
357 |
358 | SelectField.prototype.render = function() {
359 | this.jel.html(this.tmpl(this.config));
360 | return this.jel.find(".chosen-select").chosen({
361 | disable_search_threshold: 5,
362 | width: "300px"
363 | }).change((function(_this) {
364 | return function() {
365 | _this.jel.trigger("jf:changed");
366 | return jsonform.helpers.changed();
367 | };
368 | })(this));
369 | };
370 |
371 | SelectField.prototype.getValue = function() {
372 | return this.jel.find(".chosen-select").val();
373 | };
374 |
375 | SelectField.prototype.setValue = function(val) {
376 | this.jel.find(".chosen-select").val(val + "");
377 | return this.jel.find(".chosen-select").trigger("chosen:updated");
378 | };
379 |
380 | return SelectField;
381 |
382 | })();
383 |
384 | jsonform.SelectAjaxField = (function() {
385 | function SelectAjaxField(config) {
386 | this.config = config;
387 | this.jel = $('');
388 | this.el = this.jel[0];
389 | this.selectField = new jsonform.SelectField({
390 | jfValues: _.map(this.config.jfValues, function(val) {
391 | return val.jfValue;
392 | })
393 | });
394 | this.ajaxField = new jsonform.AjaxField(this.config.jfValues[0]);
395 | }
396 |
397 | SelectAjaxField.prototype.render = function() {
398 | this.jel.html("");
399 | this.jel.append(this.selectField.el);
400 | this.jel.append(this.ajaxField.el);
401 | this.selectField.render();
402 | this.ajaxField.render();
403 | return this.selectField.jel.on("jf:changed", (function(_this) {
404 | return function() {
405 | return _this.selectSwitched();
406 | };
407 | })(this));
408 | };
409 |
410 | SelectAjaxField.prototype.getValue = function() {
411 | var val;
412 | val = {};
413 | val[this.config.jfSelectKey] = this.selectField.getValue();
414 | val[this.config.jfAjaxKey] = this.ajaxField.getValue();
415 | return val;
416 | };
417 |
418 | SelectAjaxField.prototype.setValue = function(val) {
419 | var ajaxConfig;
420 | this.selectField.setValue(val[this.config.jfSelectKey]);
421 | ajaxConfig = this.getConfigBySelectKey(this.selectField.getValue());
422 | return jsonform.AjaxField.preloadValues(ajaxConfig, [val[this.config.jfAjaxKey]], (function(_this) {
423 | return function(data) {
424 | _this.ajaxField.config = ajaxConfig;
425 | return _this.ajaxField.setValue(data[0]);
426 | };
427 | })(this));
428 | };
429 |
430 | SelectAjaxField.prototype.selectSwitched = function() {
431 | var ajaxConfig;
432 | ajaxConfig = this.getConfigBySelectKey(this.selectField.getValue());
433 | this.ajaxField.config = ajaxConfig;
434 | return this.ajaxField.setValue(["", ""]);
435 | };
436 |
437 | SelectAjaxField.prototype.getConfigBySelectKey = function(key) {
438 | return _.find(this.config.jfValues, function(conf) {
439 | return conf.jfValue[0] === key;
440 | });
441 | };
442 |
443 | return SelectAjaxField;
444 |
445 | })();
446 |
447 | jsonform.StringField = (function() {
448 | function StringField(config) {
449 | this.config = config;
450 | this.tmpl = JST["fields/string"];
451 | this.jel = $('');
452 | this.el = this.jel[0];
453 | }
454 |
455 | StringField.prototype.render = function() {
456 | this.jel.html(this.tmpl(this.config));
457 | return this.jel.find("input").change(jsonform.helpers.changed);
458 | };
459 |
460 | StringField.prototype.getValue = function() {
461 | return this.jel.find("input").val();
462 | };
463 |
464 | StringField.prototype.setValue = function(val) {
465 | return this.jel.find("input").val(val);
466 | };
467 |
468 | return StringField;
469 |
470 | })();
471 |
472 | jsonform.Form = (function() {
473 | function Form(txtArea, jsonConfig) {
474 | var txtval;
475 | this.jel = $('');
476 | this.jtxt = $(txtArea);
477 | this.jtxt.hide();
478 | this.fields = [];
479 | this.jsonConfig = jsonConfig;
480 | this.parseJsonConfig(this.jsonConfig);
481 | _.each(this.fields, (function(_this) {
482 | return function(field) {
483 | _this.jel.append(field.el);
484 | return field.render();
485 | };
486 | })(this));
487 | $(document).bind('jf:change', (function(_this) {
488 | return function() {
489 | var json;
490 | json = _this.generateJson(_this.jsonConfig);
491 | return _this.jtxt.val(JSON.stringify(json, null, 2));
492 | };
493 | })(this));
494 | this.jtxt.after(this.jel);
495 | txtval = this.jtxt.val();
496 | if (!!txtval) {
497 | if (jsonform.helpers.isJsonString(txtval)) {
498 | this.fillFields(JSON.parse(txtval), this.jsonConfig);
499 | } else {
500 | jsonform.helpers.panic("Textarea has invalid JSON. jsonform will not work");
501 | }
502 | }
503 | }
504 |
505 | Form.prototype.generateJson = function(obj) {
506 | var newObj, val, vals;
507 | if (_.isArray(obj)) {
508 | if (obj.length === 1 && obj[0].jfCollection) {
509 | vals = obj[0].jfCollection.getValues();
510 | if (obj[0].jfCollection.config.jfValueType === "int") {
511 | vals = _.map(vals, function(val) {
512 | return parseInt(val);
513 | });
514 | }
515 | return vals;
516 | } else {
517 | return _.map(obj, (function(_this) {
518 | return function(v) {
519 | return _this.generateJson(v);
520 | };
521 | })(this));
522 | }
523 | } else {
524 | if (obj.jfField) {
525 | val = obj.jfField.getValue();
526 | if (obj.jfField.config.jfValueType === "int") {
527 | val = parseInt(val);
528 | }
529 | return val;
530 | } else {
531 | if (_.isObject(obj)) {
532 | newObj = {};
533 | _.each(obj, (function(_this) {
534 | return function(v, k) {
535 | return newObj[k] = _this.generateJson(v);
536 | };
537 | })(this));
538 | return newObj;
539 | } else {
540 | return obj;
541 | }
542 | }
543 | }
544 | };
545 |
546 | Form.prototype.parseJsonConfig = function(obj) {
547 | if (_.isArray(obj)) {
548 | if (obj.length === 1 && obj[0].jfCollection) {
549 | obj[0].jfCollection = new jsonform.FieldCollection(obj[0]);
550 | return this.fields.push(obj[0].jfCollection);
551 | } else {
552 | return _.each(obj, (function(_this) {
553 | return function(v) {
554 | return _this.parseJsonConfig(v);
555 | };
556 | })(this));
557 | }
558 | } else {
559 | if (obj.jfType) {
560 | obj.jfField = jsonform.helpers.newField(obj);
561 | return this.fields.push(obj.jfField);
562 | } else {
563 | return _.each(obj, (function(_this) {
564 | return function(v, k) {
565 | if (_.isObject(v)) {
566 | return _this.parseJsonConfig(v);
567 | }
568 | };
569 | })(this));
570 | }
571 | }
572 | };
573 |
574 | Form.prototype.fillFields = function(obj, jsonConfig) {
575 | if (obj === void 0 || jsonConfig === void 0) {
576 | jsonform.helpers.panic("Existing JSON doesnt match JSON config.");
577 | }
578 | if (_.isArray(obj)) {
579 | if (jsonConfig.length === 1 && jsonConfig[0].jfCollection) {
580 | return jsonConfig[0].jfCollection.itemsFromValues(obj);
581 | } else {
582 | return _.each(obj, (function(_this) {
583 | return function(v, i) {
584 | return _this.fillFields(obj[i], jsonConfig[i]);
585 | };
586 | })(this));
587 | }
588 | } else {
589 | if (jsonConfig.jfField) {
590 | return jsonConfig.jfField.setValue(obj);
591 | } else {
592 | if (_.isObject(obj)) {
593 | return _.each(obj, (function(_this) {
594 | return function(v, k) {
595 | if (jsonConfig[k]) {
596 | return _this.fillFields(v, jsonConfig[k]);
597 | } else {
598 | console.log("jsonConfig object not present:");
599 | console.log("key: ", k);
600 | return console.log("value: ", v);
601 | }
602 | };
603 | })(this));
604 | }
605 | }
606 | }
607 | };
608 |
609 | return Form;
610 |
611 | })();
612 |
613 | this.JST = {"fields/ajax": function(obj) {
614 | obj || (obj = {});
615 | var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
616 | function print() { __p += __j.call(arguments, '') }
617 | with (obj) {
618 |
619 | if(typeof(jfTitle)!== 'undefined') { ;
620 | __p += '' +
621 | ((__t = ( jfTitle )) == null ? '' : __t) +
622 | '';
623 | } ;
624 | __p += '\n';
625 | if(typeof(jfHelper)!== 'undefined') { ;
626 | __p += '' +
627 | ((__t = ( jfHelper )) == null ? '' : __t) +
628 | '';
629 | } ;
630 | __p += '\n\n';
631 |
632 | }
633 | return __p
634 | },
635 | "fields/boolean": function(obj) {
636 | obj || (obj = {});
637 | var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
638 | function print() { __p += __j.call(arguments, '') }
639 | with (obj) {
640 |
641 | if(typeof(jfTitle)!== 'undefined') { ;
642 | __p += '' +
643 | ((__t = ( jfTitle )) == null ? '' : __t) +
644 | '';
645 | } ;
646 | __p += '\n';
647 | if(typeof(jfHelper)!== 'undefined') { ;
648 | __p += '' +
649 | ((__t = ( jfHelper )) == null ? '' : __t) +
650 | '';
651 | } ;
652 | __p += '\n\n';
653 |
654 | }
655 | return __p
656 | },
657 | "fields/fieldcollection-del": function(obj) {
658 | obj || (obj = {});
659 | var __t, __p = '', __e = _.escape;
660 | with (obj) {
661 | __p += 'Delete';
662 |
663 | }
664 | return __p
665 | },
666 | "fields/fieldcollection-sort": function(obj) {
667 | obj || (obj = {});
668 | var __t, __p = '', __e = _.escape;
669 | with (obj) {
670 | __p += '↕';
671 |
672 | }
673 | return __p
674 | },
675 | "fields/fieldcollection": function(obj) {
676 | obj || (obj = {});
677 | var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
678 | function print() { __p += __j.call(arguments, '') }
679 | with (obj) {
680 |
681 | if(typeof(jfTitle)!== 'undefined') { ;
682 | __p += '' +
683 | ((__t = ( jfTitle )) == null ? '' : __t) +
684 | '';
685 | } ;
686 | __p += '\n';
687 | if(typeof(jfHelper)!== 'undefined') { ;
688 | __p += '' +
689 | ((__t = ( jfHelper )) == null ? '' : __t) +
690 | '';
691 | } ;
692 | __p += '\n\n+\n\n';
693 |
694 | }
695 | return __p
696 | },
697 | "fields/select": function(obj) {
698 | obj || (obj = {});
699 | var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
700 | function print() { __p += __j.call(arguments, '') }
701 | with (obj) {
702 |
703 | if(typeof(jfTitle)!== 'undefined') { ;
704 | __p += '' +
705 | ((__t = ( jfTitle )) == null ? '' : __t) +
706 | '';
707 | } ;
708 | __p += '\n';
709 | if(typeof(jfHelper)!== 'undefined') { ;
710 | __p += '' +
711 | ((__t = ( jfHelper )) == null ? '' : __t) +
712 | '';
713 | } ;
714 | __p += '\n\n';
723 |
724 | }
725 | return __p
726 | },
727 | "fields/selectajax": function(obj) {
728 | obj || (obj = {});
729 | var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
730 | function print() { __p += __j.call(arguments, '') }
731 | with (obj) {
732 |
733 | if(typeof(jfTitle)!== 'undefined') { ;
734 | __p += '' +
735 | ((__t = ( jfTitle )) == null ? '' : __t) +
736 | '';
737 | } ;
738 | __p += '\n';
739 | if(typeof(jfHelper)!== 'undefined') { ;
740 | __p += '' +
741 | ((__t = ( jfHelper )) == null ? '' : __t) +
742 | '';
743 | } ;
744 | __p += '\n\n';
753 |
754 | }
755 | return __p
756 | },
757 | "fields/string": function(obj) {
758 | obj || (obj = {});
759 | var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
760 | function print() { __p += __j.call(arguments, '') }
761 | with (obj) {
762 |
763 | if(typeof(jfTitle)!== 'undefined') { ;
764 | __p += '' +
765 | ((__t = ( jfTitle )) == null ? '' : __t) +
766 | '';
767 | } ;
768 | __p += '\n';
769 | if(typeof(jfHelper)!== 'undefined') { ;
770 | __p += '' +
771 | ((__t = ( jfHelper )) == null ? '' : __t) +
772 | '';
773 | } ;
774 | __p += '\n\n';
775 |
776 | }
777 | return __p
778 | }};
--------------------------------------------------------------------------------