Jump to content

User:L235/formFiller.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by L235 (talk | contribs) at 20:32, 23 May 2025 (init). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/*  Configurable BlankPage Form User‑script
    -------------------------------------------------
    This script reads its behaviour from a JSON page (for now
    [[User:L235/form-config.json]]).  The JSON controls:
      • which page the form appears on (formPage)
      • the questions to render (questions[])
      • the page to append wikitext to (targetPage)
      • which template is inserted and whether to subst (template)

    Example JSON:
    {
      "formPage": "Special:BlankPage/form",
      "targetPage": "User:L235/sandbox2",
      "template": {
        "name": "User:L235/TestTemplate",
        "subst": true
      },
      "questions": [
        { "label": "Question A:", "name": "q1", "type": "text",      "required": false, "templateParam": "1" },
        { "label": "Question B:", "name": "q2", "type": "textarea",  "required": true,  "templateParam": "2" },
        { "label": "Question C:", "name": "q3", "type": "dropdown", "required": false, "options": ["i) apples", "ii) bananas"], "templateParam": "3" },
        { "label": "Question D:", "name": "q4", "type": "checkbox", "required": false, "options": ["cats", "dogs"], "templateParam": "4" },
        { "label": "Question E:", "name": "q5", "type": "radio",    "required": true,  "options": ["noun", "verb"], "templateParam": "5" },
        { "label": "Section title:", "name": "q6", "type": "text",  "required": true,  "templateParam": "6" }
      ]
    }
*/
/* global mw, $ */
(function () {
    var CONFIG_PAGE = 'User:L235/form-config.json';

    mw.loader.using(['mediawiki.api', 'oojs-ui']).then(function () {
        var api = new mw.Api();

        // 1. Fetch JSON config -------------------------------------------
        api.get({
            action: 'query',
            prop: 'revisions',
            titles: CONFIG_PAGE,
            rvprop: 'content',
            formatversion: 2
        }).then(function (data) {
            var pages = data.query.pages;
            if (!pages.length || !pages[0].revisions) {
                console.error('[BlankPage‑Form] Config page not found or empty');
                return;
            }

            var content = pages[0].revisions[0].content;
            var config;
            try {
                config = JSON.parse(content);
            } catch (e) {
                console.error('[BlankPage‑Form] Error parsing JSON config:', e);
                return;
            }

            var currentPage = mw.config.get('wgPageName').replace(/_/g, ' ');
            if (currentPage !== config.formPage) {
                // abort if we are not on the configured form page
                return;
            }

            buildForm(config);
        }).fail(function (err) {
            console.error('[BlankPage‑Form] API error fetching config:', err);
        });

        // 2. Render the form ---------------------------------------------
        function buildForm(config) {
            var $content = $('#mw-content-text').empty();
            $content.append($('<h2>').text(config.title || 'Submit your answers'));

            var $form = $('<form>').appendTo($content);

            config.questions.forEach(function (q) {
                renderQuestion($form, q);
                $form.append('<br><br>');
            });

            var $submit = $('<input>').attr({ type: 'submit', value: 'Submit' });
            $form.append($submit);

            $form.on('submit', function (e) {
                e.preventDefault();
                handleSubmit($form, config, $submit);
            });
        }

        function renderQuestion($form, q) {
            var $label = $('<label>').text(q.label + (q.required ? ' (required): ' : ': '));
            var $field;

            switch (q.type) {
                case 'text':
                    $field = $('<input>').attr({ type: 'text', name: q.name, size: 40 });
                    break;
                case 'textarea':
                    $field = $('<textarea>').attr({ name: q.name, rows: 4, cols: 60 });
                    break;
                case 'dropdown':
                    $field = $('<select>').attr('name', q.name);
                    q.options.forEach(function (opt) {
                        $field.append($('<option>').val(opt).text(opt));
                    });
                    break;
                case 'checkbox':
                    $field = $('<span>');
                    q.options.forEach(function (opt) {
                        var $cbLabel = $('<label>');
                        var $cb = $('<input>').attr({ type: 'checkbox', name: q.name, value: opt });
                        $cbLabel.append($cb, ' ', opt, '\u00A0');
                        $field.append($cbLabel);
                    });
                    break;
                case 'radio':
                    $field = $('<span>');
                    q.options.forEach(function (opt, idx) {
                        var $rbLabel = $('<label>');
                        var $rb = $('<input>').attr({
                            type: 'radio', name: q.name, value: opt,
                            required: q.required && idx === 0 // HTML5 wants required on one item
                        });
                        $rbLabel.append($rb, ' ', opt, '\u00A0');
                        $field.append($rbLabel);
                    });
                    break;
                default:
                    console.warn('[BlankPage‑Form] Unsupported field type:', q.type);
                    return;
            }

            if (q.required && q.type !== 'radio') {
                $field.attr('required', true);
            }

            $form.append($label.append($field));
        }

        // 3. Submission ---------------------------------------------------
        function getFieldValue($form, q) {
            switch (q.type) {
                case 'checkbox':
                    return $form.find('[name=' + q.name + ']:checked').map(function () {
                        return this.value;
                    }).get().join(', ');
                case 'radio':
                    return $form.find('[name=' + q.name + ']:checked').val() || '';
                default:
                    return $form.find('[name=' + q.name + ']').val().trim();
            }
        }

        function handleSubmit($form, config, $submit) {
            // Basic validation for required fields
            var missing = config.questions.filter(function (q) {
                return q.required && !getFieldValue($form, q);
            });
            if (missing.length) {
                alert('Please fill required fields: ' + missing.map(function (q) {
                    return q.label.replace(/:\s*$/, '');
                }).join(', '));
                return;
            }

            var wikitextParams = config.questions.map(function (q) {
                var val = getFieldValue($form, q);
                return '|' + q.templateParam + '=' + val;
            }).join('');

            var tplName = config.template.name;
            if (config.template.subst) {
                tplName = 'subst:' + tplName;
            }

            var wikitext = '\n{{' + tplName + wikitextParams + '}}\n';

            $submit.prop('disabled', true).val('Submitting…');

            api.postWithToken('csrf', {
                action: 'edit',
                title: config.targetPage,
                appendtext: wikitext,
                summary: config.editSummary || 'Append answers via user‑script form'
            }).done(function () {
                mw.notify('Your answers were saved!', { type: 'success' });
                $form[0].reset();
            }).fail(function (err) {
                console.error('[BlankPage‑Form] Edit error:', err);
                mw.notify('Error: ' + err, { type: 'error', autoHide: false });
            }).always(function () {
                $submit.prop('disabled', false).val('Submit');
            });
        }
    });
})();