Skip to content

Instantly share code, notes, and snippets.

@neverstew
Last active October 8, 2019 09:12
Show Gist options
  • Save neverstew/2256f376a0b530ce70d745808a2c7790 to your computer and use it in GitHub Desktop.
Save neverstew/2256f376a0b530ce70d745808a2c7790 to your computer and use it in GitHub Desktop.
Draggable Form Creation Starter
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Draggable Forms</title>
<link rel='stylesheet' href='main.css'>
</head>
<body>
<main>
<div id="templates">
<h1>Templates</h1>
<div draggable="true" ondragstart="drag(event)" id="template-simple" class="question">
<h2>Simple Question</h2>
<label for="question">
Question
<input class="field" type="text" name="question">
</label>
<label for="required">
Required
<input class="field" type="checkbox" name="required">
</label>
</div>
<div draggable="true" ondragstart="drag(event)" id="template-single-choice" class="question">
<h2>Single-Choice Question</h2>
<label for="question">
Question
<input class="field" type="text" name="question">
</label>
<label for="option-1">
Option 1
<input class="field-option" type="radio" name="single-choice-question">
</label>
<label for="option-2">
Option 2
<input class="field-option" type="radio" name="single-choice-question">
</label>
</div>
</div>
<div id="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)" width="50vw" height="50vh">
<button id="convert" onclick="convert()">Convert</button>
</div>
</main>
<footer></footer>
<script src="main.js"></script>
</body>
</html>
body {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: Arial, Helvetica, Ubuntu, sans-serif;
}
main {
display: grid;
grid-template-columns: auto 1fr;
}
#templates {
height: 100vh;
padding: 1em;
border-right: 1px solid rgba(0,0,0,0.2);
}
.question {
margin: 1em;
padding: 1em;
border-radius: 4px;
border: 1px solid rgba(0,0,0,0.2);
box-shadow: 2px 2px 4px rgba(0,0,0,0.2);
}
.question h2 {
margin-top: 0;
font-size: 1.4em;
}
label {
display: block;
margin: 1em;
font-weight: 600;
letter-spacing: 0.05em;
}
input {
display: block;
padding: 0.2em;
}
#dropzone div {
margin-bottom: 2em;
}
#convert {
float: right;
position: relative;
top: 90%;
}
function allowDrop(ev) {
/* The default handling is to not allow dropping elements. */
/* Here we allow it by preventing the default behaviour. */
ev.preventDefault();
}
function drag(ev) {
/* Here is specified what should be dragged. */
/* This data will be dropped at the place where the mouse button is released */
/* Here, we want to drag the element itself, so we set it's ID. */
ev.dataTransfer.setData("text/html", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text/html");
/* If you use DOM manipulation functions, their default behaviour it not to
copy but to alter and move elements. By appending a ".cloneNode(true)",
you will not move the original element, but create a copy. */
var node;
if (!data.includes("template")) {
node = document.getElementById(data);
} else {
node = createNewQuestion(data);
}
ev.target.appendChild(node);
}
function createNewQuestion(templateId) {
var newEl = document.getElementById(templateId).cloneNode(true);
newEl.id = yieldId(); /* We cannot use the same ID */
return newEl;
}
var ID_COUNT = 0
function yieldId() {
ID_COUNT += 1;
return "question-"+ID_COUNT.toString();
}
function convert() {
var data = {questions: []};
const dropzone = document.getElementById("dropzone");
const questions = dropzone.getElementsByClassName("question");
for(let question of questions) {
var item = convertSimpleQuestion(question);
data.questions.push(item);
};
const dataString = JSON.stringify(data);
var dataElement = document.createElement("div");
dataElement.innerText = dataString;
document.getElementsByTagName("footer")[0].appendChild(dataElement);
}
function convertSimpleQuestion(question) {
var item = [];
var labels = question.getElementsByTagName("label")
for(let label of labels) {
var field = label.getElementsByClassName("field")[0];
item.push(createQuestionJson({
title: field.value,
questionType: field.getAttribute("type"),
}))
}
return item;
}
function convertSingleOptionQuestion(question) {
// TODO
var item = {}
return {
type: field.getAttribute("type"),
}
}
function createQuestionJson({ title, questionType, required = true, options }) {
var data = {
title: title,
shortTitle: title.toLowerCase().replace(" ", "-"),
questionType: questionType.toUpperCase(),
required: required,
}
if (options) {
data.optionsGroups = [
{
options: options
}
]
}
return data;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment