xref: /plugin/struct/script/AggregationEditor.js (revision 9d26e36ded7cf6066b458141963572b35338c6f0)
1/**
2 * Aggregation table editor
3 */
4const AggregationEditor = function (idx, table) {
5    const $table = jQuery(table);
6    let $form = null;
7    let formdata;
8
9    const schema = $table.parents('.structaggregation').data('schema');
10    if (!schema) return;
11
12    const searchconf = JSON.parse($table.parents('.structaggregation').attr('data-searchconf'));
13
14    /**
15     * Adds delete row buttons to each row
16     */
17    function addDeleteRowButtons() {
18        const disableDeleteSerial = JSINFO.plugins.struct.disableDeleteSerial;
19
20        $table.find('tr').each(function () {
21            const $me = jQuery(this);
22
23            // already added here?
24            if ($me.find('th.action, td.action').length) {
25                return;
26            }
27
28            const rid = $me.data('rid');
29            const pid = $me.data('pid');
30            let isDisabled = '';
31
32            // empty header cells
33            if (!rid) {
34                insertActionCell($me, '<th class="action">' + LANG.plugins.struct.actions + '</th>');
35                return;
36            }
37
38            // delete buttons for rows
39            const $td = jQuery('<td class="action"></td>');
40            if (rid === '') return;  // skip button addition for page data
41            // disable button for serial data if so configured
42            if (rid && pid && disableDeleteSerial) {
43                isDisabled = ' disabled';
44            }
45
46            const $btn = jQuery('<button' + isDisabled + '><i class="ui-icon ui-icon-trash"></i></button>')
47                .addClass('delete')
48                .attr('title', LANG.plugins.struct.lookup_delete)
49                .click(function (e) {
50                    e.preventDefault();
51                    if (!window.confirm(LANG.del_confirm)) return;
52
53                    jQuery.post(
54                        DOKU_BASE + 'lib/exe/ajax.php',
55                        {
56                            call: 'plugin_struct_aggregationeditor_delete',
57                            schema: schema,
58                            rid: rid,
59                            sectok: $me.parents('.structaggregationeditor').find('.struct_entry_form input[name=sectok]').val()
60                        }
61                    )
62                        .done(function () {
63                            $me.remove();
64                        })
65                        .fail(function (xhr) {
66                            alert(xhr.responseText)
67                        })
68                });
69
70            $td.append($btn);
71            insertActionCell($me, $td);
72        });
73    }
74
75    /**
76     * Insert the action cell at the right position, depending on the actcol setting
77     *
78     * @param {jQuery<HTMLTableRowElement>} $row
79     * @param {jQuery<HTMLTableCellElement>} $cell
80     */
81    function insertActionCell($row, $cell) {
82        const $children = $row.children();
83        let insertAt = searchconf.actcol;
84        if ( insertAt < 0 ) insertAt = $children.length + 1 + insertAt;
85
86        if(insertAt >= $children.length) {
87            $row.append($cell);
88        } else if (insertAt < 0) {
89            $row.prepend($cell);
90        } else {
91            $children.eq(insertAt).before($cell);
92        }
93    }
94
95    /**
96     * Initializes the form for the editor and attaches handlers
97     *
98     * @param {string} data The HTML for the form
99     */
100    function addForm(data) {
101        if ($form) $form.remove();
102        var $agg = $table.parents('.structaggregation');
103        const searchconf = JSON.parse($agg.attr('data-searchconf'));
104        const withpid = searchconf['withpid'];
105        const isPageEditor = JSINFO.plugins.struct.isPageEditor;
106
107        if (withpid && !isPageEditor) return;
108
109        $form = jQuery('<form></form>');
110        $form.html(data);
111        jQuery('<input>').attr({
112            type: 'hidden',
113            name: 'searchconf',
114            value: $agg.attr('data-searchconf')
115        }).appendTo($form); // add the search config to the form
116
117        // if page id needs to be passed to backend, add pid
118        if (withpid) {
119            jQuery('<input>').attr({
120                type: 'hidden',
121                name: 'pid',
122                value: JSINFO.id
123            }).appendTo($form); // add the page id to the form
124        }
125        $agg.append($form);
126        EntryEditor($form);
127
128        var $errors = $form.find('div.err').hide();
129
130        $form.submit(function (e) {
131            e.preventDefault();
132            $errors.hide();
133
134            jQuery.post(
135                DOKU_BASE + 'lib/exe/ajax.php',
136                $form.serialize()
137            )
138                .done(function (data) {
139                    var $tbody = $table.find('tbody');
140                    if (!$tbody.length) {
141                        $tbody = jQuery('<tbody>').appendTo($table);
142                    }
143                    $tbody.append(data);
144                    addDeleteRowButtons(); // add the delete button to the new row
145                    addForm(formdata); // reset the whole form
146                })
147                .fail(function (xhr) {
148                    $errors.text(xhr.responseText).show();
149                })
150        });
151    }
152
153    /**
154     * Main
155     *
156     * Initializes the editor if the AJAX backend returns an editor,
157     * otherwise some (ACL) check did not check out and no editing
158     * capabilites are added.
159     */
160    jQuery.post(
161        DOKU_BASE + 'lib/exe/ajax.php',
162        {
163            call: 'plugin_struct_aggregationeditor_new',
164            searchconf: searchconf
165        },
166        function (data) {
167            if (!data) return;
168            formdata = data;
169            addDeleteRowButtons();
170            addForm(data);
171        }
172    );
173
174
175};
176