I have a classic message form, which does not need a function to sent a messages. She created only for analyzing all input fields on content, and if the input fields are clear - script must show the tooltips info for the customer.
The problem is when I click on the button with pre-written fields, content in the fields are gone.
var fromWho = document.querySelector('[name="from"]');
var pass = document.querySelector('[name="pass"]');
var repeatPass = document.querySelector('[name="repeatPass"]');
var message = document.querySelector('[name="message"]');
var button = document.querySelector('button');
function onClick(e) {
if (fromWho.value = '') {
var helpFrom = document.createElement('span');
helpFrom.innerHTML = 'Please, insert sender data!';
helpFrom.style.color = 'red';
};
if (pass.value = '') {
var helpPass = document.createElement('span');
helpPass.innerHTML = 'Please, insert password!';
helpPass.style.color = 'red';
};
if (repeatPass.value != pass.value) {
var helpRepeatPass = document.createElement('span');
helpRepeatPass.innerHTML = 'Passwords do not match!';
helpRepeatPass.style.color = 'red';
};
if (message.value = '') {
var helpMessage = document.createElement('span');
helpMessage.innerHTML = 'Wrie your message!';
helpMessage.style.color = 'red';
};
console.log(fromWho.value);
}
button.addEventListener( 'click', onClick );
body {
font-family: 'Arial', sans-serif;
font-size: 12px;
}
p {
display: inline-block;
margin: 0 0 5px 0;
}
input, select {
float: right;
}
input[type="button"] {
float: left;
}
textarea {
width: 288px;
height: 114px;
margin: 0px;
resize: vertical;
}
.message-wrap {
width: 294px;
height: auto;
}
.message-wrap__from {
margin-bottom: 5px;
height: 22px;
}
.message-wrap__password {
margin-bottom: 5px;
height: 22px;
}
.message-wrap__repeatPassword {
margin-bottom: 5px;
height: 22px;
}
.message-wrap__toWhom {
margin-bottom: 5px;
height: 22px;
}
.message-wrap__message {
margin-bottom: 5px;
}
.message-wrap__message > p {
display: block;
}
.toWhom__select {
width: 160.5px;
height: 22px;
}
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style>
</style>
</head>
<body>
<div class="message-wrap">
<div class="message-wrap__from">
<p>From</p>
<input type="text" name="from">
</div>
<div class="message-wrap__password">
<p>Your password</p>
<input type="password" name="pass">
</div>
<div class="message-wrap__repeatPassword">
<p>Repeate password</p>
<input type="password" name="repeatPass">
</div>
<div class="message-wrap__toWhom">
<p>To</p>
<select class="toWhom__select">
<option value="1">Logistic sector</option>
<option value="2">Financial sector</option>
<option value="3">Director</option>
</select>
</div>
<div class="message-wrap__message">
<p>Message:</p>
<textarea name="message" name="message"></textarea>
</div>
<button>Check</button>
</div>
<script>
</script>
</body>
</html>
if conditions need to be checked with a == or a ===. = will give a new value to the variable and this explains the behaviour.
if (fromWho.value == '') {
var helpFrom = document.createElement('span');
helpFrom.innerHTML = 'Please, insert sender data!';
helpFrom.style.color = 'red';
};
...
your example:
var fromWho = document.querySelector('[name="from"]');
var pass = document.querySelector('[name="pass"]');
var repeatPass = document.querySelector('[name="repeatPass"]');
var message = document.querySelector('[name="message"]');
var button = document.querySelector('button');
function onClick(e) {
if (fromWho.value == '') {
var helpFrom = document.createElement('span');
helpFrom.innerHTML = 'Please, insert sender data!';
helpFrom.style.color = 'red';
};
if (pass.value == '') {
var helpPass = document.createElement('span');
helpPass.innerHTML = 'Please, insert password!';
helpPass.style.color = 'red';
};
if (repeatPass.value != pass.value) {
var helpRepeatPass = document.createElement('span');
helpRepeatPass.innerHTML = 'Passwords do not match!';
helpRepeatPass.style.color = 'red';
};
if (message.value == '') {
var helpMessage = document.createElement('span');
helpMessage.innerHTML = 'Wrie your message!';
helpMessage.style.color = 'red';
};
console.log(fromWho.value);
}
button.addEventListener( 'click', onClick );
body {
font-family: 'Arial', sans-serif;
font-size: 12px;
}
p {
display: inline-block;
margin: 0 0 5px 0;
}
input, select {
float: right;
}
input[type="button"] {
float: left;
}
textarea {
width: 288px;
height: 114px;
margin: 0px;
resize: vertical;
}
.message-wrap {
width: 294px;
height: auto;
}
.message-wrap__from {
margin-bottom: 5px;
height: 22px;
}
.message-wrap__password {
margin-bottom: 5px;
height: 22px;
}
.message-wrap__repeatPassword {
margin-bottom: 5px;
height: 22px;
}
.message-wrap__toWhom {
margin-bottom: 5px;
height: 22px;
}
.message-wrap__message {
margin-bottom: 5px;
}
.message-wrap__message > p {
display: block;
}
.toWhom__select {
width: 160.5px;
height: 22px;
}
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style>
</style>
</head>
<body>
<div class="message-wrap">
<div class="message-wrap__from">
<p>From</p>
<input type="text" name="from">
</div>
<div class="message-wrap__password">
<p>Your password</p>
<input type="password" name="pass">
</div>
<div class="message-wrap__repeatPassword">
<p>Repeate password</p>
<input type="password" name="repeatPass">
</div>
<div class="message-wrap__toWhom">
<p>To</p>
<select class="toWhom__select">
<option value="1">Logistic sector</option>
<option value="2">Financial sector</option>
<option value="3">Director</option>
</select>
</div>
<div class="message-wrap__message">
<p>Message:</p>
<textarea name="message" name="message"></textarea>
</div>
<button>Check</button>
</div>
<script>
</script>
</body>
</html>
Related
I saved all dom-elements in an object. I want that my Script is able to check every time when there is some input if all input fields are empty anymore. If yes, the button should still be disabled, otherwise the forward button is enabled and the user can click to the next page.
Ways like like using querySelectorAll input field etc. are working but I want that this is working with using the object.
The "areTruthy" variable is directly true if one input field is not empty anymore but it should only be true if all input fields are true. Where is my code wrong?
window.onload = () => {
forward = document.getElementById("forward");
input = {
caseNumber: {
month: document.getElementById("month"),
year: document.getElementById("year"),
},
clientsInformation: {
gender: document.getElementById("gender"),
inpName: document.getElementById("inpName"),
},
adress: {
street: document.getElementById("street"),
houseNumber: document.getElementById("house-number"),
postCode: document.getElementById("postCode"),
city: document.getElementById("city"),
receiver: document.getElementById("receiver"),
},
};
addEventListener("input", () => {
for (parts in input) {
const areTruthy = Object.values(input[parts]).every((value) => value != "");
if (areTruthy) {
forward.style.backgroundColor = "rgb(77,55,120)";
forward.style.color = "white";
forward.disabled = false;
forward.style.transition = "1s ease";
forward.addEventListener("click", () => {
window.open("case.html");
});
} else {
forward.style.backgroundColor = "rgb(191,191,191)";
forward.style.color = "black";
forward.disabled = true;
}
}
});
};
<body>
<h3>Fill in all fields</h3>
<div id = "wrapper">
<div id = "caseNumber">
<label id = "caseLabel"></label>
<input id = "month" placeholder="Zahlenfolge">
<input id = "year" placeholder = "Jahr">
</div>
<div id = "name">
<label for = "name">Name</label>
<select id = "gender">
<option>Herr</option>
<option>Frau</option>
</select>
<input id = "inpName" placeholder = "Name">
</div>
<div id = "adress">
<label for = "adress">Adresse</label>
<div id = "adressWrapper1">
<input placeholder = "Straße" id = "street" >
<input placeholder = "Hausnummer" id = "house-number">
<input placeholder = "Postleitzahl" id = "postCode" >
</div>
<div id = "adressWrapper2">
<input placeholder = "Stadt" id = "city" >
<input placeholder = "Adressant" id = "receiver" >
</div>
</div>
</div>
</div>
<div class = "button-bar">
<div class = "nav-inner" id = "backward"><a class = "nav-inner" href= "#http://127.0.0.1:5500/pages/client.html" ></a> < Zurück</div>
<div class = "nav-inner" id = "forward"> Weiter ></div>
</div>
</body>
</html>
.navbar {
display: flex;
list-style: none;
background-color: rgb(77, 55, 120);
margin: 0;
position: fixed;
width: 100%;
gap: 4rem;
height: 50px;
text-align: center;
line-height: 45px;
left: 0;
top: 0;
}
.nav-text {
text-decoration: none;
color: white;
width: auto;
cursor: pointer;
font-size: 18px;
padding-bottom: 5px;
}
#wrapper {
margin-top: 10rem;
margin-left: 5rem;
display: sticky;
}
#caseNumber {
display: block;
}
input::placeholder {
font-size: 1rem;
text-align: center;
line-height: 19rem;
}
.button-bar {
position: fixed;
bottom: 0;
width: 100%;
display: flex;
margin: 0;
left: 0;
}
.nav-inner {
cursor: pointer;
width: 50%;
text-align: center;
line-height: 83px;
}
#backward {
background-color: rgb(101, 93, 93);
color: white;
}
#forward {
background-color: rgb(191, 191, 191);
}
h3 {
left: 20vh;
position: absolute;
font-size: 24px;
margin-top: 0.5rem;
}
#caseNumber {
position: absolute;
left: 20vh;
margin-top: 6.5rem;
text-align: left;
}
#name {
position: absolute;
left: 20vh;
margin-top: 12.5rem;
}
label {
display: inline-block;
text-align: left;
width: 140px;
font-size: 20px;
}
input,
select {
width: 30vh;
height: 5vh;
font-size: 19px;
border-radius: 5px;
border-style: solid;
border: 1px solid;
}
#adress {
position: absolute;
left: 20vh;
margin-top: 18.5rem;
max-width: 40rem;
display: block;
}
#adressWrapper1 {
display: flex;
gap:5vh;
flex-direction: column;
left: 18vh;
position: absolute;
top:0rem
}
#adressWrapper2 {
display: flex;
gap:5vh;
flex-direction: column;
position: absolute;
left: 50vh;
top:0rem
}
You are not checking input values. Also you are only checking every on child per parent object key, not on all children together so you need to lift if outside for
addEventListener("input", () => {
let allFilled = true;
for (parts in input) {
const anyEmpty = Object.values(input[parts]).some(el => el.value == "");
if (anyEmpty) {
allFilled = false;
break;
}
}
if (allFilled) {
forward.style.backgroundColor = "rgb(77,55,120)";
forward.style.color = "white";
forward.disabled = false;
forward.style.transition = "1s ease";
forward.addEventListener("click", () => {
window.open("case.html");
});
} else {
forward.style.backgroundColor = "rgb(191,191,191)";
forward.style.color = "black";
forward.disabled = true;
}
});
};
If you want to see what is exactly happening you can use this to log
const anyEmpty = Object.values(input[parts]).some((el) => {
console.log(el, el.value, el.value == "");
return el.value == "";
});
I want to Generate and Download Screenshot of webpage without lossing the styles. I have a web page .In that web page i have a download button . When user click on download button then the screen shot of entire Page need to download as image in user computer . How can i do this ?
Please check my code
Index.html
<html>
<body>
<link href="style.css" rel="stylesheet">
<h1>Scrrenshot</h1>
<form class="cf">
<div class="half left cf">
<input type="text" id="input-name" placeholder="Name">
<input type="email" id="input-email" placeholder="Email address">
<input type="text" id="input-subject" placeholder="Subject">
</div>
<div class="half right cf">
<textarea name="message" type="text" id="input-message" placeholder="Message"></textarea>
</div>
<input type="submit" value="Submit" id="input-submit">
</form>
<a class="btn btn-success" href="javascript:void(0);" onclick="generate();">Generate Screenshot »</a>
</body>
<script>
(function (exports) {
function urlsToAbsolute(nodeList) {
if (!nodeList.length) {
return [];
}
var attrName = 'href';
if (nodeList[0].__proto__ === HTMLImageElement.prototype
|| nodeList[0].__proto__ === HTMLScriptElement.prototype) {
attrName = 'src';
}
nodeList = [].map.call(nodeList, function (el, i) {
var attr = el.getAttribute(attrName);
if (!attr) {
return;
}
var absURL = /^(https?|data):/i.test(attr);
if (absURL) {
return el;
} else {
return el;
}
});
return nodeList;
}
function screenshotPage() {
urlsToAbsolute(document.images);
urlsToAbsolute(document.querySelectorAll("link[rel='stylesheet']"));
var screenshot = document.documentElement.cloneNode(true);
var b = document.createElement('base');
b.href = document.location.protocol + '//' + location.host;
var head = screenshot.querySelector('head');
head.insertBefore(b, head.firstChild);
screenshot.style.pointerEvents = 'none';
screenshot.style.overflow = 'hidden';
screenshot.style.webkitUserSelect = 'none';
screenshot.style.mozUserSelect = 'none';
screenshot.style.msUserSelect = 'none';
screenshot.style.oUserSelect = 'none';
screenshot.style.userSelect = 'none';
screenshot.dataset.scrollX = window.scrollX;
screenshot.dataset.scrollY = window.scrollY;
var script = document.createElement('script');
script.textContent = '(' + addOnPageLoad_.toString() + ')();';
screenshot.querySelector('body').appendChild(script);
var blob = new Blob([screenshot.outerHTML], {
type: 'text/html'
});
return blob;
}
function addOnPageLoad_() {
window.addEventListener('DOMContentLoaded', function (e) {
var scrollX = document.documentElement.dataset.scrollX || 0;
var scrollY = document.documentElement.dataset.scrollY || 0;
window.scrollTo(scrollX, scrollY);
});
}
function generate() {
window.URL = window.URL || window.webkitURL;
window.open(window.URL.createObjectURL(screenshotPage()));
}
exports.screenshotPage = screenshotPage;
exports.generate = generate;
})(window);
</script>
</html>
style.css
#import "compass/css3";
#import url(https://fonts.googleapis.com/css?family=Merriweather);
$red: #e74c3c;
*,
*:before,
*:after {
#include box-sizing(border-box);
}
html, body {
background: #f1f1f1;
font-family: 'Merriweather', sans-serif;
padding: 1em;
}
h1 {
text-align: center;
color: #a8a8a8;
#include text-shadow(1px 1px 0 rgba(white, 1));
}
form {
border: 2px solid blue;
margin: 20px auto;
max-width: 600px;
padding: 5px;
text-align: center;
}
input, textarea {
border:0; outline:0;
padding: 1em;
#include border-radius(8px);
display: block;
width: 100%;
margin-top: 1em;
font-family: 'Merriweather', sans-serif;
#include box-shadow(0 1px 1px rgba(black, 0.1));
resize: none;
&:focus {
#include box-shadow(0 0px 2px rgba($red, 1)!important);
}
}
#input-submit {
color: white;
background: $red;
cursor: pointer;
&:hover {
#include box-shadow(0 1px 1px 1px rgba(#aaa, 0.6));
}
}
textarea {
height: 126px;
}
}
.half {
float: left;
width: 48%;
margin-bottom: 1em;
}
.right { width: 50%; }
.left {
margin-right: 2%;
}
#media (max-width: 480px) {
.half {
width: 100%;
float: none;
margin-bottom: 0;
}
}
/* Clearfix */
.cf:before,
.cf:after {
content: " "; /* 1 */
display: table; /* 2 */
}
.cf:after {
clear: both;
}
.half.left.cf > input {
margin: 5px;
}
For this i used the method [http://www.xpertdeveloper.com/2012/10/webpage-screenshot-with-html5-js/] , here screenshot is generated but without style also it is not downloading . Please help , is there any jQuery library available for this?
You can achieve this using the following JavaScript libraries ...
html2canvas ( for taking screenshot of webpage )
FileSave.js ( for downloading the screenshot as an image )
ᴅᴇᴍᴏ
(function(exports) {
function urlsToAbsolute(nodeList) {
if (!nodeList.length) {
return [];
}
var attrName = 'href';
if (nodeList[0].__proto__ === HTMLImageElement.prototype || nodeList[0].__proto__ === HTMLScriptElement.prototype) {
attrName = 'src';
}
nodeList = [].map.call(nodeList, function(el, i) {
var attr = el.getAttribute(attrName);
if (!attr) {
return;
}
var absURL = /^(https?|data):/i.test(attr);
if (absURL) {
return el;
} else {
return el;
}
});
return nodeList;
}
function screenshotPage() {
var wrapper = document.getElementById('wrapper');
html2canvas(wrapper, {
onrendered: function(canvas) {
canvas.toBlob(function(blob) {
saveAs(blob, 'myScreenshot.png');
});
}
});
}
function addOnPageLoad_() {
window.addEventListener('DOMContentLoaded', function(e) {
var scrollX = document.documentElement.dataset.scrollX || 0;
var scrollY = document.documentElement.dataset.scrollY || 0;
window.scrollTo(scrollX, scrollY);
});
}
function generate() {
screenshotPage();
}
exports.screenshotPage = screenshotPage;
exports.generate = generate;
})(window);
#import url(https://fonts.googleapis.com/css?family=Merriweather);
$red: #e74c3c;
*,
*:before,
*:after {
#include box-sizing(border-box);
}
html,
body {
background: #f1f1f1;
font-family: 'Merriweather', sans-serif;
padding: 1em;
}
h1 {
text-align: center;
color: #a8a8a8;
#include text-shadow(1px 1px 0 rgba(white, 1));
}
form {
border: 2px solid blue;
margin: 20px auto;
max-width: 600px;
padding: 5px;
text-align: center;
}
input,
textarea {
border: 0;
outline: 0;
padding: 1em;
#include border-radius(8px);
display: block;
width: 100%;
margin-top: 1em;
font-family: 'Merriweather', sans-serif;
#include box-shadow(0 1px 1px rgba(black, 0.1));
resize: none;
&:focus {
#include box-shadow(0 0px 2px rgba($red, 1)!important);
}
}
#input-submit {
color: white;
background: $red;
cursor: pointer;
&:hover {
#include box-shadow(0 1px 1px 1px rgba(#aaa, 0.6));
}
}
textarea {
height: 126px;
}
}
.half {
float: left;
width: 48%;
margin-bottom: 1em;
}
.right {
width: 50%;
}
.left {
margin-right: 2%;
}
#media (max-width: 480px) {
.half {
width: 100%;
float: none;
margin-bottom: 0;
}
}
/* Clearfix */
.cf:before,
.cf:after {
content: " ";
/* 1 */
display: table;
/* 2 */
}
.cf:after {
clear: both;
}
.half.left.cf > input {
margin: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<div id="wrapper">
<h1>Scrrenshot</h1>
<form class="cf">
<div class="half left cf">
<input type="text" id="input-name" placeholder="Name">
<input type="email" id="input-email" placeholder="Email address">
<input type="text" id="input-subject" placeholder="Subject">
</div>
<div class="half right cf">
<textarea name="message" type="text" id="input-message" placeholder="Message"></textarea>
</div>
<input type="submit" value="Submit" id="input-submit">
</form>
</div>
<a class="btn btn-success" href="javascript:void(0);" onclick="generate();">Generate Screenshot »</a>
I found that dom-to-image did a much better job than html2canvas. See the following question & answer: https://stackoverflow.com/a/32776834/207981
If you're looking to download the image(s) you'll want to combine it with FileSaver.js (already mentioned here), and if you want to download a zip with multiple image files all generated client-side take a look at jszip.
Few options for this
either use this
<html>
<head>
<title> Download-Button </title>
</head>
<body>
<p> Click the image ! You can download! </p>
<a download="logo.png" href="http://localhost/folder/img/logo.png" title="Logo title">
<img alt="logo" src="http://localhost/folder/img/logo.png">
</a>
</body>
</html>
or You can use Mordernizr
or maybe this works
<a href="/path/to/image" download>
<img src="/path/to/image" />
</a>
refer to this link aswell
[1] http://www.w3schools.com/tags/att_a_download.asp
Basically I got my css file which will be under the text but when i try to open the html file that uses it in the browser it doesn't work, the css code won't run and the styling and the javascript don't work because of that. The code is supposed to be like this one: https://codepen.io/ritaD86/pen/MyOdQr but it doesn't work in my browser while it works on the codepen.io. I also don't get it why the javascript doesn't work. What is going on? What can I do?
persons = [
person = {
firstName: "Maria",
lastName: "Fernanda",
age: "mf#desk.com",
phone: "917697967"
},
];
document.getElementById('search_button').addEventListener('click', searchPerson);
document.getElementById('add_button').addEventListener('click', addPerson);
document.getElementById('show_all').addEventListener('click', showAllPersons);
function searchPerson() {
var input = document.getElementById("search").value.toLowerCase();
var result = document.getElementById('result');
for (var i = 0; i < persons.length; i++) {
if (input === persons[i].firstName.toLowerCase() || input === persons[i].lastName.toLowerCase()) {
result.innerHTML = '<h4>I found this:</h4>' + persons[i].firstName + ' ' +
persons[i].lastName + ' </br>' + persons[i].age + ' </br>' + persons[i].phone;
return persons[i];
} else if (!isNaN(input)) {
result.innerHTML = 'Tem de inserir um nome';
} else {
result.innerHTML = 'Nenhum contacto encontrado';
}
}
}
function Person(first, last, age, phone) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.phone = phone;
}
function titleCase(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
function addPerson() {
var firstName = titleCase(document.getElementById("name").value);
var lastName = titleCase(document.getElementById("lastname").value);
var age = document.getElementById("age").value;
var phone = document.getElementById("phone").value;
var newPerson = new Person(firstName, lastName, age, phone);
persons.push(newPerson);
if (newPerson.firstName != undefined) {
alert(newPerson.firstName + ' added');
} else {
alert('No person added');
}
showAllPersons();
}
function showAllPersons() {
var i;
var l;
var showButton = document.getElementById('show_all');
var list = document.getElementById('all_list');
while (list.firstChild) {
list.removeChild(list.firstChild);
}
for (var l = 0; l < persons.length; l++) {
var node = document.createElement("LI");
list.appendChild(node);
node.innerHTML =
'<p><b>Nome Completo:</b> ' + persons[l].firstName +' ' + persons[l].lastName + '</p>' +
'<p><b>Email:</b> ' + persons[l].age + '</p>' +
'<p><b>Telemovel:</b> ' + persons[l].phone + '</p>'
for (var key in person) {
var value = person[key];
}
}
showButton.disabled = true;
}
#import "bourbon";
#import "neat";
// Media queries
$desktop: new-breakpoint(min-width 960px 12);
$tablet: new-breakpoint(max-width 959px 12);
$mobile: new-breakpoint(max-width 767px 4);
// Variables
$max-width: 1200px;
form {
padding: 20px 0 40px;
.field {
#include padding(10px 0);
#include margin(5px 0);
#include display(inline-block);
#include fill-parent;
label {
#include span-columns(5);
#include padding(5px 10px);
}
input {
#include span-columns(7);
#include padding(5px 10px);
}
}
}
.container {
#include outer-container;
text-align: center;
}
.search_person {
#include span-columns(6);
}
.add_person {
#include span-columns(6);
}
.all_persons {
#include span-columns(4);
#include shift(4);
#all_list {
list-style-type: none;
margin: 20px 0;
padding: 0;
li {
margin: 0 0 30px;
text-align: left;
}
}
}
<html>
<head>
<title>Desk+ - Grupo 36</title>
<link rel="stylesheet" type="text/css" href="ab.css">
<script src="ab.js"></script>
</head>
<body>
<div class="container">
<h1>Contactos</h1>
<div class="all_persons">
<button id="show_all" type="button">Mostrar todos</button>
<ul id="all_list">
</ul>
</div>
<div class="search_person">
<h3>Insira um nome</h3>
<input type="text" id="search">
<button id="search_button" type="button">Procurar</button>
<p id="result"></p>
</div>
<div class="add_person">
<h3>Adicionar contacto</h3>
<form action="" method="post">
<div class="field">
<label for="firstname">Primeiro Nome: </label>
<input type="text" id="name">
</div>
<div class="field">
<label for="lastname">Último Nome: </label>
<input type="text" id="lastname">
</div>
<div class="field">
<label for="age">Email: </label>
<input type="text" id="age">
</div>
<div class="field">
<label for="phone">Phone: </label>
<input type="number" id="phone">
</div>
<button id="add_button" type="button">Add</button>
</form>
</div>
</div>
</body>
</html>
Here is the compiled css->
html {
box-sizing: border-box;
}
*, *::after, *::before {
box-sizing: inherit;
}
form {
padding: 20px 0 40px;
}
form .field {
padding: 10px 0;
margin: 5px 0;
display: inline-block;
width: 100%;
}
form .field label {
float: left;
display: block;
margin-right: 2.3576520234%;
width: 40.291369653%;
padding: 5px 10px;
}
form .field label:last-child {
margin-right: 0;
}
form .field input {
float: left;
display: block;
margin-right: 2.3576520234%;
width: 57.3509783236%;
padding: 5px 10px;
}
form .field input:last-child {
margin-right: 0;
}
.container {
max-width: 1200px;
margin-left: auto;
margin-right: auto;
text-align: center;
}
.container::after {
clear: both;
content: "";
display: block;
}
.search_person {
float: left;
display: block;
margin-right: 2.3576520234%;
width: 48.8211739883%;
}
.search_person:last-child {
margin-right: 0;
}
.add_person {
float: left;
display: block;
margin-right: 2.3576520234%;
width: 48.8211739883%;
}
.add_person:last-child {
margin-right: 0;
}
.all_persons {
float: left;
display: block;
margin-right: 2.3576520234%;
width: 31.7615653177%;
margin-left: 34.1192173411%;
}
.all_persons:last-child {
margin-right: 0;
}
.all_persons #all_list {
list-style-type: none;
margin: 20px 0;
padding: 0;
}
.all_persons #all_list li {
margin: 0 0 30px;
text-align: left;
}
try this instead the css/scss you are using. It will work. cheers!
It is SCSS and not CSS. You need to convert it to CSS first for it to work. In addition to that, try to move your script to the end of the body tag instead of inside the head tag.
I'm working on form validation. Everything is working fine what I actually want is I want to add some more input fields like checkbox, radio button, select and textarea, upload file and like so into the form I want them to be validated as well.
I got the email input error working but it is not working correctly as it should validate the email first and then it should remove the error message but it is removing the error message just after entering few characters.
I want the phone number to be validated. Like the user should enter 10 numeric digits that is in India if in another country that will differ I am a bit confused how to do it.
I want a success message to pop up when all the fields are correctly validated as they should. what I tried is this:
$('.success_msg').fadeIn().delay(3000).fadeOut();
$('input , textarea , select').val('').removeClass('valid');
event.preventDefault();
I want all the fields to be cleared when all the validations are done and the success message is sent.
Can anyone point me in the right direction?
var Validator = function(formObject) {
this.form = $(formObject);
var Elements = {
name: {
reg: /^[a-zA-Z]{2,20}$/,
error: "Not a valid name.",
},
email: {
reg: /^[a-z-0-9_+.-]+\#([a-z0-9-]+\.)+[a-z0-9]{2,7}$/i,
error: "Not a valid e-mail address.",
},
phone: {
reg: /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/,
error: "Not a valid number.",
},
message: {
reg: /^(?!\s*$).+/,
error: "Message field cannot be empty.",
},
};
var handleError = function(element, message) {
element.addClass('input-error');
var $err_msg = element.parent('div');
$err_msg.find('.error').remove();
var error = $('<div class="error"></div>').text(message);
error.appendTo($err_msg);
element.keyup(function() {
$(error).fadeOut(1000, function() {
element.removeClass('input-error');
});
});
};
this.validate = function() {
var errorCount = 0;
this.form.find("input, textarea").each(function(index, field) {
var type = $(field).data("validation");
var validation = Elements[type];
if (validation) {
if (!validation.reg.test($(field).val())) {
errorCount++;
handleError($(field), validation.error);
}
}
})
return errorCount == 0;
};
};
$(function() {
$("form#test").on("submit", function(event) {
//event.preventDefault();
return new Validator(this).validate(); // "this" here refers to the form
})
})
body {
background: #fff;
color: #333;
font: 76% Verdana, sans-serif;
}
form {
margin: 1em 0 0 2em;
width: 90%;
}
fieldset {
margin: 0;
border: 1px solid #ccc;
padding-bottom: 1em;
}
legend {
font-weight: bold;
text-transform: uppercase;
}
label {
float: left;
width: 5em;
padding-right: 2em;
font-weight: bold;
}
div {
margin-bottom: 30px;
}
input {
font: 1em Verdana, sans-serif;
}
fieldset ul li input {
float: left;
width: 120px;
border: 1px solid #ccc;
}
textarea {
width: 300px;
height: 200px;
border: 1px solid #ccc;
font: 1em Verdana, sans-serif;
}
form p {
margin: 0;
padding: 0.4em 0 0 7em;
}
form p input {
background: #666;
color: #fff;
font-weight: bold;
}
div.error {
clear: left;
margin-left: 5.3em;
color: red;
padding-right: 1.3em;
height: 100%;
padding-bottom: 0.3em;
line-height: 1.3;
}
.input-error {
background: #ff9;
border: 1px solid red;
}
.success_msg {
width: 350px;
line-height: 40px;
border: 1px solid green;
border-radius: 5px;
background-color: rgba(213, 255, 187, 0.7);
display: none;
position: absolute;
bottom: 5px;
left: 50%;
transform: translateX(-50%);
z-index: 999;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" method="post" id="test">
<fieldset>
<legend>Contact information</legend>
<div>
<label for="firstname">Firstname:</label>
<input type="text" name="firstname" id="firstname" data-validation="name" />
</div>
<div>
<label for="lastname">Lastname:</label>
<input type="text" name="lastname" id="lastname" data-validation="name" />
</div>
<div>
<label for="email">Email:</label>
<input type="email" name="email" id="email" data-validation="email" />
</div>
<div>
<label for="phone">phone</label>
<input type="number" name="phone" id="phone" data-validation="phone" />
</div>
<div>
<label>Gender:</label>
<input type="radio" name="gender" value="male" data-validation="gender" />
<input type="radio" name="gender" value="female" data-validation="gender">
</div>
<div>
<label>select</label>
<input type="checkbox" name="checkbox" id="checkbox1" value="demo1" data-validation="checkbox" />
<input type="checkbox" name="checkbox" id="checkbox2" value="demo2" data-validation="checkbox" />
<input type="checkbox" name="checkbox" id="checkbox3" value="demo3" ata-validation="checkbox" />
</div>
<select data-validation="selectOption">
<option value="">Select any option</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
</select>
<div>
<label>Upload:</label>
<input type="file" name="file" id="file" data-validation="file" />
</div>
<div>
<label for="message">Message:</label>
<textarea id="message" name="message" cols="30" rows="15" data-validation="message"></textarea>
</div>
<p><input type="submit" name="send" id="send" value="Send" /></p>
</fieldset>
<div class="success_msg">
<p>Form submitted Successfully</p>
</div>
</form>
Please feel free to clear your doubts before you invest your time answering the question.
Here is the working code:
https://jsfiddle.net/bhumi/o2gxgz9r/47570/
I have changed selector to use id
You need to use loop in handle error:
var Validator = function(form) {
this.form = $(form);
var Elements = {
name: {
selector: $('input[type=text]'),
reg: /^[a-zA-Z]{2,20}$/
},
email: {
selector: $('input[type=email]'),
reg: /^[a-z-0-9_+.-]+\#([a-z0-9-]+\.)+[a-z0-9]{2,7}$/i
},
message: {
selector: $('textarea'),
reg: /^\s+$/
}
};
var handleError = function(element, message, v1) {
if (v1.selector.length > 1) {
var ss = v1.selector;
$(ss).each(function(i, v) {
$(v).removeClass('input-error');
if($(v).val() == ''){
$(v).addClass('input-error');
var $err_msg = $(v).parent('div');
if($(v).parent('div').find('.error').length == 0) {
var error = $('<div class="error"></div>').text(message);
}else{
$(v).parent('div').find('.error').text('');
var error = $(v).parent('div').find('.error').text(message);
$(this).siblings('.error').show();
}
error.appendTo($err_msg);
}else{
$(v).siblings('.error').text('')
}
$(v).keyup(function() {
$(error).fadeOut(1000, function() {
element.removeClass('input-error');
});
});
});
} else {
element.addClass('input-error');
var $err_msg = element.parent('div');
if(element.parent('div').find('.error').length == 0) {
var error = $('<div class="error"></div>').text(message);
}else{
element.parent('div').find('.error').text('');
var error = element.parent('div').find('.error').text(message);
$(this).siblings('.error').show();
}
error.appendTo($err_msg);
element.keyup(function() {
$(error).fadeOut(1000, function() {
element.removeClass('input-error');
});
});
}
};
this.validate = function() {
this.form.submit(function(e) {
for (var i in Elements) {
var type = i;
var validation = Elements[i];
switch (type) {
case 'name':
if (!validation.reg.test(validation.selector.val())) {
handleError(validation.selector, 'Not a valid name.', validation);
}
break;
case 'email':
if (!validation.reg.test(validation.selector.val())) {
handleError(validation.selector, 'Not a valid e-mail address.', validation);
}
break;
case 'message':
if (validation.reg.test(validation.selector.val()) || validation.selector.val() == '') {
handleError(validation.selector, 'Message field cannot be empty.', validation);
}
break;
default:
break;
}
}
e.preventDefault();
});
};
};
var validator = new Validator('#test');
validator.validate();
I hope this is what you were trying to achieve. This took longer than expected but I tried to achieve it. This whole form is custom form. You could have used the existing plugins to achieve it. Any which ways it took much time to figure it out. Consider the question as most of things are working, ignore if something's not what you want.
$(document).ready(function() {
/* contact form validation */
var Validator = function(formObject) {
this.form = $(formObject);
var Elements = {
name: {
reg: /^[a-zA-Z ]{2,20}$/,
require: true,
error: "Not a valid name.",
},
email: {
reg: /^[a-z-0-9_+.-]+\#([a-z0-9-]+\.)+[a-z0-9]{2,7}$/i,
error: "Not a valid e-mail address.",
},
phone: {
reg: /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/,
error: "Not a valid number.",
},
message: {
reg: /^(?!\s*$).+/,
error: "Message field cannot be empty.",
},
gender: {
error: "gender is required",
},
selectOption: {
error: "this field is required",
required: true
}
};
var handleError = function(element, message) {
element.addClass('input-error');
var $err_msg = element.parent('div');
$err_msg.find('.error').remove();
var error = $('<div class="error"></div>').text(message);
error.appendTo($err_msg);
console.log(element);
element.on('keypress change', function() {
$(error).fadeOut(1000, function() {
console.log(element);
element.removeClass('input-error');
});
});
};
/* Select Option */
this.validate = function() {
var errorCount = 0;
this.form.find("select").each(function(index, field) {
var type = $(field).data("validation");
var validation = Elements[type];
if ($(field).val() == "") {
errorCount++;
handleError($(field), validation.error);
}
});
this.form.find("input, textarea").each(function(index, field) {
var type = $(field).data("validation");
var validation = Elements[type];
if (validation !== undefined) {
var re = new RegExp(validation.reg);
if (validation) {
if (!re.test($(field).val())) {
errorCount++;
handleError($(field), validation.error);
}
}
}
})
/* Radio button */
var radioList = $('input:radio');
var radioNameList = new Array();
var radioUniqueNameList = new Array();
var notCompleted = 0;
for (var i = 0; i < radioList.length; i++) {
radioNameList.push(radioList[i].name);
}
radioUniqueNameList = jQuery.unique(radioNameList);
console.log(radioUniqueNameList);
for (var i = 0; i < radioUniqueNameList.length; i++) {
var field = $('#' + radioUniqueNameList[i]);
var type = field.data("validation");
var validation = Elements[type];
if ($('input[name=' + type + ']:checked', '#test').val() == undefined) {
errorCount++;
handleError($(field), validation.error);
}
}
return errorCount == 0;
};
};
/* Submit form*/
$(function() {
$("form#test").on('submit', function(e) {
var NoErrors = new Validator(this).validate();
if (NoErrors == true) {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function() {
// AJAX request finished, handle the results and error msg
$('.success_msg').fadeIn().delay(3000).fadeOut();
$('input[type!="submit"], textarea').val('').removeClass('error');
}
});
}
return false;
})
})
});
body {
background: #fff;
color: #333;
font: 76% Verdana, sans-serif;
}
form {
margin: 1em 0 0 2em;
width: 90%;
}
fieldset {
margin: 0;
border: 1px solid #ccc;
padding-bottom: 1em;
}
legend {
font-weight: bold;
text-transform: uppercase;
}
label {
float: left;
width: 5em;
padding-right: 2em;
font-weight: bold;
}
div {
margin-bottom: 30px;
}
input {
font: 1em Verdana, sans-serif;
}
fieldset ul li input {
float: left;
width: 120px;
border: 1px solid #ccc;
}
textarea {
width: 300px;
height: 200px;
border: 1px solid #ccc;
font: 1em Verdana, sans-serif;
}
form p {
margin: 0;
padding: 0.4em 0 0 7em;
}
form p input {
background: #666;
color: #fff;
font-weight: bold;
}
div.error {
clear: left;
margin-left: 5.3em;
color: red;
padding-right: 1.3em;
height: 100%;
padding-bottom: 0.3em;
line-height: 1.3;
}
.input-error {
background: #ff9;
border: 1px solid red;
}
.success_msg {
width: 350px;
line-height: 40px;
border: 1px solid green;
border-radius: 5px;
background-color: rgba(213, 255, 187, 0.7);
display: none;
position: absolute;
bottom: 5px;
left: 50%;
transform: translateX(-50%);
z-index: 999;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<form action="#" method="post" id="test">
<fieldset>
<legend>Contact information</legend>
<div>
<label for="firstname">Firstname:</label>
<input type="text" name="firstname" id="firstname" data-validation="name" />
</div>
<div>
<label for="lastname">Lastname:</label>
<input type="text" name="lastname" id="lastname" data-validation="name" />
</div>
<div>
<label for="email">Email:</label>
<input type="email" name="email" id="email" data-validation="email" />
</div>
<div>
<label for="phone">phone</label>
<input type="number" name="phone" id="phone" data-validation="phone" />
</div>
<div>
<label>Gender:</label>
<input type="radio" name="gender" value="male" data-validation="gender" />
<input type="radio" name="gender" value="female" data-validation="gender">
</div>
<select data-validation="selectOption">
<option value="">Select any option</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
</select>
<div>
<label for="message">Message:</label>
<textarea id="message" name="message" cols="30" rows="15" data-validation="message"></textarea>
</div>
<p><input type="submit" name="send" id="send" value="Send" /></p>
</fieldset>
<div class="success_msg">
<p>Form submitted Successfully</p>
</div>
</form>
I'm attempting to make a remove button for my dynamically created input boxes, however I can't seem to get it to work. I get the feeling its because the "child" didn't exist upon initially loading the script, but I'm not sure.
Any help would be appreciated. Thanks.
var addButton = document.getElementById("add-button");
var removeButton = document.getElementById("remove-button");
var incomeSection = document.getElementById("income");
var incomeRow = document.getElementById("income-row");
var itemCounter = 2
incomeSection.addEventListener("click", activateItem);
function activateItem(e) {
if (e.target.id == "add-button") {
incomeSection.innerHTML += '<div id="income-row"><input class="input" type="text" name="income-type-1" placeholder="Income source ' + itemCounter + '"><span class="currency">£</span><input class="input income-amount" type="text" name="income-amount-1" placeholder="Amount"><input id="remove-button" class="button" type="button" value="-"></div>';
itemCounter++;
}
if (e.target.id == "remove-button") {
incomeSection.removeChild(incomeRow);
}
}
html body {
background-color: #c9c9c9;
font-family: 'Montserrat', sans-serif;
color: #686868;
}
#income {
padding: 10px;
}
.input {
padding: 8px;
font-size: 14px;
margin-right: 10px;
margin-bottom: 5px;
width: 30%;
}
.button {
width: 25px;
height: 25px;
}
.currency {
padding: 10px;
font-size: 14px;
margin-right: -4px;
margin-bottom: 5px;
background-color: darkgray;
color: white;
}
<div id="income">
<div id="income-displayed">
<h2>Income: <span></span></h2>
</div>
<div id="income-row">
<input class="input" type="text" name="income-type-1" placeholder="Income source">
<span class="currency">£</span>
<input class="input income-amount" type="text" name="income-amount-1" placeholder="Amount">
<input id="add-button" class="button" type="button" value="+">
</div>
</div>
Just replace the following line it will resolved your issue :-
incomeSection.removeChild(incomeRow);
with the following
e.target.parentNode.remove();
var addButton = document.getElementById("add-button");
var removeButton = document.getElementById("remove-button");
var incomeSection = document.getElementById("income");
var incomeRow = document.getElementById("income-row");
var itemCounter = 2
incomeSection.addEventListener("click", activateItem);
function activateItem(e) {
if (e.target.id == "add-button") {
incomeSection.innerHTML += '<div id="income-row"><input class="input" type="text" name="income-type-1" placeholder="Income source '+itemCounter+'"><span class="currency">£</span><input class="input income-amount" type="text" name="income-amount-1" placeholder="Amount"><input id="remove-button" class="button" type="button" value="-"></div>'; itemCounter ++;
}
if (e.target.id == "remove-button") {
e.target.parentNode.remove();
}
}
html body {
background-color: #c9c9c9;
font-family: 'Montserrat', sans-serif;
color: #686868;
}
#income {
padding: 10px;
}
.input {
padding: 8px;
font-size: 14px;
margin-right: 10px;
margin-bottom: 5px;
width: 30%;
}
.button {
width: 25px;
height: 25px;
}
.currency {
padding: 10px;
font-size: 14px;
margin-right: -4px;
margin-bottom: 5px;
background-color: darkgray;
color: white;
}
<div id="income">
<div id="income-displayed"><h2>Income: <span></span></h2></div>
<div id="income-row">
<input class="input" type="text" name="income-type-1" placeholder="Income source"><span class="currency">£</span><input class="input income-amount" type="text" name="income-amount-1" placeholder="Amount"><input id="add-button" class="button" type="button" value="+"></div>
</div>
This Snippet demonstrates how to add and remove elements to and from the DOM utilizing:
cloneNode
.children
parentNode
Further details are commented in the source
SNIPPET
// #incFormA element will bind with eventListener
var form = document.getElementById("incFormA");
// #setA will contain the #dupes
var set = document.getElementById("setA");
// Reference to clone template #dupe
var dupe = document.getElementById('dupe');
// Increment counter that will ensure unique ids
var cntr = 0;
// If any part of the form is clicked call actDeact
form.addEventListener("click", actDeact);
/*
| actDeact()
| -If the clicked button's id === addA
| then clone #dupe and add an id (#dupe+cntr)
| -Iterate through it's children
| and assign unique ids and names to
| the 1st and 3rd children of (#dupe+cntr)
| -Append #dupe+cntr to #setA
*/
/*
| -If the clicked button was a .remA
| find it's parentNode and remove it.
*/
function actDeact(e) {
cntr++;
if (e.target.id === 'addA') {
var clone = dupe.cloneNode(true);
clone.id = 'dupe' + cntr;
var i;
var grp = clone.children;
var qty = grp.length;
for (i = 0; i < qty; i++) {
switch (i) {
case 0:
grp[0].id = 'inc' + cntr;
grp[0].name = 'inc' + cntr;
break;
case 2:
grp[2].id = 'amt' + cntr;
grp[2].name = 'amt' + cntr;
break;
default:
break;
}
}
setA.appendChild(clone);
} else if (e.target.className === "remA") {
var clone = e.target.parentNode;
setA.removeChild(clone);
} else return false;
}
html body {
background-color: #c9c9c9;
font-family: 'Montserrat', sans-serif;
color: #686868;
}
#setA {
padding: 10px;
}
/* The clone template is out of the way
| yet still accessible for cloning.
*/
#dupe {
display: none;
}
.input {
padding: 8px;
font-size: 14px;
margin-right: 10px;
margin-bottom: 5px;
width: 30%;
}
button {
width: 25px;
height: 25px;
float: right;
}
.currency {
padding: 10px;
font-size: 14px;
margin-right: -4px;
margin-bottom: 5px;
background-color: darkgray;
color: white;
}
/*
| This ruleset is for positioning #addA
*/
.block {
position: relative;
display: block;
min-height: 100%;
width: 20%;
left: 80%;
bottom: 15px;
}
<!--Use <form> to post collect and send data*-->
<form id='incFormA' name='incFormA'>
<fieldset id="setA">
<legend class="display">
<!--Use <output> to calculate and display data*-->
<h2>Income: <output id='outA'></output></h2>
</legend>
<div class='block'>
<!--One add <button>-->
<button id="addA" type='button'>+</button>
</div>
<!--#dupe is the group of elements kept as a clone template-->
<span id='dupe'>
<input id='inc' class="input" name="inc" type="text" placeholder="Income source">
<span class="currency">£</span>
<input id="amt" class="input" name="amt" type="text" placeholder="Amount">
<button class="remA">-</button>
</span>
</fieldset>
</form>
<!--*Choice of elements optional-->