-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
/
has_many.es6
89 lines (78 loc) · 3.54 KB
/
has_many.es6
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
$(function() {
// Provides a before-removal hook:
// $ ->
// # This is a good place to tear down JS plugins to prevent memory leaks.
// $(document).on 'has_many_remove:before', '.has_many_container', (e, fieldset, container)->
// fieldset.find('.select2').select2 'destroy'
//
// # If you need to do anything after removing the items you can use the
// has_many_remove:after hook
// $(document).on 'has_many_remove:after', '.has_many_container', (e, fieldset, container)->
// list_item_count = container.find('.has_many_fields').length
// alert("There are now #{list_item_count} items in the list")
//
$(document).on('click', 'a.button.has_many_remove', function(event){
event.preventDefault();
const parent = $(this).closest('.has_many_container');
const to_remove = $(this).closest('fieldset');
recompute_positions(parent);
parent.trigger('has_many_remove:before', [to_remove, parent]);
to_remove.remove();
return parent.trigger('has_many_remove:after', [to_remove, parent]);
});
// Provides before and after creation hooks:
// $ ->
// # The before hook allows you to prevent the creation of new records.
// $(document).on 'has_many_add:before', '.has_many_container', (e, container)->
// if $(@).children('fieldset').length >= 3
// alert "you've reached the maximum number of items"
// e.preventDefault()
//
// # The after hook is a good place to initialize JS plugins and the like.
// $(document).on 'has_many_add:after', '.has_many_container', (e, fieldset, container)->
// fieldset.find('select').chosen()
//
$(document).on('click', 'a.button.has_many_add', function(event){
let before_add;
event.preventDefault();
const parent = $(this).closest('.has_many_container');
parent.trigger((before_add = $.Event('has_many_add:before')), [parent]);
if (!before_add.isDefaultPrevented()) {
let index = parent.data('has_many_index') || (parent.children('fieldset').length - 1);
parent.data({has_many_index: ++index});
const regex = new RegExp($(this).data('placeholder'), 'g');
const html = $(this).data('html').replace(regex, index);
const fieldset = $(html).insertBefore(this);
recompute_positions(parent);
return parent.trigger('has_many_add:after', [fieldset, parent]);
}
});
$(document).on('change', '.has_many_container[data-sortable] :input[name$="[_destroy]"]', function() {
recompute_positions($(this).closest('.has_many'));
});
init_sortable();
$(document).on('has_many_add:after', '.has_many_container', init_sortable);
});
var init_sortable = function() {
const elems = $('.has_many_container[data-sortable]:not(.ui-sortable)');
elems.sortable({
items: '> fieldset',
handle: '> ol > .handle',
stop: recompute_positions
});
elems.each(recompute_positions);
};
var recompute_positions = function(parent){
parent = parent instanceof jQuery ? parent : $(this);
const input_name = parent.data('sortable');
let position = parseInt(parent.data('sortable-start') || 0, 10);
parent.children('fieldset').each(function() {
// We ignore nested inputs, so when defining your has_many, be sure to keep
// your sortable input at the root of the has_many block.
const destroy_input = $(this).find("> ol > .input > :input[name$='[_destroy]']");
const sortable_input = $(this).find(`> ol > .input > :input[name$='[${input_name}]']`);
if (sortable_input.length) {
sortable_input.val(destroy_input.is(':checked') ? '' : position++);
}
});
};