Last active
October 8, 2019 09:12
-
-
Save neverstew/2256f376a0b530ce70d745808a2c7790 to your computer and use it in GitHub Desktop.
Draggable Form Creation Starter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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%; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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