summaryrefslogtreecommitdiffstats
path: root/public/js/icinga/behavior/form.js
blob: ca9db3b70d452b2ccce20812ecf70db66c3b66c3 (plain)
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
/*! Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */

/**
 * Controls behavior of form elements, depending reload and
 */
(function(Icinga, $) {

    "use strict";

    Icinga.Behaviors = Icinga.Behaviors || {};

    var Form = function (icinga) {
        Icinga.EventListener.call(this, icinga);
        this.on('rendered', '.container', this.onRendered, this);

        // store the modification state of all input fields
        this.inputs = new WeakMap();
    };
    Form.prototype = new Icinga.EventListener();

    /**
     * @param event
     */
    Form.prototype.onRendered = function (event) {
        var _this = event.data.self;
        var container = event.target;

        container.querySelectorAll('form input').forEach(function (input) {
            if (! _this.inputs.has(input) && input.type !== 'hidden') {
                _this.inputs.set(input, input.value);
                _this.icinga.logger.debug('registering "' + input.value + '" as original input value');
            }
        });
    };

    /**
     * Mutates the HTML before it is placed in the DOM after a reload
     *
     * @param content       {String}    The content to be rendered
     * @param $container    {jQuery}    The target container where the html will be rendered in
     * @param action        {String}    The action-url that caused the reload
     * @param autorefresh   {Boolean}   Whether the rendering is due to an autoRefresh
     * @param autoSubmit    {Boolean}   Whether the rendering is due to an autoSubmit
     *
     * @returns {string|NULL}           The content to be rendered, or NULL, when nothing should be changed
     */
    Form.prototype.renderHook = function(content, $container, action, autorefresh, autoSubmit) {
        if ($container.attr('id') === 'menu') {
            var $search = $container.find('#search');
            if ($search[0] === document.activeElement) {
                return null;
            }
            if ($search.length) {
                var $content = $('<div></div>').append(content);
                $content.find('#search').attr('value', $search.val()).addClass('active');
                return $content.html();
            }
            return content;
        }

        if (! autorefresh || autoSubmit) {
            return content;
        }

        var _this = this;
        var changed = false;
        $container[0].querySelectorAll('form input').forEach(function (input) {
            if (_this.inputs.has(input) && _this.inputs.get(input) !== input.value) {
                changed = true;
                _this.icinga.logger.debug(
                    '"' + _this.inputs.get(input) + '" was changed ("' + input.value + '") and aborts reload...'
                );
            }
        });
        if (changed) {
            return null;
        }

        var origFocus = document.activeElement;
        var containerId = $container.attr('id');
        if ($container.has(origFocus).length
            && $(origFocus).length
            && ! $(origFocus).hasClass('autofocus')
            && $(origFocus).closest('form').length
            && $(origFocus).not(':input[type=button], :input[type=submit], :input[type=reset]').length
        ) {
            this.icinga.logger.debug('Not changing content for ' + containerId + ' form has focus');
            return null;
        }

        return content;
    };

    Icinga.Behaviors.Form = Form;

}) (Icinga, jQuery);