From 42364c13370150b30fb25cb7b4f1abb050bee89f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilja=20Karta=C5=A1ov?= Date: Fri, 26 Apr 2019 14:58:07 +0200 Subject: [PATCH] Add feedback form sending --- contact/index.html | 17 +- static/main.js | 582 +++++++++++++++++++++++++++------------------ 2 files changed, 353 insertions(+), 246 deletions(-) diff --git a/contact/index.html b/contact/index.html index 0dd9ab9..9baccfc 100644 --- a/contact/index.html +++ b/contact/index.html @@ -1,5 +1,5 @@ - + @@ -75,20 +75,21 @@
-
-
- - + +
+ +
diff --git a/static/main.js b/static/main.js index 4bffd36..e892ea7 100644 --- a/static/main.js +++ b/static/main.js @@ -1,8 +1,8 @@ 'use strict'; -// jStuff +// JStuff -function jStuff(query) +function JStuff(query) { this.nodes = null; @@ -33,6 +33,11 @@ function jStuff(query) return this; }; + this.onSubmit = function(handler) { + this.all(function(n, f) {n.addEventListener('submit', f, false)}, handler); + return this; + }; + this.addClass = function(className) { this.all(function(node, cn) { if (node.classList) @@ -77,20 +82,22 @@ function jStuff(query) } }, className); } + + this.value = function(value) { + return this.all(function(node, value) { + if (node.value) { + if (value) + node.value = value; + return node.value; + } + return null; + }, value); + } } -jStuff.create = function(tagName, childNode) { - var n = document.createElement(tagName); - if (childNode) - n.appendChild(childNode); - return new jStuff(n); -} +window.$ = function(q){return new JStuff(q)}; -jStuff.createLabel = function(text) { - return new jStuff(document.createTextNode(text)); -} - -jStuff.main = function(func) { +window.$.main = function(func) { if (window.addEventListener) { addEventListener("load", func, false); } else if (window.attachEvent) { @@ -100,7 +107,105 @@ jStuff.main = function(func) { } } -window.$ = jStuff; +$.create = function(tagName, childNode) { + var n = document.createElement(tagName); + if (childNode) + n.appendChild(childNode); + return new JStuff(n); +} + +$.createLabel = function(text) { + return new JStuff(document.createTextNode(text)); +} + +// AJAX + +function JStuffAjax(attr) { + var GET = 'GET', + POST = 'POST', + t = this, + query = '', + method, + r; + + try { + method = (attr.method == POST) ? POST : GET; + } catch(e) { + method = GET; + } + + this.onReadyStateChange = function() { + if (this.request.readyState == 4) { + if (this.request.status === 200) { + if (typeof (this.attr.load) !== 'undefined') { + this.attr.load(this.request.status, this.request.responseText); + } + } + return true; + } + return false + } + + try { + r = new XMLHttpRequest(); + } catch(e) { + var iev=[ + "MSXML2.XmlHttp.5.0", + "MSXML2.XmlHttp.4.0", + "MSXML2.XmlHttp.3.0", + "MSXML2.XmlHttp.2.0", + "Microsoft.XmlHttp" + ]; + + for(var i = 0; i < iev.length; i++) { + try { + r = new ActiveXObject(iev[i]); + break; + } catch(e){ + // do nothing + } + } + } + + if (typeof (attr.data) !== 'undefined') { + for (var key in attr.data) { + if (query != '') + query += '&'; + query += encodeURIComponent(key)+'='+encodeURIComponent(attr.data[key]); + } + + if (method == GET) { + attr.url += '?'+query; + query = null; + } + } + + if (typeof (attr.sync) === 'undefined') { + attr.sync = true; + } + + r.overrideMimeType("text/plain"); + r.open(method, attr.url, attr.sync); + r.setRequestHeader("Content-type","application/x-www-form-urlencoded"); + r.onreadystatechange = function() {t.onReadyStateChange()}; + + r.send(query); + + this.request = r; + this.attr = attr; +} + +$.ajax = function(attr) {return new JStuffAjax(attr)}; + +$.log = function(msg, ex) { + if (console.log) { + if (ex) { + msg += ' E('+ex.message+')'; + } + console.log(msg); + } +}; + // SVG fix @@ -110,293 +215,294 @@ window.$ = jStuff; var LEGACY_SUPPORT = false; function embed(parent, svg, target) { - // if the target exists - if (target) { - // create a document fragment to hold the contents of the target - var fragment = document.createDocumentFragment(); + // if the target exists + if (target) { + // create a document fragment to hold the contents of the target + var fragment = document.createDocumentFragment(); - // cache the closest matching viewBox - var viewBox = !svg.hasAttribute('viewBox') && target.getAttribute('viewBox'); + // cache the closest matching viewBox + var viewBox = !svg.hasAttribute('viewBox') && target.getAttribute('viewBox'); - // conditionally set the viewBox on the svg - if (viewBox) { - svg.setAttribute('viewBox', viewBox); - } + // conditionally set the viewBox on the svg + if (viewBox) { + svg.setAttribute('viewBox', viewBox); + } - // clone the target - var clone = target.cloneNode(true); + // clone the target + var clone = target.cloneNode(true); - // copy the contents of the clone into the fragment - while (clone.childNodes.length) { - fragment.appendChild(clone.firstChild); - } + // copy the contents of the clone into the fragment + while (clone.childNodes.length) { + fragment.appendChild(clone.firstChild); + } - // append the fragment into the svg - parent.appendChild(fragment); - } + // append the fragment into the svg + parent.appendChild(fragment); + } } function loadreadystatechange(xhr) { - // listen to changes in the request - xhr.onreadystatechange = function () { - // if the request is ready - if (xhr.readyState === 4) { - // get the cached html document - var cachedDocument = xhr._cachedDocument; + // listen to changes in the request + xhr.onreadystatechange = function () { + // if the request is ready + if (xhr.readyState === 4) { + // get the cached html document + var cachedDocument = xhr._cachedDocument; - // ensure the cached html document based on the xhr response - if (!cachedDocument) { - cachedDocument = xhr._cachedDocument = document.implementation.createHTMLDocument(''); + // ensure the cached html document based on the xhr response + if (!cachedDocument) { + cachedDocument = xhr._cachedDocument = document.implementation.createHTMLDocument(''); - cachedDocument.body.innerHTML = xhr.responseText; + cachedDocument.body.innerHTML = xhr.responseText; - // ensure domains are the same, otherwise we'll have issues appending the - // element in IE 11 - // cachedDocument.domain = document.domain; + // ensure domains are the same, otherwise we'll have issues appending the + // element in IE 11 + // cachedDocument.domain = document.domain; - xhr._cachedTarget = {}; - } + xhr._cachedTarget = {}; + } - // clear the xhr embeds list and embed each item - xhr._embeds.splice(0).map(function (item) { - // get the cached target - var target = xhr._cachedTarget[item.id]; + // clear the xhr embeds list and embed each item + xhr._embeds.splice(0).map(function (item) { + // get the cached target + var target = xhr._cachedTarget[item.id]; - // ensure the cached target - if (!target) { - target = xhr._cachedTarget[item.id] = cachedDocument.getElementById(item.id); - } + // ensure the cached target + if (!target) { + target = xhr._cachedTarget[item.id] = cachedDocument.getElementById(item.id); + } - // embed the target into the svg - embed(item.parent, item.svg, target); - }); - } - }; + // embed the target into the svg + embed(item.parent, item.svg, target); + }); + } + }; - // test the ready state change immediately - xhr.onreadystatechange(); + // test the ready state change immediately + xhr.onreadystatechange(); } function svg4everybody(rawopts) { - var opts = Object(rawopts); + var opts = Object(rawopts); - // create legacy support variables - var nosvg; - var fallback; + // create legacy support variables + var nosvg; + var fallback; - // if running with legacy support - if (LEGACY_SUPPORT) { - // configure the fallback method - fallback = opts.fallback || function (src) { - return src.replace(/\?[^#]+/, '').replace('#', '.').replace(/^\./, '') + '.png' + (/\?[^#]+/.exec(src) || [''])[0]; - }; + // if running with legacy support + if (LEGACY_SUPPORT) { + // configure the fallback method + fallback = opts.fallback || function (src) { + return src.replace(/\?[^#]+/, '').replace('#', '.').replace(/^\./, '') + '.png' + (/\?[^#]+/.exec(src) || [''])[0]; + }; - // set whether to shiv and elements and use image fallbacks - nosvg = 'nosvg' in opts ? opts.nosvg : /\bMSIE [1-8]\b/.test(navigator.userAgent); + // set whether to shiv and elements and use image fallbacks + nosvg = 'nosvg' in opts ? opts.nosvg : /\bMSIE [1-8]\b/.test(navigator.userAgent); - // conditionally shiv and - if (nosvg) { - document.createElement('svg'); - document.createElement('use'); - } - } + // conditionally shiv and + if (nosvg) { + document.createElement('svg'); + document.createElement('use'); + } + } - // set whether the polyfill will be activated or not - var polyfill; - var olderIEUA = /\bMSIE [1-8]\.0\b/; - var newerIEUA = /\bTrident\/[567]\b|\bMSIE (?:9|10)\.0\b/; - var webkitUA = /\bAppleWebKit\/(\d+)\b/; - var olderEdgeUA = /\bEdge\/12\.(\d+)\b/; - var edgeUA = /\bEdge\/.(\d+)\b/; - //Checks whether iframed - var inIframe = window.top !== window.self; + // set whether the polyfill will be activated or not + var polyfill; + var olderIEUA = /\bMSIE [1-8]\.0\b/; + var newerIEUA = /\bTrident\/[567]\b|\bMSIE (?:9|10)\.0\b/; + var webkitUA = /\bAppleWebKit\/(\d+)\b/; + var olderEdgeUA = /\bEdge\/12\.(\d+)\b/; + var edgeUA = /\bEdge\/.(\d+)\b/; + //Checks whether iframed + var inIframe = window.top !== window.self; - if ('polyfill' in opts) { - polyfill = opts.polyfill; - } else if (LEGACY_SUPPORT) { - polyfill = olderIEUA.test(navigator.userAgent) || newerIEUA.test(navigator.userAgent) || (navigator.userAgent.match(olderEdgeUA) || [])[1] < 10547 || (navigator.userAgent.match(webkitUA) || [])[1] < 537 || edgeUA.test(navigator.userAgent) && inIframe; - } else { - polyfill = newerIEUA.test(navigator.userAgent) || (navigator.userAgent.match(olderEdgeUA) || [])[1] < 10547 || (navigator.userAgent.match(webkitUA) || [])[1] < 537 || edgeUA.test(navigator.userAgent) && inIframe; - } + if ('polyfill' in opts) { + polyfill = opts.polyfill; + } else if (LEGACY_SUPPORT) { + polyfill = olderIEUA.test(navigator.userAgent) || newerIEUA.test(navigator.userAgent) || (navigator.userAgent.match(olderEdgeUA) || [])[1] < 10547 || (navigator.userAgent.match(webkitUA) || [])[1] < 537 || edgeUA.test(navigator.userAgent) && inIframe; + } else { + polyfill = newerIEUA.test(navigator.userAgent) || (navigator.userAgent.match(olderEdgeUA) || [])[1] < 10547 || (navigator.userAgent.match(webkitUA) || [])[1] < 537 || edgeUA.test(navigator.userAgent) && inIframe; + } - // create xhr requests object - var requests = {}; + // create xhr requests object + var requests = {}; - // use request animation frame or a timeout to search the dom for svgs - var requestAnimationFrame = window.requestAnimationFrame || setTimeout; + // use request animation frame or a timeout to search the dom for svgs + var requestAnimationFrame = window.requestAnimationFrame || setTimeout; - // get a live collection of use elements on the page - var uses = document.getElementsByTagName('use'); - var numberOfSvgUseElementsToBypass = 0; + // get a live collection of use elements on the page + var uses = document.getElementsByTagName('use'); + var numberOfSvgUseElementsToBypass = 0; - function oninterval() { - // get the cached index - var index = 0; + function oninterval() { + // get the cached index + var index = 0; - // while the index exists in the live collection - while (index < uses.length) { - // get the current - var use = uses[index]; + // while the index exists in the live collection + while (index < uses.length) { + // get the current + var use = uses[index]; - // get the current - var parent = use.parentNode; - var svg = getSVGAncestor(parent); - var src = use.getAttribute('xlink:href') || use.getAttribute('href'); + // get the current + var parent = use.parentNode; + var svg = getSVGAncestor(parent); + var src = use.getAttribute('xlink:href') || use.getAttribute('href'); - if (!src && opts.attributeName) { - src = use.getAttribute(opts.attributeName); - } + if (!src && opts.attributeName) { + src = use.getAttribute(opts.attributeName); + } - if (svg && src) { + if (svg && src) { - // if running with legacy support - if (LEGACY_SUPPORT && nosvg) { - // create a new fallback image - var img = document.createElement('img'); + // if running with legacy support + if (LEGACY_SUPPORT && nosvg) { + // create a new fallback image + var img = document.createElement('img'); - // force display in older IE - img.style.cssText = 'display:inline-block;height:100%;width:100%'; + // force display in older IE + img.style.cssText = 'display:inline-block;height:100%;width:100%'; - // set the fallback size using the svg size - img.setAttribute('width', svg.getAttribute('width') || svg.clientWidth); - img.setAttribute('height', svg.getAttribute('height') || svg.clientHeight); + // set the fallback size using the svg size + img.setAttribute('width', svg.getAttribute('width') || svg.clientWidth); + img.setAttribute('height', svg.getAttribute('height') || svg.clientHeight); - // set the fallback src - img.src = fallback(src, svg, use); + // set the fallback src + img.src = fallback(src, svg, use); - // replace the with the fallback image - parent.replaceChild(img, use); - } else if (polyfill) { - if (!opts.validate || opts.validate(src, svg, use)) { - // remove the element - parent.removeChild(use); + // replace the with the fallback image + parent.replaceChild(img, use); + } else if (polyfill) { + if (!opts.validate || opts.validate(src, svg, use)) { + // remove the element + parent.removeChild(use); - // parse the src and get the url and id - var srcSplit = src.split('#'); - var url = srcSplit.shift(); - var id = srcSplit.join('#'); + // parse the src and get the url and id + var srcSplit = src.split('#'); + var url = srcSplit.shift(); + var id = srcSplit.join('#'); - // if the link is external - if (url.length) { - // get the cached xhr request - var xhr = requests[url]; + // if the link is external + if (url.length) { + // get the cached xhr request + var xhr = requests[url]; - // ensure the xhr request exists - if (!xhr) { - xhr = requests[url] = new XMLHttpRequest(); + // ensure the xhr request exists + if (!xhr) { + xhr = requests[url] = new XMLHttpRequest(); - xhr.open('GET', url); + xhr.open('GET', url); - xhr.send(); + xhr.send(); - xhr._embeds = []; - } + xhr._embeds = []; + } - // add the svg and id as an item to the xhr embeds list - xhr._embeds.push({ - parent: parent, - svg: svg, - id: id - }); + // add the svg and id as an item to the xhr embeds list + xhr._embeds.push({ + parent: parent, + svg: svg, + id: id + }); - // prepare the xhr ready state change event - loadreadystatechange(xhr); - } else { - // embed the local id into the svg - embed(parent, svg, document.getElementById(id)); - } - } else { - // increase the index when the previous value was not "valid" - ++index; - ++numberOfSvgUseElementsToBypass; - } - } - } else { - // increase the index when the previous value was not "valid" - ++index; - } - } + // prepare the xhr ready state change event + loadreadystatechange(xhr); + } else { + // embed the local id into the svg + embed(parent, svg, document.getElementById(id)); + } + } else { + // increase the index when the previous value was not "valid" + ++index; + ++numberOfSvgUseElementsToBypass; + } + } + } else { + // increase the index when the previous value was not "valid" + ++index; + } + } - // continue the interval - if (!uses.length || uses.length - numberOfSvgUseElementsToBypass > 0) { - requestAnimationFrame(oninterval, 67); - } - } + // continue the interval + if (!uses.length || uses.length - numberOfSvgUseElementsToBypass > 0) { + requestAnimationFrame(oninterval, 67); + } + } - // conditionally start the interval if the polyfill is active - if (polyfill) { - oninterval(); - } + // conditionally start the interval if the polyfill is active + if (polyfill) { + oninterval(); + } } function getSVGAncestor(node) { - var svg = node; - while (svg.nodeName.toLowerCase() !== 'svg') { - svg = svg.parentNode; - if (!svg) { - break; - } - } - return svg; + var svg = node; + while (svg.nodeName.toLowerCase() !== 'svg') { + svg = svg.parentNode; + if (!svg) { + break; + } + } + return svg; } +// Core +var gCore = { + mod: null +}; + +// Contact + +function Contact() +{ + var t = this; + + this.email = $('#feedback__email'); + this.msg = $('#feedback__msg'); + + this.onLoad = function(httpStatus, content) { + if (httpStatus == 200) { + this.email.value(''); + this.msg.value(''); + $.log('Success!'); + alert("Thank you for your message!"); + } else { + alert("Your message was not sent!"); + $.log('server response: '+httpStatus); + } + }; + + this.onSubmit = function(evt) { + $.ajax({ + url: '/hook/feedback/', + handler: function(httpStatus, content) {t.onLoad(httpStatus, content)}, + data: {email: this.email.value(), msg: this.msg.value()}, + method: 'POST' + }); + event.preventDefault(); + return false; + } + + $('#feedback__form').onSubmit(function(evt) {return t.onSubmit(evt)}); +} + // Main -function main() -{ - /* - var inps = document.querySelectorAll('.float-label'); - - console.log('INputs: '+JSON.stringify(inps)); - - for (var i=0; i { - var t = event.currentTarget; - t.parentNode.classList.add('active'); - }); - - inp.addEventListener('blur', (event) => { - var t = event.currentTarget; - console.log(t.value) - if (t.value == '') - t.parentNode.classList.remove('active'); - }); - } - - window.addEventListener('scroll', (event) => { - - var nodes = document.querySelectorAll('.slider'), - scrollTop = window.scrollY; - - for(var i=0; i