I am a complete beginner in JS, please help me. How can I create and populate a similar array in JS? Not through const should be done obviously?
const questions = [
{
questionText: 'What is the capital of France?',
answerOptions: [
{ answerText: 'New York', isCorrect: false },
{ answerText: 'London', isCorrect: false },
{ answerText: 'Paris', isCorrect: true },
{ answerText: 'Dublin', isCorrect: false },
],
},
{
questionText: 'Who is CEO of Tesla?',
answerOptions: [
{ answerText: 'Jeff Bezos', isCorrect: false },
{ answerText: 'Elon Musk', isCorrect: true },
{ answerText: 'Bill Gates', isCorrect: false },
{ answerText: 'Tony Stark', isCorrect: false },
],
}
];
Here you go buddy. Make sure you get the questions and answers in the right json format. and console.log them a few times to check how you can access the data inside the json. Once that is clear you can use these classes and the for loops below to get what you want.
Those who have a problem with this answer let me know in the comments.
Edited: I MADE THE NECESSARY CHANGES. You can add a plus button to add more options
class Question {
constructor(question, answers) {
this.question = question;
this.answers = answers;
}
}
class Answer {
constructor(answer, isCorrect) {
this.answer = answer;
this.isCorrect = isCorrect;
}
}
function GetData() {
var question = document.querySelector('#question').value;
var options = document.querySelectorAll('.option');
var checkboxes = document.querySelectorAll('.checkbox');
var result = [];
var answerslist = [];
for (var j = 0; j < options.length; j++) {
const A = new Answer(options[j].value, checkboxes[j].checked)
answerslist.push(A);
}
const Q = new Question(question, answerslist);
result.push(Q);
console.log(result);
}
body {
box-sizing: border-box;
overflow-x: hidden;
font-size: 62.5%;
padding: 5rem;
}
.Inputarea {
width: 70%;
margin: auto;
height: auto;
background-color: gainsboro;
padding: 2rem;
}
input[type="text"] {
width: 60%;
margin: 1rem auto;
border-radius: 0.3rem;
border: none;
}
input[type="text"] :focus {
border: 2px solid mediumpurple;
}
input::placeholder {
color: mediumpurple;
}
button {
width: 30%;
margin: 1rem 15%;
background-color: white;
font-size: 1rem;
color: blueviolet;
border-radius: 0.5rem;
padding: 0.5rem;
font-weight: bolder;
border: none;
}
button:hover {
background-color: blueviolet;
color: white;
transition: all 0.3s ease-in;
}
input[type="checkbox"] {
margin: 1rem 3rem;
}
<div class="Inputarea">
<input id="question" type="text" placeholder="Enter Question">
<input class="option" type="text" placeholder="Enter Option1">
<input class="checkbox" type="checkbox">
<input class="option" type="text" placeholder="Enter Option2">
<input class="checkbox" type="checkbox">
<input class="option" type="text" placeholder="Enter Option3">
<input class="checkbox" type="checkbox">
<input class="option" type="text" placeholder="Enter Option4">
<input class="checkbox" type="checkbox">
<button onclick="return GetData();">Submit</button>
</div>
Related
Hi I'm trying to do the following in javascript, basically, I have an input that I will get the input text from an array, and I need each option to have an object as a value so I can use some attributes of my object
const data = [
{
name: "SIMPLES NACIONAL – MEI",
funcionarioIncrease: 49.99,
socioIncrease: 0,
FATURAMENTO: [
{
name: "ATÉ 30.000,00",
value: 49.99,
},
{
name: "De 30.001,00 a 50.000,00 ",
value: 99.99,
},
],
},
{
name: "SIMPLES NACIONAL – SERVIÇOS",
funcionarioIncrease: 25,
socioIncrease: 25,
FATURAMENTO: [
{
name: "ATÉ 30.000,00",
value: 149.99,
},
{
name: "De 30.001,00 a 50.000,00 ",
value: 199.99,
},
],
},
];
const Modes = () => {
if (data instanceof Array) {
return data.map((value) => {
return {
name: value.name,
funcionarioIncrease: value.funcionarioIncrease,
socioIncrease: value.socioIncrease,
faturamento: value.FATURAMENTO,
};
});
} else {
return null;
}
};
let results = function () {
const modes = Modes();
let selectHeader = document.querySelectorAll(".select__header");
let selectItem = document.querySelectorAll(".select__item");
modes.map((value) => {
let element = document.createElement("div");
element.classList.add("select__item");
element.innerHTML(value.name);
});
selectHeader.forEach((item) => {
item.addEventListener("click", selectToggle);
});
selectItem.forEach((item) => {
item.addEventListener("click", selectChoose);
});
function selectToggle() {
this.parentElement.classList.toggle("is-active");
}
function selectChoose() {
let text = this.innerText,
select = this.closest(".select"),
currentText = select.querySelector(".select__current");
currentText.innerText = text;
select.classList.remove("is-active");
}
};
results();
.select {
position: relative;
width: 100%;
}
.select.is-active .select__body {
display: block;
}
.select__header {
border: 1px solid #ccc;
cursor: pointer;
display: flex;
}
.select__current {
font-size: 18px;
line-height: 24px;
padding: 8px;
}
.select__icon {
align-items: center;
display: flex;
flex-shrink: 0;
justify-content: center;
height: 40px;
margin-left: auto;
text-align: center;
width: 40px;
}
.select__body {
border: 1px solid #cccccc;
border-top: 0;
display: none;
left: 0;
position: absolute;
right: 0;
top: 100%;
}
.select__item {
cursor: pointer;
font-size: 16px;
line-height: 24px;
padding: 8px;
}
.select__item:hover {
background-color: #f2f2f2;
}
<div class="service_mode flex">
<div class="select is-active">
<div class="select__header">
<span class="select__current">Value 1</span>
<div class="select__icon">×</div>
</div>
<div class="select__body"></div>
</div>
</div>
for some reason, I am not able to map my array and add its inner HTML as the attribute name of my object and I am also not finding a way to link the option to that object.
As it says element.innerHTML is not a function. Instead of element.innerHTML(value.name);, write element.innerHTML = value.name;
So your code looks like:
modes.map((value) => {
let element = document.createElement("div");
element.classList.add("select__item");
element.innerHTML = value.name;
});
Try this below:
element.innerHTML = value.name;
I have made some quizzes in javascript. When my users click the complete button at the end of the quiz I then want to make the box on the home page have a green outline around it so they know they have completed that quiz. The complete button is on the challenge1.html page and the item I want to put the outline round is the item in the grid on home.html. Would anyone be able to give me some advice on how to do this?
Files: home.html, challenge1.html, home.css, challenge1.css and quiz.js
home.html
<div class="grid-container">
<div class="grid-item item1">1. Discover HTML Basics and Tags</div>
<div class="grid-item item2">2. Styling HTML with Tags</div>
<div>3. Creating Links and Images</div>
<div class="grid-item item4">4. Building Features</div>
<div class="grid-item item5">5. Building Lists</div>
</div>
challenge1.html
<div class="container">
<div id="question-container" class="hide">
<div id="question">Question</div>
<div id="answer-buttons" class="btn-grid">
<button class="btn">Answer 1</button>
<button class="btn">Answer 2</button>
<button class="btn">Answer 3</button>
<button class="btn">Answer 4</button>
</div>
</div>
<div class="controls">
<button id="start-btn" class="start-btn btn">Start</button>
<button id="next-btn" class="next-btn btn hide">Next</button>
<button id="complete-btn" class="complete-btn btn hide">Complete</button>
</div>
</div>
home.css
.grid-container {
display: grid;
margin-top: 30px;
grid-gap: 10px;
background-color: #FFFFFF;
padding: 10px;
}
.grid-container3 {
display: grid;
margin-top: 30px;
grid-gap: 10px;
background-color: #FFFFFF;
padding: 10px;
margin-bottom: 100px;
}
.grid-item {
background-color: #E26CBA;
padding: 20px;
font-size: 20px;
border-radius: 20px;
font-family: 'Poppins', sans-serif;
color: #3F0068;
}
.item3 {
grid-column: 1 / span 2;
grid-row: 2;
}
challenge.css
*, *::before, *::after {
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
:root {
--hue-neutral: 200;
--hue-wrong: 0;
--hue-correct: 145;
}
body {
--hue: var(--hue-neutral);
padding: 0;
margin: 0;
display: flex;
width: 100vw;
height: 100vh;
justify-content: center;
align-items: center;
background-color: hsl(var(--hue), 0%, 100%);
}
body.correct {
--hue: var(--hue-correct);
}
body.wrong {
--hue: var(--hue-wrong);
}
.container {
width: 800px;
max-width: 80%;
background-color: white;
border-radius: 5px;
padding: 10px;
box-shadow: 0 0 10px 2px;
}
.btn-grid {
display: grid;
grid-template-columns: repeat(2, auto);
padding: 10px;
margin: 20px 0;
}
.btn {
--hue: var(--hue-neutral);
border: 1px solid hsl(var(--hue), 100%, 20%);
background-color: hsl(var(--hue), 84%, 73%);
border-radius: 5px;
padding: 10px 10px;
margin:10px;
color: white;
outline: none;
}
.btn:hover {
border-color: black;
}
.btn.correct {
--hue: var(--hue-correct);
color: black;
}
.btn.wrong {
--hue: var(--hue-wrong);
}
.start-btn, .next-btn {
font-size: 1.5rem;
font-weight: bold;
padding: 10px 20px;
}
.complete-btn {
font-size: 1.5rem;
font-weight: bold;
padding: 10px 20px;
--hue: var(--hue-correct);
}
.controls {
display: flex;
justify-content: center;
align-items: center;
}
.hide {
display: none;
}
quiz.JS
$(document).ready(function() {
const startButton = document.getElementById('start-btn')
const nextButton = document.getElementById('next-btn')
const completeButton = document.getElementById('complete-btn')
const questionContainerElement = document.getElementById('question-container')
const questionElement = document.getElementById('question')
const answerButtonsElement = document.getElementById('answer-buttons')
let shuffledQuestions, currentQuestionIndex
startButton.addEventListener('click', startGame)
nextButton.addEventListener('click', () => {
currentQuestionIndex++
setNextQuestion()
})
function startGame() {
startButton.classList.add('hide')
shuffledQuestions = questions.sort(() => Math.random() - .5)
currentQuestionIndex = 0
questionContainerElement.classList.remove('hide')
setNextQuestion()
}
function setNextQuestion() {
resetState()
showQuestion(shuffledQuestions[currentQuestionIndex])
}
function showQuestion(question) {
questionElement.innerText = question.question
question.answers.forEach(answer => {
const button = document.createElement('button')
button.innerText = answer.text
button.classList.add('btn')
if (answer.correct) {
button.dataset.correct = answer.correct
}
button.addEventListener('click', selectAnswer)
answerButtonsElement.appendChild(button)
})
}
function resetState() {
clearStatusClass(document.body)
nextButton.classList.add('hide')
while (answerButtonsElement.firstChild) {
answerButtonsElement.removeChild(answerButtonsElement.firstChild)
}
}
function selectAnswer(e) {
const selectedButton = e.target
const correct = selectedButton.dataset.correct
setStatusClass(document.body, correct)
Array.from(answerButtonsElement.children).forEach(button => {
setStatusClass(button, button.dataset.correct)
})
if (shuffledQuestions.length > currentQuestionIndex + 1) {
nextButton.classList.remove('hide')
} else {
completeButton.innerText = 'Complete'
completeButton.classList.remove('hide')
}
}
function setStatusClass(element, correct) {
clearStatusClass(element)
if (correct) {
element.classList.add('correct')
} else {
element.classList.add('wrong')
}
}
function clearStatusClass(element) {
element.classList.remove('correct')
element.classList.remove('wrong')
}
const questions = [
{
question: 'What does HTML stand for?',
answers: [
{ text: 'Hyperlinks and Text Markup Language', correct: true },
{ text: 'Hyper Text Markup Language', correct: false },
{ text: 'Home Tool Markup Language', correct: false }
]
},
{
question: 'Which character is used to indicate an end tag?',
answers: [
{ text: '<', correct: false },
{ text: '*', correct: false },
{ text: '/', correct: true },
{ text: ';', correct: false }
]
},
{
question: 'Who is making the Web standards?',
answers: [
{ text: 'Google', correct: false },
{ text: 'Mozilla', correct: false },
{ text: 'Microsoft', correct: false },
{ text: 'The World Wide Web Consortium', correct: true }
]
},
{
question: 'What is the correct HTML for making a text input field?',
answers: [
{ text: '<input type="textfield">', correct: false },
{ text: '<input type="text">', correct: true },
{ text: '<textfield>', correct: false },
{ text: '<textinput type="text">', correct: false }
]
},
{
question: 'Choose the correct HTML element for the largest heading:',
answers: [
{ text: '<head>', correct: false },
{ text: '<h6>', correct: false },
{ text: '<heading>', correct: false },
{ text: '<h1>', correct: true }
]
}
]
});
As Steve mentioned in the comment above, sessionStorage (or localStorage) might be what you need. For instance, when the user completes the quiz, you can trigger the following action:
window.sessionStorage.setItem("challengeCompleted", "true")
Then, in your home.html page, you add something like:
let challengeCompleted = window.sessionStorage.getItem("challengeCompleted")
if (challengeCompleted !== null && Boolean(challengeCompleted)):
// Handle your css change here
let btn = document.getElementById("your-btn-id");
btn.style["border-color"] = "green";
Something along these lines. I didn't check the code and just wrote it quickly from memory so could have a mistake, but this is the idea.
Lastly, use localStorage if you want the webpage to always remember the user's performance and sessionStorage if performance resets every time the user comes into the website again.
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 working with form validation. My code is working fine but whenever I click on send button validations showing multiple time. And here I want to add radio button, checkbox, select according to my code. How should I add these other fields? I tried my level best but couldn't achieve it.
Can anyone help me to add this to other fields?
Below is my code:
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.",
},
message: {
reg: /^(?!\s*$).+/,
error: "Message field cannot be empty.",
},
};
var handleError = function(element, message) {
element.addClass('input-error');
var $err_msg = element.parent('div');
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
})
})
<style type="text/css">
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;
}
</style>
<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="name">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="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>
</form>
Please check this codepen:
https://codepen.io/creativedev/pen/BVNXYE
I have added this line
$err_msg.find('.error').remove();
Updated code:
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.",
},
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
})
})
<script>
jQuery(function()
{
jQuery("#test").validate({
rules:
{
"firstname":
{
required: true
},
"lastname":
{
required: true
},
"email":
{
required: true
},
"message":
{
required: true
}
}
});
});
whenever I click on send button validations showing multiple time
$err_msg.empty(); /* add this cleanup old errors */
error.appendTo($err_msg);
I need help on the following code, I created a back button in my Javascript Quiz, but if I click on it, it goes back but does not remember the choices i chose thereby forcing me to choose a new answer. I don't know how to go about this. Below is the Javascript Link:
http://jsbin.com/zinagipovo/edit?html,css,js,console
var currentQuestion = 0;
var score = 0;
var totQuestions = questions.length;
var container = document.getElementById('quizContainer');
var questionEl = document.getElementById('question');
var opt1 = document.getElementById('opt1');
var opt2 = document.getElementById('opt2');
var opt3 = document.getElementById('opt3');
var opt4 = document.getElementById('opt4');
var backButton = document.getElementById('backButton');
var nextButton = document.getElementById('nextButton');
var resultCont = document.getElementById('result');
function loadQuestion (questionIndex) {
var q = questions[questionIndex];
questionEl.textContent = (questionIndex + 1) + '. ' +q.question;
opt1.textContent = q.option1;
opt2.textContent = q.option2;
opt3.textContent = q.option3;
opt4.textContent = q.option4;
};
function loadNextQuestion () {
var selectedOption =
document.querySelector('input[type=radio]:checked');
if(!selectedOption){
alert('Please select your answer!');
return;
}
var answer = selectedOption.value;
if(questions[currentQuestion].answer == answer){
score +=1;
}
selectedOption.checked = false;
currentQuestion++;
if(currentQuestion == totQuestions - 1){
nextButton.textContent = 'Finish';
}
if (currentQuestion == totQuestions){
resultCont.style.display = '';
resultCont.textContent = 'You got ' + score +' questions correct';
return false;
currentQuestion = 0;
}
loadQuestion(currentQuestion);
}
function loadPrevQuestion () {
if (currentQuestion > 0) {
currentQuestion--;
loadQuestion(currentQuestion);
}
}
loadQuestion(currentQuestion);
The questions are in an external file
var questions = [{
"question": "How many long vowels do we have in English Language?",
"option1": "10",
"option2": "5",
"option3": "6",
"option4": "7",
"answer": "2"
}, {
"question": "How many short vowels do we have in English Language?",
"option1": "6",
"option2": "5",
"option3": "12",
"option4": "7",
"answer": "4"
}, {
"question": "How many Vowels do we have in English Language?",
"option1": "20",
"option2": "24",
"option3": "8",
"option4": "12",
"answer": "1"
}, {
"question":"Which of these is not a Vowel Sound?",
"option1": "/θ/",
"option2": "/əʊ/",
"option3": "/i:/",
"option4": "/u:/",
"answer": "1"
},
]
The HTML Code goes thus:
<div>
<button id="quiz" onclick="document.getElementById('quizContainer').style.display='block'" style="width:auto; margin-top: 15px;">Take the Quiz!!</button>
<div id="quizContainer" class="modal">
<span onclick="document.getElementById('quizContainer').style.display='none'" class="close" title="Close Quiz">×</span>
<header class="title">Vowel Sounds</header>
<div id="question" class="question"></div>
<label class="option"><input type="radio" name="option" value="1" /> <span id="opt1"></span></label>
<label class="option"><input type="radio" name="option" value="2" /> <span id="opt2"></span></label>
<label class="option"><input type="radio" name="option" value="3" /> <span id="opt3"></span></label>
<label class="option"><input type="radio" name="option" value="4" /> <span id="opt4"></span></label>
<button id="nextButton" class="next-btn" onclick="loadNextQuestion();">Next</button>
<button id="backButton" class="back-btn" onclick="loadPrevQuestion();">Back</button>
<div id="result" class="container result" style="display:none;"></div>
</div>
</div>
<script>
// Get the modal
var modal = document.getElementById('quizContainer');
</script>
The CSS code is:
.modal { display: none; background-color: #fefefe; height: 387px; width: 100%; position: fixed; z-index: 1; overflow: auto; padding-top: 100px; margin-top: 100px; top: 50%; left: 50%; transform: translateX(-50%) translateY(-50%); padding: 20px; border: 1px solid #08038C; box-shadow: 0 0 8px 3px #fff; }
.title { padding-top: 20px; text-align: center; font-size: 40px; text-transform: uppercase; color: #08038c; }
.question { padding: 20px; font-size: 22px; background: #08038c; border-radius: 20px; margin: 10px 0 10px 0; color: #f6f6f6; }
.option{ width: 450px; display: inline-block; padding: 10px 0 10px 15px; vertical-align: middle; background: #08038c; margin: 10px 0 10px 10px; color: white; border-radius: 20px; }
.option:hover{ background: #08038c; color: #f6f6f6;}
.next-btn, .back-btn { border: 2px solid #08038c; outline: none; background: rgba(255,255,255, 0.5); width: 150px; height: 35px; cursor: pointer; float: right; margin: 10px; }
.next-btn:hover, .back-btn:hover { background: #08038c; color: #f6f6f6; }
.result { height: 20px; text-align: center; font-size: 20px; }
.option input:checked .option{ background: #08038c; color: #000; }
.close { position: absolute; right: 35px; top: 15px; color: #000; font-size: 40px; font-weight: bold; }
#quiz { background-color: #4CAF50; color: white; padding: 14px 20px; margin: 8px 0; border: none; cursor: pointer; width: 100%; }
.back-btn { float:left;}
.close:hover, .close:focus { color: red; cursor: pointer; }
You have a typo in the jsbin's JavaScript. You define totQuestions before you define questions. If you move it to after your program at least runs.
The general idea should be to store the answers and calculate the total at the end. You can simply create another array, answers, and in loadNextQuestion, set answers[currentQuestion] = answer instead of your if/score += 1 block. You can add similar functionality to loadPrevQuestion. Then in loadQuestion, you would set checked of the option corresponding to answers[currentQuestion]. Finally, instead of the score variable, you'd calculate it at the end, such as by a reduction.
Here's a jsbin doing the above, though it's using ES6 and instead of an answers array I melded it into questions and made the options dynamic.