-
-
Save dchun/81cf5df7bb82f42c8fac to your computer and use it in GitHub Desktop.
Render Form Example Shopify
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 getJSON(url) { | |
return new Promise(function(resolve, reject) { | |
var xhr = new XMLHttpRequest(); | |
xhr.open('GET',url,true); | |
xhr.responseType = 'json'; | |
xhr.onload = function() { | |
var status = xhr.status; | |
if (status == 200) { | |
resolve(xhr.response); | |
} else { | |
reject(status); | |
} | |
}; | |
xhr.onerror = function() { | |
reject(xhr.response); | |
}; | |
xhr.send(); | |
}); | |
}; | |
function postForm(form) { | |
if (validate(form)) { | |
var xhr = new XMLHttpRequest(); | |
var fData = new FormData(form) | |
xhr.open('POST',form.action,true); | |
xhr.onreadystatechange = function () { | |
if (xhr.readyState == 4 && xhr.status == 201) { | |
document.getElementById('qm-modal-inner').innerHTML = '<h2>Success!</h2>'; | |
setTimeout(function(){ | |
document.getElementById('qm-modal').remove(); | |
},2000) | |
} | |
}; | |
xhr.send(fData); | |
} | |
} | |
function validate(form) { | |
var a = form.getElementsByClassName('qm-required') | |
var errors = 0; | |
for (var ii=0; ii<a.length; ii++) { | |
a[ii].classList.remove('qm-error'); | |
var group = 0; | |
for (var i=0; i<a[ii].childNodes.length; i++) { | |
var child = a[ii].childNodes[i]; | |
if (child.tagName == "INPUT") { | |
if (child.type == "text" && child.value.length < 1 ) { | |
a[ii].className = a[ii].className + " qm-error"; | |
errors ++; | |
} | |
if (child.type == "email") { | |
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; | |
if (!re.test(child.value)) { | |
a[ii].className = a[ii].className + " qm-error"; | |
errors ++; | |
} | |
} | |
if (child.type == "tel" && child.value.length < 1 ) { | |
a[ii].className = a[ii].className + " qm-error"; | |
errors ++; | |
} | |
if (child.type == "checkbox") { | |
if (child.checked) { group++ } | |
} | |
if (child.type == "radio") { | |
if (child.checked) { group++ } | |
} | |
} | |
if (child.tagName == "SELECT" && child.value.length < 1) { | |
a[ii].className = a[ii].className + " qm-error"; | |
errors ++; | |
} | |
if (child.tagName == "TEXTAREA" && child.value.length < 1) { | |
a[ii].className = a[ii].className + " qm-error"; | |
errors ++; | |
} | |
} | |
if ((a[ii].classList.contains("qm-checkbox") || a[ii].classList.contains("qm-radio")) && group < 1) { | |
a[ii].className = a[ii].className + " qm-error"; | |
errors++; | |
} | |
} | |
if (errors < 1) { return true } | |
} | |
function renderForm(url,fId,json_product) { | |
var a = document.getElementById('qm-modal'); | |
if (a) { | |
setProduct(json_product); | |
var quote = JSON.parse(sessionStorage.getItem('qm-rfq')); | |
document.getElementById('qm-variant-text').value = quote.variantText; | |
document.getElementById('qm-variant-id').value = quote.variantId; | |
a.style.display = 'block'; | |
} else { | |
setProduct(json_product); | |
buildForm(url,fId); | |
} | |
} | |
function setProduct(json_product) { | |
var e = document.getElementById('product-select'); | |
if (e.disabled == false) { | |
var i = e.options[e.selectedIndex].value; | |
var t = e.options[e.selectedIndex].text; | |
} else { | |
var i = ''; | |
var t = ''; | |
for (var k=0; k<json_product['options'].length; k++) { | |
var l = document.getElementById('product-select-option-'+k); | |
var m = l.options[l.selectedIndex].value; | |
t = t + json_product['options'][k] + ': ' + m + ' / '; | |
} | |
t = t.substring(0, t.length - 3); | |
}; | |
var myQuote = new Object(); | |
myQuote.productId = json_product['id']; | |
myQuote.productTitle = json_product['title']; | |
myQuote.variantId = i; | |
myQuote.variantText = t; | |
sessionStorage.setItem('qm-rfq', JSON.stringify(myQuote)); | |
} | |
function buildForm(url,fId) { | |
var a = document.createElement('div'); | |
a.id = 'qm-modal'; | |
a.style.display = 'visible'; | |
a.style.position = 'fixed'; | |
a.style.zIndex = '10000'; | |
a.style.top = '0'; | |
a.style.left = '0'; | |
a.style.right = '0'; | |
a.style.bottom = '0'; | |
a.style.overflowX = 'hidden'; | |
a.style.overflowY = 'auto'; | |
a.style.background = 'rgba(0,0,0,0.7)'; | |
var al = document.createElement('img'); | |
al.id = 'qm-ajax-loader'; | |
al.src = '//cdn.shopify.com/s/global/lightbox/v204/loading.gif'; | |
al.style.position = 'fixed'; | |
al.style.left = '50%'; | |
al.style.top = '45%'; | |
a.appendChild(al); | |
document.getElementsByTagName('body')[0].appendChild(a); | |
getJSON(url+'forms/'+fId+'.json').then(function(d) { | |
var b = document.createElement('div'); | |
b.id = 'qm-modal-inner'; | |
b.style.display = 'none'; | |
b.style.zIndex = '10001'; | |
b.style.margin = '30px auto'; | |
b.style.top = '30px'; | |
b.style.position = 'relative'; | |
b.style.background = '#fff'; | |
b.style.width = '600px'; | |
b.style.padding = '10px 20px'; | |
b.style.border = '5px solid #999'; | |
b.style.borderRadius = '10px'; | |
b.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)'; | |
var c = document.createElement('form'); | |
c.style.padding = '10px'; | |
c.action = url+'requests.json'; | |
c.enctype = 'application/json'; | |
c.id = 'qm-form'; | |
var l = document.createElement('input'); | |
l.type = 'hidden'; | |
l.name = 'request[form_id]'; | |
l.value = d['id']; | |
c.appendChild(l); | |
var m = document.createElement('div'); | |
var n = document.createElement('div'); | |
var o = document.createElement('label'); | |
var p = document.createElement('label'); | |
var q = document.createElement('input'); | |
var r = document.createElement('input'); | |
var aa = document.createElement('input'); | |
var ab = document.createElement('input'); | |
var quote = JSON.parse(sessionStorage.getItem('qm-rfq')); | |
m.className = 'qm-group'; | |
n.className = 'qm-group'; | |
o.htmlFor = 'product'; | |
o.innerHTML = 'Product'; | |
p.htmlFor = 'variant'; | |
p.innerHTML = 'Variants'; | |
q.type = 'text'; | |
q.id = 'qm-product-title' | |
q.name = ''; | |
q.readOnly = 'true'; | |
q.value = quote.productTitle; | |
r.type = 'text'; | |
r.id = 'qm-variant-text' | |
r.name = ''; | |
r.readOnly = 'true'; | |
r.value = quote.variantText; | |
aa.type = 'hidden'; | |
aa.id = 'qm-product-id' | |
aa.name = ''; | |
aa.value = quote.productId; | |
ab.type = 'hidden'; | |
ab.id = 'qm-variant-id' | |
ab.name = ''; | |
ab.value = quote.variantId; | |
m.appendChild(o); | |
m.appendChild(q); | |
m.appendChild(aa); | |
n.appendChild(p); | |
n.appendChild(r); | |
n.appendChild(ab); | |
c.appendChild(m); | |
c.appendChild(n); | |
var f = document.createElement('div'); | |
var h = document.createElement('a'); | |
var g = document.createElement('h4'); | |
f.style.padding = '10px'; | |
f.style.borderBottom = '1px solid #e5e5e5'; | |
h.style.float = 'right'; | |
h.id = 'modal_close'; | |
h.href = '#'; | |
h.text = 'x'; | |
h.onclick = function() { a.style.display = 'none'; return false; } | |
g.style.margin = '0'; | |
g.innerHTML = d['name']; | |
f.appendChild(h); | |
f.appendChild(g); | |
b.appendChild(f); | |
var i = d['fields']; | |
for (var e in i) { | |
switch(i[e]['type']) { | |
case 'name': | |
var w = document.createElement('div'); | |
var x = document.createElement('label'); | |
var y = document.createElement('input'); | |
var u = document.createElement('input'); | |
var v = document.createElement('input'); | |
i[e]['required'] == '1' ? w.className = 'qm-group qm-name qm-required' : w.className = 'qm-group qm-name'; | |
x.innerHTML = i[e]['label']; | |
x.htmlFor = e; | |
y.type = 'text'; | |
y.id = e; | |
y.name = 'request[fields]['+e+'][request]'; | |
i[e]['required'] == '1' ? y.required = 'true' : y.required = 'false'; | |
u.type = 'hidden'; | |
u.name = 'request[fields]['+e+'][label]'; | |
u.value = i[e]['label']; | |
v.type = 'hidden'; | |
v.name = 'request[fields]['+e+'][type]'; | |
v.value = i[e]['type']; | |
w.appendChild(x); | |
w.appendChild(y); | |
w.appendChild(u); | |
w.appendChild(v); | |
c.appendChild(w); | |
break; | |
case 'phone': | |
var w = document.createElement('div'); | |
var x = document.createElement('label'); | |
var y = document.createElement('input'); | |
var u = document.createElement('input'); | |
var v = document.createElement('input'); | |
i[e]['required'] == '1' ? w.className = 'qm-group qm-phone qm-required' : w.className = 'qm-group qm-phone'; | |
x.innerHTML = i[e]['label']; | |
x.htmlFor = e; | |
y.type = 'tel'; | |
y.id = e; | |
y.name = 'request[fields]['+e+'][request]'; | |
i[e]['required'] == '1' ? y.required = 'true' : y.required = 'false'; | |
u.type = 'hidden'; | |
u.name = 'request[fields]['+e+'][label]'; | |
u.value = i[e]['label']; | |
v.type = 'hidden'; | |
v.name = 'request[fields]['+e+'][type]'; | |
v.value = i[e]['type']; | |
w.appendChild(x); | |
w.appendChild(y); | |
w.appendChild(u); | |
w.appendChild(v); | |
c.appendChild(w); | |
break; | |
case 'email': | |
var w = document.createElement('div'); | |
var x = document.createElement('label'); | |
var y = document.createElement('input'); | |
var u = document.createElement('input'); | |
var v = document.createElement('input'); | |
i[e]['required'] == '1' ? w.className = 'qm-group qm-email qm-required' : w.className = 'qm-group qm-email'; | |
x.innerHTML = i[e]['label']; | |
x.htmlFor = e; | |
y.type = 'email'; | |
y.id = e; | |
y.name = 'request[fields]['+e+'][request]'; | |
i[e]['required'] == '1' ? y.required = 'true' : y.required = 'false'; | |
u.type = 'hidden'; | |
u.name = 'request[fields]['+e+'][label]'; | |
u.value = i[e]['label']; | |
v.type = 'hidden'; | |
v.name = 'request[fields]['+e+'][type]'; | |
v.value = i[e]['type']; | |
w.appendChild(x); | |
w.appendChild(y); | |
w.appendChild(u); | |
w.appendChild(v); | |
c.appendChild(w); | |
break; | |
case 'text': | |
var w = document.createElement('div'); | |
var x = document.createElement('label'); | |
var y = document.createElement('input'); | |
var u = document.createElement('input'); | |
var v = document.createElement('input'); | |
i[e]['required'] == '1' ? w.className = 'qm-group qm-text qm-required' : w.className = 'qm-group qm-text'; | |
x.innerHTML = i[e]['label']; | |
x.htmlFor = e; | |
y.type = 'text'; | |
y.id = e; | |
y.name = 'request[fields]['+e+'][request]'; | |
i[e]['required'] == '1' ? y.required = 'true' : y.required = 'false'; | |
u.type = 'hidden'; | |
u.name = 'request[fields]['+e+'][label]'; | |
u.value = i[e]['label']; | |
v.type = 'hidden'; | |
v.name = 'request[fields]['+e+'][type]'; | |
v.value = i[e]['type']; | |
w.appendChild(x); | |
w.appendChild(y); | |
w.appendChild(u); | |
w.appendChild(v); | |
c.appendChild(w); | |
break; | |
case 'paragraph': | |
var w = document.createElement('div'); | |
var x = document.createElement('label'); | |
var y = document.createElement('textarea'); | |
var u = document.createElement('input'); | |
var v = document.createElement('input'); | |
i[e]['required'] == '1' ? w.className = 'qm-group qm-paragraph qm-required' : w.className = 'qm-group qm-name'; | |
x.innerHTML = i[e]['label']; | |
x.htmlFor = e; | |
y.id = e; | |
y.name = 'request[fields]['+e+'][request]'; | |
i[e]['required'] == '1' ? y.required = 'true' : y.required = 'false'; | |
u.type = 'hidden'; | |
u.name = 'request[fields]['+e+'][label]'; | |
u.value = i[e]['label']; | |
v.type = 'hidden'; | |
v.name = 'request[fields]['+e+'][type]'; | |
v.value = i[e]['type']; | |
w.appendChild(x); | |
w.appendChild(y); | |
w.appendChild(u); | |
w.appendChild(v); | |
c.appendChild(w); | |
break; | |
case 'radio': | |
var w = document.createElement('div'); | |
var x = document.createElement('label'); | |
var t = document.createElement('input'); | |
var u = document.createElement('input'); | |
i[e]['required'] == '1' ? w.className = 'qm-group qm-radio qm-required' : w.className = 'qm-group qm-radio'; | |
x.innerHTML = i[e]['label']; | |
t.type = 'hidden'; | |
t.name = 'request[fields]['+e+'][label]'; | |
t.value = i[e]['label']; | |
u.type = 'hidden'; | |
u.name = 'request[fields]['+e+'][type]'; | |
u.value = i[e]['type']; | |
w.appendChild(x); | |
w.appendChild(t); | |
w.appendChild(u); | |
for (var y in i[e]['options']) { | |
var v = document.createElement('label'); | |
var z = document.createElement('input'); | |
v.innerHTML = i[e]['options'][y]['name']; | |
v.htmlFor = e+'_'+i[e]['options'][y]['name'].toLowerCase().split(' ').join('_'); | |
z.id = e+'_'+i[e]['options'][y]['name'].toLowerCase().split(' ').join('_'); | |
z.type ='radio'; | |
z.value = i[e]['options'][y]['name']; | |
z.name ='request[fields]['+e+'][request]'; | |
i[e]['required'] == '1' ? z.required = true : z.required = false; | |
w.appendChild(z); | |
w.appendChild(v); | |
} | |
c.appendChild(w); | |
break; | |
case 'check_box': | |
var w = document.createElement('div'); | |
var x = document.createElement('label'); | |
var t = document.createElement('input'); | |
var u = document.createElement('input'); | |
i[e]['required'] == '1' ? w.className = 'qm-group qm-checkbox qm-required' : w.className = 'qm-group qm-checkbox'; | |
x.innerHTML = i[e]['label']; | |
t.type = 'hidden'; | |
t.name = 'request[fields]['+e+'][label]'; | |
t.value = i[e]['label']; | |
u.type = 'hidden'; | |
u.name = 'request[fields]['+e+'][type]'; | |
u.value = i[e]['type']; | |
w.appendChild(x); | |
w.appendChild(t); | |
w.appendChild(u); | |
for (var y in i[e]['options']) { | |
var v = document.createElement('label'); | |
var z = document.createElement('input'); | |
v.innerHTML = i[e]['options'][y]['name']; | |
v.htmlFor = e+'_'+i[e]['options'][y]['name'].toLowerCase().split(' ').join('_'); | |
z.id = e+'_'+i[e]['options'][y]['name'].toLowerCase().split(' ').join('_'); | |
i[e]['options'][y]['required'] == '1' ? z.required = true : z.required = false; | |
z.type ='checkbox'; | |
z.value = i[e]['options'][y]['name']; | |
z.name ='request[fields]['+e+'][request][]'; | |
w.appendChild(z); | |
w.appendChild(v); | |
} | |
c.appendChild(w); | |
break; | |
case 'select': | |
var u = document.createElement('div'); | |
var x = document.createElement('label'); | |
var s = document.createElement('input'); | |
var t = document.createElement('input'); | |
var w = document.createElement('select'); | |
var v = document.createElement('option'); | |
i[e]['required'] == '1' ? u.className = 'qm-group qm-select qm-required' : u.className = 'qm-group qm-select'; | |
x.innerHTML = i[e]['label']; | |
s.type = 'hidden'; | |
s.name = 'request[fields]['+e+'][label]'; | |
s.value = i[e]['label']; | |
t.type = 'hidden'; | |
t.name = 'request[fields]['+e+'][type]'; | |
t.value = i[e]['type']; | |
w.name = 'request[fields]['+e+'][request]'; | |
i[e]['required'] == '1' ? w.required = true : w.required = false; | |
v.text = 'Select Option'; | |
v.value = ''; | |
u.appendChild(x); | |
u.appendChild(s); | |
u.appendChild(t); | |
u.appendChild(w); | |
w.add(v); | |
for (var y in i[e]['options']) { | |
var z = document.createElement('option'); | |
z.value = i[e]['options'][y]['name']; | |
z.text = i[e]['options'][y]['name']; | |
w.add(z); | |
} | |
c.appendChild(u); | |
break; | |
} | |
} | |
var j = document.createElement('div'); | |
var k = document.createElement('button'); | |
j.className = 'qm-actions'; | |
k.type = 'submit'; | |
k.id = 'qm-submit'; | |
k.innerText = 'Submit'; | |
k.onclick = function() { postForm(c); return false; } | |
j.appendChild(k); | |
c.appendChild(j); | |
b.appendChild(c); | |
a.appendChild(b); | |
showModal(); | |
}, function(err) { | |
a.removeChild(al); | |
var b = document.createElement('div'); | |
b.id = 'qm-modal-inner'; | |
b.style.zIndex = '10001'; | |
b.style.margin = '30px auto'; | |
b.style.top = '30px'; | |
b.style.position = 'relative'; | |
b.style.background = '#fff'; | |
b.style.width = '600px'; | |
b.style.padding = '10px 20px'; | |
b.style.border = '5px solid #999'; | |
b.style.borderRadius = '10px'; | |
b.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)'; | |
b.innerHTML = '<h2>Uh Oh. There seems to be a problem!</h2><p>'+err+'</p>'; | |
a.appendChild(b); | |
setTimeout(function(){ | |
a.remove(); | |
},2000) | |
}); | |
} | |
function showModal() { | |
document.getElementById('qm-ajax-loader').remove(); | |
var a = document.getElementById('qm-modal'); | |
var b = a.childNodes[0]; | |
if (b.style.display == 'none') { | |
b.style.display = 'block'; | |
} | |
} | |
var json_product = {"id":231950045,"title":"test","handle":"test","description":"blah blah blah","published_at":"2014-02-03T21:55:00-05:00","created_at":"2014-02-03T23:55:37-05:00","vendor":"david","type":"test2","tags":["rfq"],"price":0,"price_min":0,"price_max":3400,"available":true,"price_varies":true,"compare_at_price":null,"compare_at_price_min":0,"compare_at_price_max":0,"compare_at_price_varies":false,"variants":[{"id":872978185,"title":"quiet / v2 / large","options":["quiet","v2","large"],"option1":"quiet","option2":"v2","option3":"large","price":1200,"weight":0,"compare_at_price":null,"inventory_quantity":1,"inventory_management":null,"inventory_policy":"deny","available":true,"sku":"","requires_shipping":true,"taxable":true,"barcode":"","featured_image":null},{"id":523889853,"title":"sexy / Default Title / small","options":["sexy","Default Title","small"],"option1":"sexy","option2":"Default Title","option3":"small","price":0,"weight":0,"compare_at_price":null,"inventory_quantity":1,"inventory_management":null,"inventory_policy":"deny","available":true,"sku":"","requires_shipping":false,"taxable":false,"barcode":"","featured_image":null},{"id":872978621,"title":"stud / v34 / medium","options":["stud","v34","medium"],"option1":"stud","option2":"v34","option3":"medium","price":3400,"weight":0,"compare_at_price":null,"inventory_quantity":1,"inventory_management":null,"inventory_policy":"deny","available":true,"sku":"","requires_shipping":true,"taxable":true,"barcode":"","featured_image":null},{"id":875766609,"title":"say / bleh / big","options":["say","bleh","big"],"option1":"say","option2":"bleh","option3":"big","price":0,"weight":0,"compare_at_price":null,"inventory_quantity":1,"inventory_management":null,"inventory_policy":"deny","available":true,"sku":"","requires_shipping":true,"taxable":true,"barcode":"","featured_image":null}],"images":[],"featured_image":null,"options":["monogram","name","size"],"content":"blah blah blah"} | |
document.getElementById('product-add-wrap').innerHTML='<div id="product-add-medallion" class=""></div><input type="submit" name="quote" id="quote" value="Quote" class="smooth">'; | |
document.getElementById('quote').onclick = function() { renderForm('http://boopis.lvh.me:3000/',2,json_product); return false; } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated script for new data structure and refactor a bit.