xref: /plugin/struct/script.js (revision 8824339dfb9d3e3672bb1214601296a5f483eeb4)
1jQuery(function () {
2    'use strict';
3    /* globals JSINFO */
4
5    /** counter for copied multi templates */
6    var copycount = 0;
7
8    /**
9     * Simplyfies AJAX requests for types
10     *
11     * @param {string} column A configured column in the form schema.name
12     * @param {function} fn Callback on success
13     * @param {object} data Additional data to pass
14     */
15    function struct_ajax(column, fn, data) {
16        if (!data) data = {};
17
18        data['call'] = 'plugin_struct';
19        data['column'] = column;
20        data['id'] = JSINFO.id;
21        data['ns'] = JSINFO.namespace;
22
23        jQuery.post(DOKU_BASE + 'lib/exe/ajax.php', data, fn, 'json')
24            .fail(function (result) {
25                if(result.responseJSON) {
26                    if (result.responseJSON.stacktrace) {
27                        console.error(result.responseJSON.error + "\n" + result.responseJSON.stacktrace);
28                    }
29                    alert(result.responseJSON.error);
30                } else {
31                    // some fatal error occured, get a text only version of the response
32                    alert(jQuery(result.responseText).text());
33                }
34            });
35    }
36
37    /**
38     * @param {string} val
39     * @return {Array}
40     */
41    function split(val) {
42        return val.split(/,\s*/);
43    }
44
45    /**
46     * @param {string} term
47     * @returns {string}
48     */
49    function extractLast(term) {
50        return split(term).pop();
51    }
52
53
54    /**
55     * Replace numbered placeholders in a string with the given arguments
56     *
57     * Example formatString('{0} is dead, but {1} is alive! {0} {2}', 'ASP', 'ASP.NET');
58     *
59     * adapted from http://stackoverflow.com/a/4673436/3293343
60     * @param format
61     * @returns {*}
62     */
63    function formatString(format) {
64        var args = Array.prototype.slice.call(arguments, 1);
65        return format.replace(/{(\d+)}/g, function(match, number) {
66            return typeof args[number] != 'undefined'
67                ? args[number]
68                : match
69            ;
70        });
71    }
72
73
74    /**
75     * hints
76     */
77    jQuery('.struct .hashint').tooltip();
78
79    /**
80     * Attach datepicker to date types
81     */
82    jQuery('input.struct_date').datepicker({
83        dateFormat: 'yy-mm-dd'
84    });
85
86    /**
87     * Attach image dialog to image types
88     */
89    jQuery('button.struct_media').click(function () {
90        var input_id = jQuery(this).siblings('input').attr('id');
91        window.open(
92            DOKU_BASE + 'lib/exe/mediamanager.php' +
93            '?ns=' + encodeURIComponent(JSINFO['namespace']) +
94            '&edid=' + encodeURIComponent(input_id) +
95            '&onselect=insertStructMedia',
96            'mediaselect',
97            'width=750,height=500,left=20,top=20,scrollbars=yes,resizable=yes'); //
98    });
99
100    /**
101     * Custom onSelect handler for struct img button
102     */
103    window.insertStructMedia = function (edid, mediaid, opts, align) {
104        jQuery('#' + edid).val(mediaid).change();
105    };
106
107    /**
108     * Autocomplete for single type
109     */
110    jQuery('input.struct_autocomplete').autocomplete({
111        ismulti: false,
112        source: function (request, cb) {
113            var name = jQuery(this.element[0]).closest('label').data('column');
114            var term = request.term;
115            if (this.options.ismulti) {
116                term = extractLast(term);
117            }
118            struct_ajax(name, cb, {search: term});
119        }
120    });
121
122    /**
123     * Autocomplete for multi type
124     */
125    jQuery('.multiwrap input.struct_autocomplete').autocomplete('option', {
126        ismulti: true,
127        focus: function () {
128            // prevent value inserted on focus
129            return false;
130        },
131        select: function (event, ui) {
132            var terms = split(this.value);
133            // remove the current input
134            terms.pop();
135            // add the selected item
136            terms.push(ui.item.value);
137            // add placeholder to get the comma-and-space at the end
138            terms.push("");
139            this.value = terms.join(", ");
140            return false;
141        }
142    });
143
144    /**
145     * Handle tabs in the Schema Editor
146     */
147    jQuery('#plugin__struct_json, #plugin__struct_delete').hide();
148    jQuery('#plugin__struct_tabs').find('a').click(function (e) {
149        e.preventDefault();
150        e.stopPropagation();
151        var $me = jQuery(this);
152        if($me.parent().hasClass('active')) return; // nothing to do
153
154        $me.parent().parent().find('li').removeClass('active');
155        $me.parent().addClass('active');
156        jQuery('#plugin__struct_json, #plugin__struct_editor, #plugin__struct_delete').hide();
157        jQuery($me.attr('href')).show();
158    });
159
160
161    /**
162     * Toggle the disabled class in the schema editor
163     */
164    jQuery('#plugin__struct_editor').find('td.isenabled input').change(function () {
165        var $checkbox = jQuery(this);
166        $checkbox.parents('tr').toggleClass('disabled', !$checkbox.prop('checked'));
167    });
168
169    var $dokuform = jQuery('#dw__editform');
170
171    /**
172     * Duplicate the elements in .newtemplate whenever any input in it changes
173     */
174    $dokuform.find('.struct .newtemplate').each(function () {
175        var $tplwrapper = jQuery(this);
176        var $tpl = $tplwrapper.children().clone(true, true);
177
178        $tplwrapper.on('change', 'input,textarea,select', function () {
179            if (jQuery(this).val() == '') return;
180
181            // prepare a new template and make sure all the IDs in it are unique
182            var $copy = $tpl.clone(true, true);
183            copycount++;
184            $copy.find('*[id]').each(function () {
185                this.id = this.id + '_' + copycount;
186            });
187
188            // append the template
189            $tplwrapper.append($copy);
190        });
191    });
192
193    /**
194     * Toggle fieldsets in edit form and remeber in cookie
195     */
196    $dokuform.find('.struct fieldset legend').each(function () {
197        var $legend = jQuery(this);
198        var $fset = $legend.parent();
199
200        // reinit saved state from cookie
201        if (DokuCookie.getValue($fset.data('schema'))) {
202            $fset.toggleClass('closed');
203        }
204
205        // attach click handler
206
207        $legend.click(function () {
208            $fset.toggleClass('closed');
209            // remember setting in preference cookie
210            if ($fset.hasClass('closed')) {
211                DokuCookie.setValue($fset.data('schema'), 1);
212            } else {
213                DokuCookie.setValue($fset.data('schema'), '');
214            }
215        });
216    });
217
218    jQuery('a.deleteSchema').click(function (event) {
219        var schema = jQuery(this).closest('tr').find('td:nth-child(2)').text();
220        var page = jQuery(this).closest('tr').find('td:nth-child(1)').text();
221        if(!window.confirm(formatString(LANG.plugins.struct['confirmAssignmentsDelete'], schema, page))) {
222            event.preventDefault();
223            event.stopPropagation();
224        }
225    })
226
227});
228