So I wrote this multi-step form and it worked with the current code I have listed below until I changed it to send/receive data from php. The only thing that works is updating the progress bar but other then that it doesn't work. I have an idea why its not working cause of the actual button event isn't targeting the correct $(this).parent(); when I changed it from nextSection() to onSubmit(). I would possibly like to write it where it just selects the div class from an object then remove the current section but I wanna keep it the way I have for now.
$(".btn").on("click", nextSection);
function nextSection() {
if (typeof sections[current] !== "undefined") {
if(valid) {
current_section = $(this).parent();
next_section = $(this).parent().next();
console.log(current_section)
next_section.fadeIn();
current_section.remove();
current++;
updateProgressbar();
if (current === 1) {
let username = $(".username").val();
updatePenguinObj("username", username);
} else if (current === 2) {
let password = $(".password").val();
let email = $(".email").val();
updatePenguinObj("password", password);
updatePenguinObj("email", email);
} else if (current === 3) {
let name = $(".done");
name.text(name.text().replace(/%.+?%/, userData.username));
}
}
}
}
Then I changed it to the onSubmit() function w/ the validation responses.
$(".btn").on("click", onSubmit);
function onSubmit(event) {
event.preventDefault()
let request = new XMLHttpRequest()
request.onreadystatechange = () => handleResponse(request)
let formData = new FormData()
formData.append('username', userData.username);
formData.append('color', userData.colorId);
formData.append('password', userData.password);
formData.append('email', userData.email);
request.open('POST', 'scripts/php/create.php')
request.send(formData)
}
function handleResponse(request) {
if (request.readyState !== XMLHttpRequest.DONE || request.status !== 200) {
return
}
let response = JSON.parse(request.responseText);
if (!response) {
return
}
sectionValidation(response);
}
function sectionValidation(response) {
valid = true;
let section = $(sections[current]);
let input = section.find("input");
input.each(function() {
let inputs = $(this).attr('type') === "checkbox" ? !$(this).is(':checked') : input;
if(inputs) {
if (!response.valid) {
showError(response.message);
return valid = response.valid;
}
}
});
if(valid) {
nextSection(); //This is where nextSection is excuted to go to next page but doesnt.
}
}
I pastebin the entire code for each file type that way im not spamming this thread with just code. Overall i'm just trying to figure out how to fix it where I can go to the next section.
HTML - https://pastebin.com/eF8eXBfN
JS - https://pastebin.com/LuvYtYFc
PHP -
Basically just returns a JSON Object {message: "Test", valid: false} for the message responses and validation for it to go to next section.
if this isn't helpful I apologise in advance ....
because nextSection(); uses $(this) it won't have refrance to the button as it would have done when you used $(".btn").on("click", nextSection);
so you could add a reference of $(this) though to that function from the onSubmit
I create an example using your code, I dummy the response from the php but the rest is the same: https://jsfiddle.net/PatrickHume/8x6rodpn/
I don't know if this is better but it's another approach, I hope its helpful
let valid = true;
let sections = {
0: ".rules-section",
1: ".color-section",
2: ".info-section",
3: ".done-section"
};
let userData;
let current = 0,
current_section, next_section;
let currPalleteId = 0;
let penguinColors = {
"Blue": "003366",
"Green": "009900",
"Pink": "FF3399",
"Black": "333333",
"Red": "CC0000",
"Orange": "FF6600",
"Yellow": "FFCC00",
"Purple": "660099",
"Brown": "996600",
"Peach": "FF6666",
"Dark Green": "006600",
"Light Blue": "0099CC",
"Lime Green": "8AE302",
"Sensei Gray": "93A0A4",
"Aqua": "02A797",
"Arctic White": "F0F0D8",
};
window.onload = function() {
initalizeCreate();
};
function initalizeCreate() {
loadPalletes();
createPenguinObj();
$(".btn").on("click", onSubmit);
$(".show-password").on("click", togglePassword);
$("#startAgain").on("click", resetForm);
$(".random-username").on("click", randomUsername);
$(".username").keyup(function() {
let username = this.value;
updateDollName(username);
});
}
async function randomUsername() {
let url = "https://randomuser.me/api/";
let obj = await (await fetch(url)).json();
obj = obj.results[0];
let randuser = obj.login.username
$(".username").val(randuser);
updateDollName(randuser);
}
function updateDollName(username) {
username === "" ? $(".penguinName").text("Penguin Name") : $(".penguinName").text(username);
}
function togglePassword() {
$(this).toggleClass("fa-eye fa-eye-slash");
let input = $(this).prev('.info-section input');
input.attr('type', input.attr('type') === 'password' ? 'text' : 'password');
}
function resetForm() {
location.reload()
}
function nextSection($this) {
if (typeof sections[current] !== "undefined") {
if (valid) {
current_section = $($this).parent();
next_section = $($this).parent().next();
// console.log(current_section)
next_section.fadeIn();
current_section.remove();
current++;
updateProgressbar();
if (current === 1) {
let username = $(".username").val();
updatePenguinObj("username", username);
} else if (current === 2) {
let password = $(".password").val();
let email = $(".email").val();
updatePenguinObj("password", password);
updatePenguinObj("email", email);
} else if (current === 3) {
let name = $(".done");
name.text(name.text().replace(/%.+?%/, userData.username));
}
}
}
}
function onSubmit(event) {
event.preventDefault()
let request = new XMLHttpRequest()
request.onreadystatechange = () => handleResponse(request, $(this))
let formData = new FormData()
formData.append('username', userData.username);
formData.append('color', userData.colorId);
formData.append('password', userData.password);
formData.append('email', userData.email);
request.open('POST', 'https://reqbin.com/sample/post/json')
request.send(formData)
}
function handleResponse(request, $this) {
if (request.readyState !== XMLHttpRequest.DONE || request.status !== 200) {
return
}
var resp = `{
"message": "Test",
"valid": true
}`
let response = JSON.parse(resp);
if (!response) {
return
}
sectionValidation(response, $this);
}
function sectionValidation(response, $this) {
valid = true;
let section = $(sections[current]);
let input = section.find("input");
input.each(function() {
let inputs = $(this).attr('type') === "checkbox" ? !$(this).is(':checked') : input;
if (inputs) {
if (!response.valid) {
showError(response.message);
return valid = response.valid;
}
}
});
if (valid) {
nextSection($this);
}
}
function showError(text) {
$("#c_container").append(`<div class="error-block-container"><div class="error-container"><div id="error-content"><div id="error-msg-txt"> %text% </div><div id="error-btn"><div id="error-txt">Ok</div></div></div></div></div>`);
$("#error-btn").on("click", () => {
closeError();
});
let message = $("#error-msg-txt").html(text);
message.text(message.text().replace(/%.+?%/, message));
$(".error-block-container").fadeIn();
}
function closeError() {
$(".error-block-container").remove();
}
function updateProgressbar() {
let progressSteps = document.querySelectorAll(".progress-step");
progressSteps.forEach((progressStep, id) => {
if (id < current + 1) {
progressStep.classList.add("progress-step-active");
progressStep.classList.add("step");
} else {
progressStep.classList.remove("progress-step-active");
progressStep.classList.remove("step");
}
});
progressSteps.forEach((progressStep, id) => {
if (id < current) {
progressStep.classList.add("progress-step-check");
progressStep.classList.remove("progress-step-active");
} else {
progressStep.classList.remove("progress-step-check");
}
});
let progressActive = document.querySelectorAll(".step");
$(".progress").css("width", ((progressActive.length - 1) / (progressSteps.length - 1)) * 100 + "%");
}
function loadPalletes() {
let colorIndexNum = 0;
for (let palletes in penguinColors) {
let colorHex = penguinColors[palletes],
colorIndex = palletes,
colorIndexCurrNum = ++colorIndexNum;
$("#palletes").append(`<div data-id="${colorIndexCurrNum}" class="tinyPallete" style="background: #${colorHex}"></div> `);
}
$("#palletes").on("click", function(e) {
currPalleteId = $(e.target).attr("data-id");
e.currentTarget.querySelector(".active").classList.remove("active");
if (e.target.classList.contains("tinyPallete")) {
e.target.classList.add("active");
}
$(".doll").css("background-color", "#" + penguinColorByIndex(currPalleteId, false));
});
}
function penguinColorByIndex(index, keys) {
if (keys) {
return Object.keys(penguinColors)[--index];
}
return Object.values(penguinColors)[--index];
}
function updatePenguinObj(key, value) {
userData[key] = value;
return userData;
}
function createPenguinObj() {
userData = new Object();
userData.username = "";
userData.colorId = Number(currPalleteId);
userData.password = "";
userData.email = "";
return userData;
}
<html>
<head>
<title>Create Account</title>
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" />
<link type="text/css" rel="stylesheet" href="styles/fonts.css" />
<link type="text/css" rel="stylesheet" href="styles/create.css" />
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.16.0/jquery.validate.min.js"></script>
</head>
<body>
<div id="c_header">
<h2>Create a Free Account</h2>
<div id="startAgain">Start Again</div>
<div class="c_progressBar">
<div class="progress" id="progress"></div>
<div class="progress-step progress-step-active"></div>
<div class="progress-step"></div>
<div class="progress-step"></div>
<div class="progress-step"></div>
</div>
</div>
<div id="c_container">
<div id="c_content">
<img id="logo" src="images/logo.png" /><img id="safety" src="images/safety.png" />
<form method="POST">
<div class="rules-section">
<div class="grid-rules">
<div class="item">
<div>
<div id="rule-title">Respect other penguins</div>
Club Penguin does not tolerate any swearing, bullying or mean behavior toward other penguins. Disciplinary action will be taken should any one of these occur while playing.
</div>
<img id="rule-image" src="images/respect.png" />
</div>
<div class="item">
<div>
<div id="rule-title">No inappropriate talk</div>
References to drugs and alcohol related activities, and sexual, racial or otherwise inappropriate talk are not permitted.
</div>
<img id="rule-image" src="images/inapp.png" />
</div>
<div class="item">
<div>
<div id="rule-title">Never reveal personal information</div>
The best way to stay safe online is to NEVER share your real name, phone number, address, email or passwords.
</div>
<img id="rule-image" src="images/personal.png" />
</div>
<div class="item">
<div>
<div id="rule-title">No cheating</div>
Use of third party programs to cheat is prohibited. Players who use any third party programs while playing risk being permanently banned.
</div>
<img id="rule-image" src="images/cheating.png" />
</div>
</div>
<hr />
<div id="agree"> <span class="toggle">
<input type="checkbox" id="agree" name="agree" /><label>I agree to the Club Penguin Rules.</label>
</span>
</div>
<div id="terms"> <span class="toggle">
<input type="checkbox" id="terms" name="terms" /><label>I agree to the <a id="hyper" href="#">Terms of Use</a></label>
</span>
</div>
<button class="btn" name="submit">Continue</button>
</div>
<div class="color-section">
<div id="color-form">
<p id="epname">Enter Your Penguin Name:</p>
<!--<span class="bubble">
<div id="bubble-msg"></div>
</span>-->
<input type="text" name="username" class="username" id="inputaligncenter" maxlength="16" /> <span toggle="#random_username" class="fa fa-fw fa-refresh random-username" title="Random Username"></span>
<div id="cpsmall">Minimum 4 characters: use only numbers, letters and spaces.</div>
<p id="cpname">Click on a Color:</p>
<div id="palletes"></div>
<img id="paintbucket" src="images/paintbucket.png" />
</div>
<div class="doll-container"> <img class="doll" src="images/doll.png" /> <span class="penguinName">Penguin Name</span> </div>
<button class="btn" name="submit">Continue</button>
</div>
<div class="info-section">
<div id="info-form">
<div id="ppname-wrapper">
Penguin Password:
<div id="ppsmall">This is the password you will use to login to Club Penguin. </div>
<input type="password" name="password" class="password" placeholder="Password"><span toggle="#password" class="fa fa-fw fa-eye field_icon show-password"></span>
<input type="password" name="cpassword" class="cpassword" placeholder="Confirm Password"><span toggle="#c_password" class="fa fa-fw fa-eye field_icon show-password"></span>
<p id="activatedTxt">your penguin must be activated before you will be able to play at club penguin</p>
Parent's Email Address:
<div id="ppsmall">Please enter your parent's valid email address. Club Penguin will send your parent an e-mail with an activation code.</div>
<div class="env"> <img src="images/envelope.png">
<input type="text" class="email" name="email">
</div>
</div>
<div class="doll-container fixed"> <img class="doll" src="images/doll.png" /> <span class="penguinName">Penguin Name</span> </div>
</div>
<button type="submit" class="btn" name="submit">Continue</button>
</div>
<div class="done-section">
<h2 class="done">%username%, your Account Has Been Successfully Created!</h2>
</div>
</form>
</div>
</div>
</body>
</html>
Solved my problem lol. I just wrote another function that just selects the classes from a div, removes the current, then adds 1 to the current section to show the next. If anyone has a better method feel free to correct me.
function gotoNextSection() {
current_section = $(sections[current]);
current_section.remove();
current++;
next_section = $(sections[current]);
next_section.fadeIn();
updateProgressbar();
}
Related
Good Day,
I am currently nearly done creating a Modal with Vanilla JS, at present, my "Age Gate" does check if the age of the user is less than 18 and displays a error of 'Invalid Credentials',
I have tried to go further by trying to close the modal on the correct value and then the modal to close,
Please see my code below for the JS:
const modal = document.getElementById("myModal");
const form = document.querySelector('form');
const loading = document.getElementById("loading");
const btnSubmit = document.getElementById('btnSubmit');
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
// Functions
function onlyNumbers(e) {
const ageGate = document.querySelectorAll('.ageGate');
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
const errMsgDiv = document.getElementById('errorMsg');
let containsNumber = false
ageGate.forEach(input => {
if(numbers.some(num => input.value.includes(num))) containsNumber = true;
})
if (containsNumber || ageGate.value !== numbers && ageGate.value == '' || ageGate[2].value < 2004) {
let paragraph = document.createElement('p');
paragraph.innerHTML = 'Invalid Credentials';
errMsgDiv.append(paragraph);
e.preventDefault()
} else if (containsNumber = true) {
btnSubmit.remove()
loading.classList.remove('hide')
}
};
and now the Modal html:
<div id="modal">
<div class="modal-content">
<div class="flex-container">
<div>
<img
src="{% static 'imgs/Fireball_logo.png' %}"
class="logo"
alt="fireball logo"
/>
<h1>WOAH THERE!</h1>
<p class="info-text">We just need to see something</p>
</div>
<form action="">
{% csrf_token %}
<div class="form-flex">
<input
class="ageGate"
type="text"
max-length="2"
placeholder="DD"
/>
<input
class="ageGate"
type="text"
max-length="2"
placeholder="MM"
/>
<input
class="ageGate"
type="text"
max-length="4"
placeholder="YYYY"
/>
</div>
<p class="cookie-policy">
<small>
This site uses cookies. Cookie Policy. I agree
to the terms of use, and the privacy policy.
This information will not be used for marketing
purposes
</small>
</p>
<div class="text-center">
<button id="btnSubmit" class="btn" type="submit">
<p class="btn-text">Enter</p>
</button>
<img
src="{% static 'imgs/spinner.gif' %}"
alt="spinner"
id="loading"
class="loading close">
</div>
<span id="errorMsg"></span>
</form>
<div>
<img
src="{% static 'imgs/Drinkaware_logo.png' %}"
alt="Drinkaware Logo"
/>
</div>
</div>
</div>
</div>
Please as usual, I am sort of new with it all and I am definitely trying, so in your help, please could I ask for a brief explanation on your solution so that I may see how to think as a dev as that kind of information does help me
Thanks!
function onlyNumbers(e) {
e.preventDefault()
const ageGate = document.querySelectorAll('.ageGate');
const errMsgDiv = document.getElementById('errorMsg');
const year = ageGate[2].value;
const month = ageGate[1].value;
const day = ageGate[0].value;
const userBirthday = new Date(year, month - 1, day);
// Date Right Now
const today = new Date();
// Users age in years
const acceptingYear = today.getFullYear() - userBirthday.getFullYear()
if (acceptingYear < 18 ||
acceptingYear == 18 &&
today.getMonth() < userBirthday.getMonth() ||
today.getMonth() == userBirthday.getMonth() &&
today.getDate() < userBirthday.getDate()
) {
let paragraph = document.createElement('p');
paragraph.innerHTML = 'Invalid Credentials';
errMsgDiv.append(paragraph);
} else {
btnSubmit.remove()
loading.classList.remove('hide')
modal.classList.add('close');
}
};
I needed to target the modal and make sure that it was closing on execution of my function
I'm trying to compare user input value with JSON data.
I found some questions similar to this one, but it didn't solve my problem.
This is my code, do you know why it doesn't work.
Javascript
fetch('js/countries.json')
.then(res => res.json())
.then(data => {
function checkCountry() {
let input = document.getElementById("countryInput").value;
let country = data.find(check => check.country === "Norway");
let text;
if (input === data[country]) {
text = "Yes";
} else {
text = "No";
}
document.getElementById("alert").innerHTML = text;
}
document.getElementById("check").addEventListener("click", checkCountry);
console.log(data);
})
JSON
[{"country":"USA","active":true},
{"country":"Spain","active":true},
{"country":"Norway","active":true}]
HTML
<form action="">
<div class="input-container">
<input id="countryInput" type="text" placeholder="Country">
<i class="fas fa-search"></i>
</div>
<button id="check" type="button">CHECK</button>
</form>
This line is not good: if (input === data[country]) {
you have to check with the same mechanism as you have checked for country above...
let inputCountry = data.find(check => check.country === input);
Like this:
const data = [{"country":"USA","active":true},
{"country":"Spain","active":true},
{"country":"Norway","active":true}];
document.getElementById("check").addEventListener("click", checkCountry);
function checkCountry() {
let input = document.getElementById("countryInput").value;
let country = data.find(check => check.country === "Norway");
let inputCountry = data.find(check => check.country === input);
let text;
// You have to check with the country
if (inputCountry && input === inputCountry.country) {
text = "Yes";
} else {
text = "No";
}
console.log(text);
}
<form action="">
<div class="input-container">
<input id="countryInput" type="text" placeholder="Country">
<i class="fas fa-search"></i>
</div>
<button id="check" type="button">CHECK</button>
</form>
You can't use data[country] because data isn't key value pair collection.
It consists of objects.
Try to change resulting json from {'country': 'Spain', 'active': true}, ... to
'Spain': {active: true}, ...
Or call data element via:
if (input === data.find(el => el.country == country)) {
text = "Yes";
} else {
text = "No";
}
I was trying to do the form submit response, like on submit the form fields should be hidden and to show the thank you message without refreshing the page, but when i click submit the page is getting refreshed and showing the ajax response {"result":"success","data":"{\"message\":[\"sample message\"]}"
tried using Send Email from a Static HTML Form using Google Apps Mail!
(function() {
'use strict';
function getFormData(form) {
var elements = form.elements;
var fields = Object.keys(elements).filter().map(function(k) {
if (elements[k].name !== undefined) {
return elements[k].name;
// special case for Edge's html collection
} else if (elements[k].length > 0) {
return elements[k].item(0).name;
}
}).filter(function(item, pos, self) {
return self.indexOf(item) == pos && item;
});
var formData = {};
fields.forEach(function(name) {
var element = elements[name];
// singular form elements just have one value
formData[name] = element.value;
// when our element has multiple items, get their values
if (element.length) {
var data = [];
for (var i = 0; i < element.length; i++) {
var item = element.item(i);
if (item.checked || item.selected) {
data.push(item.value);
}
}
formData[name] = data.join(', ');
}
});
// add form-specific values into the data
formData.formDataNameOrder = JSON.stringify(fields);
formData.formGoogleSheetName = form.dataset.sheet || "responses"; // default sheet name
//formData.formGoogleSend = form.dataset.email || ""; // no email by default
formData.formPage = form.dataset.page || "";
}
function handleFormSubmit(event) {
if (this.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
this.classList.add('was-validated');
} else if (this.checkValidity() === true) {
var form = event.target;
var formData = getFormData(form);
var data = formData.data;
var url = form.action;
var xhr = new XMLHttpRequest();
xhr.open('POST', url);
// xhr.withCredentials = true;
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
form.reset();
var formElements = form.querySelector(".form-elements")
if (formElements) {
formElements.style.display = "none"; // hide form
}
var thankYouMessage = form.querySelector(".thankyou_message");
if (thankYouMessage) {
thankYouMessage.style.display = "block";
}
return;
};
// url encode form data for sending as post data
var encoded = Object.keys(data).map(function(k) {
return encodeURIComponent(k) + "=" + encodeURIComponent(data[k]);
}).join('&');
xhr.send(encoded);
}
}
function loaded() {
var forms = document.getElementsByClassName('needs-validation');
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener("submit", handleFormSubmit, false);
});
}
document.addEventListener("DOMContentLoaded", loaded, false);
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="gform needs-validation" method="POST" data-page="form validation test" action="https://script.google.com/macros/s/AKfycbxXw4fshxotq4vkQ3LUjvBaHhjS2RjFvDvKs5FW4w/exec" novalidate>
<div class="form-elements col-md-6 m-5">
<div class="form-row">
<div class="col-md-12 mb-3">
<textarea id="visitorMessage" class="form-control" name="message" placeholder="Message" required></textarea>
<div class="invalid-tooltip"> Please enter the message </div>
</div>
</div>
<button class="btn btn-primary btn-sm mx-0" type="submit">Submit</button>
</div>
<div class="thankyou_message" style="display: none;">
<h2>Thanks for contacting us! We will get back to you soon!</h2>
</div>
</form>
I expect to show the thankyou message without refreshing the page but the actual result is the page getting refreshed and showing the Ajax response
move event.preventDefault(); out of the if statement so the default submit action of the form is never triggered. You don't want to do an submit when you do an ajax request since the submit action will navigate to the form action url.
$('.needs-validation').on('submit', handleFormSubmit);
function handleFormSubmit(event) {
event.preventDefault();
if (this.checkValidity() === true) {
//Do this in the ajax succes event handler
$('.thankyou_message').show();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="gform needs-validation" method="POST" data-page="form validation test" action="https://script.google.com/macros/s/AKfycbxXw4fshxotq4vkQ3LUjvBaHhjS2RjFvDvKs5FW4w/exec" novalidate>
<div class="form-elements col-md-6 m-5">
<div class="form-row">
<div class="col-md-12 mb-3">
<textarea id="visitorMessage" class="form-control" name="message" placeholder="Message" required></textarea>
<div class="invalid-tooltip"> Please enter the message </div>
</div>
</div>
<button class="btn btn-primary btn-sm mx-0" type="submit">Submit</button>
</div>
<div class="thankyou_message" style="display: none;">
<h2>Thanks for contacting us! We will get back to you soon!</h2>
</div>
</form>
I have this below code. I can display the list of JSON file but I can't click the items of the list. Could you teach me How to add click and store item function.
What I would like to do is click the item of the list .After click it "NAME" value store the textbox. so then After set the value Click submit buttom then pass the NAME and related data. For example. Fist data https://api.myjson.com/bins/8x0ag
Fist data name is orange. When user click the orange. and press submit button I would like to send the code "102" and location "N34" data to Next page.
name "orange"
code "102"
location "N34"
Actually I had another code. To select item and store the value into the text field. but I changed the code after that I lost selecting function.
$(document).ready(function() {
Main.init();
});
var Main = (function($) {
return {
vars: { },
init: function() {
Main.build();
Main.events();
},
events: function() {
$(document).on('keyup', '.search', function() {
const ref = $(this).attr('data-ref');
const {
vars
} = Main;
$(`.resultUl[data-ref="${ref}"]`).html('');
const searchField = $(this).val();
const expression = new RegExp(searchField, "i");
$.each(vars.JSONdata, (key, value) => {
const {
name,
location,
code,
image
} = value;
if (name.search(expression) != -1 || location.search(expression) != -1) {
$(`.resultUl[data-ref="${ref}"]`).append(
`<li class="list-group-item link-class"
data-name="${name}"
data-code="${code}"
data-location="${location}">
<img src="${image}" height="40" width="40" class="img-thumbnail" />
${name}
<span class="text-muted">${location}</span>
</li>`
);
}
});
});
},
build: async function() {
JSONdata = await this.getJson();
this.vars = {
JSONdata
};
this.generateFields(20);
},
getJson: () => new Promise((resolve, reject) => {
$.getJSON('https://api.myjson.com/bins/8x0ag', (data) => {
resolve(data);
}).fail(function() {
reject([]);
})
}),
generateFields: (fieldNumber) => {
Array(fieldNumber).fill().map((v, i) => {
const ref = i + 1;
$('#container').append(
`<div class="fieldContainer">
<div class="btn-group">
<input type="text" class="search" data-ref="${ref}" placeholder="" class="form-control" size="3000" onkeypress="return event.keyCode!=13" />
<span class="searchclear glyphicon glyphicon-remove-circle"></span>
</div>
<ul class="list-group resultUl" data-ref="${ref}"></ul>
</div>`
)
});
},
}
})($);
I tried to add this code to above but it doesn't work.
$('#result').on('click', 'li', function() {
var name = $(this).data('name' );
var code = $(this).data('code' );
var location = $(this).data('location' );
var click_text = $(this).text().split('|');
$('#search').val($.trim(click_text[0]));
$("#result").html('');
$('#result').after('<input type="hidden" name="name" value="'+name+'">');
$('#result').after('<input type="hidden" name="code" value="'+code+'">');
$('#result').after('<input type="hidden" name="location" value="'+location+'">');
});
Mainly you need an event handler for the onClick for the li items.
It sets the name as value in the visible fields and creates hidden inputs in the form where you may have as much variables as you like but serialized in any way
Here is your working example
$(document).ready(function() {
Main.init();
});
var Main = (function($) {
return {
vars: {
},
init: function() {
Main.build();
Main.events();
},
events: function() {
$(document).on('keyup', '.search', function() {
const ref = $(this).attr('data-ref');
const {
vars
} = Main;
$(`.resultUl[data-ref="${ref}"]`).html('');
const searchField = $(this).val();
const expression = new RegExp(searchField, "i");
$.each(vars.JSONdata, (key, value) => {
const {
name,
location,
code,
image
} = value;
if (name.search(expression) != -1 || location.search(expression) != -1) {
$(`.resultUl[data-ref="${ref}"]`).append(
`<li
class="list-group-item link-class list-item"
data-name="${name}"
data-code="${code}"
data-location="${location}"
>
<img src="${image}" height="40" width="40" class="img-thumbnail" />
${name}
<span class="text-muted">${location}</span>
</li>
`
);
}
});
}),
$(document).on('click', '.list-item', function() {
const ul = $(this).closest('ul');
const ref = $(ul).attr('data-ref');
const name = $(this).attr('data-name');
const location = $(this).attr('data-location');
const code = $(this).attr('data-code');
const hiddenInput = $(`.hiddenField[data-ref=${ref}]`);
//console.log(hiddenInput.length);
$(`.search[data-ref=${ref}]`).val(name);
if (hiddenInput.length) {
$(hiddenInput).val(`${name}_${location}_${code}`);
} else {
$('#submitForm').append(
`<input
type="hidden"
class="hiddenField"
data-ref="${ref}"
name="search_${ref}"
value="${name},${location},${code}}"
/>
`
)
}
$(ul).html('');
})
},
build: async function() {
JSONdata = await this.getJson(); //JSONdata is a global variable which you can access from everywhere
this.vars = {
JSONdata
};
this.generateFields(20);
},
getJson: () => new Promise((resolve, reject) => {
// Change the path below with the path for your script
$.getJSON('https://api.myjson.com/bins/lpizs', (data) => {
resolve(data);
}).fail(function() {
reject([]);
})
}),
generateFields: (fieldNumber) => {
Array(fieldNumber).fill().map((v, i) => {
const ref = i + 1;
$('#container').append(
`<div class="fieldContainer">
<div class="btn-group">
<input type="text" class="search" data-ref="${ref}" placeholder="製品 その1" class="form-control" size="3000" onkeypress="return event.keyCode!=13" />
<span class="searchclear glyphicon glyphicon-remove-circle"></span>
</div>
<ul class="list-group resultUl" data-ref="${ref}"></ul>
</div>`
)
});
},
}
})($);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<head>
<title>JQuery</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
</head>
<body>
<br /><br />
<div class="container" style="width:900px;">
<h2 align="center"></h2>
<h3 align="center"></h3>
<br /><br />
<div align="center">
<div id="container">
</div>
<br />
<form action="recive.php" method="post" id="submitForm">
<input type="submit" id="submit" />
</form>
</div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>
I have 3 sections of input fields separated with different heading(Laser Pass, The Giggsy, The set up) generated from a JSON array. Here is what it looks like:
I want to compare two fields Score and Attempts and show an error message if the value of Score is larger then Attempts. Something like this:
But some section like, The Giggsy have a different type of input fields and no need to compare/check those fields. Only where it has SCORE and ATTEMPTS should compare.
When the section is filled up Show success message like this:
What I can do to make those things in angular way. Here is what I've done so far: PLUNKER
HTML:
<div class="row" ng-repeat="all in options">
<h4> {{ all.name}} </h4>
<div class="col-sm-5ths" ng-repeat="measurement in all.measurements">
<div class="form-group no-margin form-oneline">
<label style="width: 100%">{{ measurement.name }}</label>
<input ng-model="measurement.value" type="{{ measurement.type }}" min="{{ measurement.min }}" max="{{ measurement.max }}" class="form-control display-inline" required>
<label style="width: 100%">{{ measurement.scale }}</label>
</div>
</div>
<span style="color:red;" ng-show="testDataFieldWarning(options.measurements)">
Score can't be larger then Attempts
</span>
<span style="color:Green;" >
Done!!
</span>
</div>
<button type="submit" style="margin-top:50px;" ng-disable="">Submit</button>
JS
$scope.testDataFieldWarning = function (measurements) {
var score = 0 , attempts = 0;
angular.forEach(measurements, function(measurement) {
if((measurement.name) == 'Score'){
score = measurement.value;
}
if((measurement.name) == 'Attempts'){
attempts = measurement.value;
}
});
return attempts < score;
}
$scope.testDataFieldValidate = function (measurement) {
var isInvalid = false;
angular.forEach(measurement, function(v) {
if(typeof (v.value) == 'undefined'){
isInvalid = true;
}
});
return (isInvalid);
}
Sorry for bad English and explanation.
I forked your plunker and added some additional validating functions...
function isScoreField(measurements) {
if (measurements[1].name === 'Score' && measurements[2].name ==='Attempts') {
return true;
} else {
return false;
}
}
$scope.testDataFieldInvalid = function (measurements) {
if (isScoreField(measurements) && parseInt(measurements[2].value) < parseInt(measurements[1].value)) {
return true;
} else {
return false;
}
};
$scope.testDataFieldsEntered = function (measurements) {
if (measurements[1].value && measurements[2].value) {
return true;
} else {
return false;
}
};
... that will conditionally show/hide the done/error messages.
<span style="color:red;" ng-show="testDataFieldInvalid(all.measurements)">
Score can't be larger than Attempts
</span>
<span style="color:Green;" ng-show="testDataFieldsEntered(all.measurements) && !testDataFieldInvalid(all.measurements)">
Done!!
</span>
Hope this helps!