subform.js ➔ init_subform   F
last analyzed

Complexity

Conditions 20

Size

Total Lines 83
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 53
dl 0
loc 83
rs 0
c 0
b 0
f 0
cc 20

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like subform.js ➔ init_subform often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
function init_subform(id, sortable, allow_add, allow_delete) {
2
    var container = $('#' + id),
3
        delete_button = $('<a class="button remove-item">-</a>'),
4
        add_button = $('<a class="button add-item">+</a>')
5
            .on('click', function(e) {
6
                e.preventDefault();
7
                add_form();
8
            }),
9
        index = 0;
10
    
11
    function add_form() {
12
        var prototype = container.data('prototype'),
13
            index = container.data('index'),
14
            new_form = $(prototype.replace(/__name__/g, 'new-' + index))
15
                .insertBefore(add_button);
16
        if (allow_delete === true) {
17
            new_form.prepend(delete_button.clone());
18
        }
19
        container.data('index', index + 1);
20
        update_add_button();
21
        
22
        if (sortable === true) {
23
            container.sortable('refresh');
24
            container.trigger('sortupdate');
25
        }
26
        new_form.trigger('subformadded');
27
    }
28
29
    function update_add_button() {
30
        if (allow_add) {
31
            if (container.data('max-count') > 0) {
32
                if (container.data('max-count') > container.children(':not(.add_item)').length) {
33
                    if (container.find('> .add-item').length === 0) {
34
                        container.append(add_button);
35
                    }
36
                } else  {
37
                    add_button.detach();
38
                }
39
            } else if (container.find('> .add-item').length === 0) {
40
                container.append(add_button);
41
            }
42
        }
43
    }
44
    
45
    container.on('click', 'a.remove-item', function(e) {
46
        e.preventDefault();
47
        $(this).parent().remove();
48
        update_add_button();
49
    });
50
51
    container.children().each(function() {
52
        if (allow_delete === true) {
53
            $(this).prepend(delete_button.clone());
54
        }
55
        index++;
56
    });
57
58
    container.data('index', index);
59
    update_add_button();
60
    
61
    if (sortable === true) {
62
        container
63
            .sortable({items: '> :not(a.add-item)'})
64
            .on('sortupdate', function() {
65
                $($(this).find('> .ui-sortable-handle').get().reverse()).each(function(index, element) {
66
                    let id = element.id
67
                    if (!id) {
68
                        id = $('> .input > *:first-child', element).attr('id');
69
                    }
70
                    $('#' + id + '_score').val(index);
71
                });
72
            });
73
    }
74
75
    add_button.on('click', function() {
76
        // If there is exactly one file selector, we're probably in some sort of attachment list,
77
        // so let's assume the user wants to add a file
78
        // (at some point this should probably be made configurable)
79
        if ($(this).prev().find('input[type="file"]').length === 1) {
80
            $(this).prev().find('input[type="file"]').click();
81
        }
82
    });
83
}
84