{"id":74,"date":"2026-09-01T08:07:42","date_gmt":"2026-09-01T08:07:42","guid":{"rendered":"https:\/\/plugin.themenut.com\/qnabuy\/?page_id=74"},"modified":"2026-09-01T09:17:32","modified_gmt":"2026-09-01T09:17:32","slug":"json-generator","status":"publish","type":"page","link":"https:\/\/plugin.themenut.com\/qnabuy\/json-generator\/","title":{"rendered":"JSON Generator"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<style data-wp-block-html=\"css\">\n:root {\n            --primary: #007cba;\n            --primary-hover: #005a87;\n            --bg-light: #f8fafc;\n            --border: #cbd5e1;\n            --dark: #1e293b;\n            --danger: #ef4444;\n            --card-bg: #ffffff;\n        }\n\n        .container { max-width: 1300px; margin: 0 auto; display: grid; grid-template-columns: repeat(auto-fill, minmax(max(min(22rem, 100%), (100% - (1.2rem * (3 - 1))) \/3), 1fr)); gap: 24px; }\n\n        .card { background: var(--card-bg); border: 1px solid var(--border); border-radius: 8px; padding: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); }\n        .card-header { display: flex; justify-content: space-between; align-items: center; border-bottom: 2px solid var(--bg-light); padding-bottom: 12px; margin-bottom: 16px; }\n        h2 { font-size: 18px; color: var(--dark); }\n\n        \/* Question Box Styling *\/\n        .question-card { border: 1px solid var(--border); border-radius: 8px; padding: 16px; margin-bottom: 20px; background: #fff; position: relative; }\n        .question-card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; background: #f1f5f9; padding: 8px 12px; border-radius: 6px; }\n        \n        \/* Form Controls *\/\n        .form-group { margin-bottom: 12px; }\n        .inline-group { display: flex; gap: 12px; }\n        label { display: block; font-size: 11px; font-weight: 700; text-transform: uppercase; margin-bottom: 4px; color: #64748b; }\n        input[type=\"text\"] { width: 100%; padding: 8px 12px; border: 1px solid var(--border); border-radius: 4px; font-size: 14px; outline: none; }\n        input[type=\"text\"]:focus { border-color: var(--primary); }\n\n        \/* Answers & Mapping Section *\/\n        .answer-box { background: var(--bg-light); border: 1px solid var(--border); border-radius: 6px; padding: 12px; margin-bottom: 12px; }\n        .mapping-row { display: flex; gap: 8px; margin-top: 8px; align-items: center; }\n        .mapping-row input { flex: 1; }\n\n        \/* Buttons *\/\n        .btn { padding: 8px 14px; border-radius: 4px; border: none; font-size: 13px; font-weight: 600; cursor: pointer; transition: 0.2s; }\n        .btn-primary { background: var(--primary); color: #fff; }\n        .btn-primary:hover { background: var(--primary-hover); }\n        .btn-secondary { background: #e2e8f0; color: var(--dark); }\n        .btn-secondary:hover { background: #cbd5e1; }\n        .btn-danger { background: var(--danger); color: #fff; padding: 4px 8px; font-size: 12px; }\n\n        \/* Output JSON Code Box *\/\n        .sticky-preview { position: sticky; top: 20px; }\n        pre { background: #0f172a; color: #38bdf8; padding: 16px; border-radius: 6px; font-family: monospace; font-size: 13px; overflow-x: auto; max-height: 80vh; }\n<\/style>\n\n<div class=\"container\">\n        <!-- Input Controls -->\n        <div class=\"card\">\n            <div class=\"card-header\">\n                <h2>Quiz Questions Editor<\/h2>\n                <button class=\"btn btn-primary\" id=\"add-question-btn\">+ Add Question<\/button>\n            <\/div>\n            \n            <div id=\"questions-container\"><\/div>\n        <\/div>\n\n        <!-- JSON Output Preview -->\n        <div class=\"sticky-preview\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Live JSON Schema Output<\/h2>\n                    <button class=\"btn btn-primary\" id=\"copy-btn\">Copy JSON<\/button>\n                <\/div>\n                <pre><code id=\"json-preview\">{}<\/code><\/pre>\n            <\/div>\n        <\/div>\n    <\/div>\n\n<script>\n\/\/ Multi-question state store\n        let questionsState = [\n            {\n                id: 'q1',\n                text: 'Select your routine items:',\n                answers: [\n                    {\n                        text: 'Cleanser & Hydrator (Small)',\n                        mappings: [\n                            { productId: '101', variations: '202, 203' },\n                            { productId: '103', variations: '' }\n                        ]\n                    },\n                    {\n                        text: 'Cleanser & Hydrator (Large)',\n                        mappings: [\n                            { productId: '102', variations: '204' }\n                        ]\n                    }\n                ]\n            }\n        ];\n\n        const questionsContainer = document.getElementById('questions-container');\n        const jsonPreview = document.getElementById('json-preview');\n\n        \/\/ Render full questions UI\n        function render() {\n            questionsContainer.innerHTML = '';\n\n            questionsState.forEach((q, qIdx) => {\n                const qCard = document.createElement('div');\n                qCard.className = 'question-card';\n                qCard.innerHTML = `\n                    <div class=\"question-card-header\">\n                        <strong style=\"font-size: 14px;\">Question #${qIdx + 1}<\/strong>\n                        <div>\n                            ${questionsState.length > 1 ? `<button class=\"btn btn-danger\" onclick=\"removeQuestion(${qIdx})\">Remove Question<\/button>` : ''}\n                        <\/div>\n                    <\/div>\n\n                    <div class=\"inline-group\">\n                        <div class=\"form-group\" style=\"width: 30%;\">\n                            <label>Question ID<\/label>\n                            <input type=\"text\" value=\"${q.id}\" oninput=\"updateQuestion(${qIdx}, 'id', this.value)\">\n                        <\/div>\n                        <div class=\"form-group\" style=\"width: 70%;\">\n                            <label>Question Prompt<\/label>\n                            <input type=\"text\" value=\"${q.text}\" oninput=\"updateQuestion(${qIdx}, 'text', this.value)\">\n                        <\/div>\n                    <\/div>\n\n                    <div style=\"display:flex; justify-content:space-between; align-items:center; margin: 16px 0 8px 0;\">\n                        <label style=\"margin: 0;\">Answers & Product Mapping<\/label>\n                        <button class=\"btn btn-secondary\" onclick=\"addAnswer(${qIdx})\" style=\"font-size:12px;\">+ Add Choice<\/button>\n                    <\/div>\n\n                    <div id=\"answers-container-${qIdx}\"><\/div>\n                `;\n\n                const answersContainer = qCard.querySelector(`#answers-container-${qIdx}`);\n                \n                q.answers.forEach((ans, ansIdx) => {\n                    const ansBox = document.createElement('div');\n                    ansBox.className = 'answer-box';\n                    ansBox.innerHTML = `\n                        <div style=\"display:flex; justify-content:space-between; margin-bottom: 8px;\">\n                            <span style=\"font-size: 11px; font-weight: bold; color: #475569;\">Answer #${ansIdx + 1}<\/span>\n                            <button class=\"btn btn-danger\" onclick=\"removeAnswer(${qIdx}, ${ansIdx})\">Remove Choice<\/button>\n                        <\/div>\n                        <input type=\"text\" placeholder=\"Answer Text\" value=\"${ans.text}\" oninput=\"updateAnswerText(${qIdx}, ${ansIdx}, this.value)\" style=\"margin-bottom:8px;\">\n                        \n                        <label style=\"font-size:10px; margin-top:6px;\">Product Mappings<\/label>\n                        <div id=\"mappings-${qIdx}-${ansIdx}\"><\/div>\n                        <button class=\"btn btn-secondary\" onclick=\"addMapping(${qIdx}, ${ansIdx})\" style=\"font-size:11px; margin-top:6px;\">+ Add Product Mapping<\/button>\n                    `;\n\n                    const mappingsContainer = ansBox.querySelector(`#mappings-${qIdx}-${ansIdx}`);\n                    ans.mappings.forEach((map, mapIdx) => {\n                        const row = document.createElement('div');\n                        row.className = 'mapping-row';\n                        row.innerHTML = `\n                            <input type=\"text\" placeholder=\"Product ID (e.g. 101)\" value=\"${map.productId}\" oninput=\"updateMapping(${qIdx}, ${ansIdx}, ${mapIdx}, 'productId', this.value)\">\n                            <input type=\"text\" placeholder=\"Variations (e.g. 202, 203)\" value=\"${map.variations}\" oninput=\"updateMapping(${qIdx}, ${ansIdx}, ${mapIdx}, 'variations', this.value)\">\n                            <button class=\"btn btn-danger\" onclick=\"removeMapping(${qIdx}, ${ansIdx}, ${mapIdx})\">\u2715<\/button>\n                        `;\n                        mappingsContainer.appendChild(row);\n                    });\n\n                    answersContainer.appendChild(ansBox);\n                });\n\n                questionsContainer.appendChild(qCard);\n            });\n\n            updateJSONOutput();\n        }\n\n        \/\/ Generate JSON output format\n        function updateJSONOutput() {\n            const formattedSchema = {\n                questions: questionsState.map(q => ({\n                    id: q.id || 'q1',\n                    question: q.text,\n                    answers: q.answers.map(ans => {\n                        const product_variations = {};\n                        ans.mappings.forEach(m => {\n                            if (m.productId.trim() !== '') {\n                                const vars = m.variations\n                                    .split(',')\n                                    .map(v => parseInt(v.trim(), 10))\n                                    .filter(v => !isNaN(v));\n                                product_variations[m.productId.trim()] = vars;\n                            }\n                        });\n                        return {\n                            text: ans.text,\n                            product_variations: product_variations\n                        };\n                    })\n                }))\n            };\n\n            jsonPreview.textContent = JSON.stringify(formattedSchema, null, 4);\n        }\n\n        \/\/ Global State Handler Functions\n        document.getElementById('add-question-btn').addEventListener('click', () => {\n            const nextId = `q${questionsState.length + 1}`;\n            questionsState.push({\n                id: nextId,\n                text: 'New Question Title',\n                answers: [{ text: 'Sample Option', mappings: [{ productId: '', variations: '' }] }]\n            });\n            render();\n        });\n\n        window.removeQuestion = (qIdx) => {\n            questionsState.splice(qIdx, 1);\n            render();\n        };\n\n        window.updateQuestion = (qIdx, field, val) => {\n            questionsState[qIdx][field] = val;\n            updateJSONOutput();\n        };\n\n        window.addAnswer = (qIdx) => {\n            questionsState[qIdx].answers.push({ text: 'New Answer Option', mappings: [{ productId: '', variations: '' }] });\n            render();\n        };\n\n        window.removeAnswer = (qIdx, ansIdx) => {\n            questionsState[qIdx].answers.splice(ansIdx, 1);\n            render();\n        };\n\n        window.updateAnswerText = (qIdx, ansIdx, val) => {\n            questionsState[qIdx].answers[ansIdx].text = val;\n            updateJSONOutput();\n        };\n\n        window.addMapping = (qIdx, ansIdx) => {\n            questionsState[qIdx].answers[ansIdx].mappings.push({ productId: '', variations: '' });\n            render();\n        };\n\n        window.removeMapping = (qIdx, ansIdx, mapIdx) => {\n            questionsState[qIdx].answers[ansIdx].mappings.splice(mapIdx, 1);\n            render();\n        };\n\n        window.updateMapping = (qIdx, ansIdx, mapIdx, field, val) => {\n            questionsState[qIdx].answers[ansIdx].mappings[mapIdx][field] = val;\n            updateJSONOutput();\n        };\n\n        \/\/ Clipboard handle\n        document.getElementById('copy-btn').addEventListener('click', () => {\n            navigator.clipboard.writeText(jsonPreview.textContent);\n            const btn = document.getElementById('copy-btn');\n            btn.textContent = 'Copied!';\n            setTimeout(() => { btn.textContent = 'Copy JSON'; }, 2000);\n        });\n\n        \/\/ Initial setup\n        render();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Quiz Questions Editor + Add Question Live JSON Schema Output Copy JSON {}<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-74","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/plugin.themenut.com\/qnabuy\/wp-json\/wp\/v2\/pages\/74","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/plugin.themenut.com\/qnabuy\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/plugin.themenut.com\/qnabuy\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/plugin.themenut.com\/qnabuy\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/plugin.themenut.com\/qnabuy\/wp-json\/wp\/v2\/comments?post=74"}],"version-history":[{"count":10,"href":"https:\/\/plugin.themenut.com\/qnabuy\/wp-json\/wp\/v2\/pages\/74\/revisions"}],"predecessor-version":[{"id":109,"href":"https:\/\/plugin.themenut.com\/qnabuy\/wp-json\/wp\/v2\/pages\/74\/revisions\/109"}],"wp:attachment":[{"href":"https:\/\/plugin.themenut.com\/qnabuy\/wp-json\/wp\/v2\/media?parent=74"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}