/
custom-fields.js
105 lines (93 loc) · 3.33 KB
/
custom-fields.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/* Module for working with multiple custom field inputs. This will create
* a new field when the user enters text into the last field key. It also
* gives a visual indicator when fields are removed by disabling them.
*
* See the snippets/custom_form_fields.html for an example.
*/
this.ckan.module('custom-fields', function (jQuery, _) {
return {
options: {
/* The selector used for each custom field wrapper */
fieldSelector: '.control-custom'
},
/* Initializes the module and attaches custom event listeners. This
* is called internally by ckan.module.initialize().
*
* Returns nothing.
*/
initialize: function () {
if (!jQuery('html').hasClass('ie7')) {
jQuery.proxyAll(this, /_on/);
var delegated = this.options.fieldSelector + ':last input:first';
this.el.on('change', delegated, this._onChange);
this.el.on('change', ':checkbox', this._onRemove);
// Style the remove checkbox like a button.
this.$('.checkbox').addClass("btn btn-danger icon-remove");
}
},
/* Creates a new field and appends it to the list. This currently works by
* cloning and erasing an existing input rather than using a template. In
* future using a template might be more appropriate.
*
* element - Another custom field element to wrap.
*
* Returns nothing.
*/
newField: function (element) {
this.el.append(this.cloneField(element));
},
/* Clones the provided element, wipes it's content and increments it's
* for, id and name fields (if possible).
*
* current - A custom field to clone.
*
* Returns a newly created custom field element.
*/
cloneField: function (current) {
return this.resetField(jQuery(current).clone());
},
/* Wipes the contents of the field provided and increments it's name, id
* and for attributes.
*
* field - A custom field to wipe.
*
* Returns the wiped element.
*/
resetField: function (field) {
function increment(index, string) {
return (string || '').replace(/\d+/, function (int) { return 1 + parseInt(int, 10); });
}
var input = field.find(':input');
input.val('').attr('id', increment).attr('name', increment);
var label = field.find('label');
label.text(increment).attr('for', increment);
return field;
},
/* Disables the provided field and input elements. Can be re-enabled by
* passing false as the second argument.
*
* field - The field to disable.
* disable - If false re-enables the element.
*
* Returns nothing.
*/
disableField: function (field, disable) {
field.toggleClass('disabled', disable !== false);
field.find(':input:not(:checkbox)').prop('disabled', disable !== false);
},
/* Event handler that fires when the last key in the custom field block
* changes.
*/
_onChange: function (event) {
if (event.target.value !== '') {
var parent = jQuery(event.target).parents('.control-custom');
this.newField(parent);
}
},
/* Event handler called when the remove checkbox is checked */
_onRemove: function (event) {
var parent = jQuery(event.target).parents('.control-custom');
this.disableField(parent, event.target.checked);
}
};
});