I'have a form which has date of birth filed. I want to show error message when I get response back from my php script. My php is script working fine, I'm getting response when there are multiple element as an array. like this.
[{code: 0, message: "Please fill valid date of birth."}, {code: 1, message: ""}]
This is my HTML
<input class="date_of_birth" name="date[]" type="text" value="" />
<span class="stepbirthVal"></span>
<input class="date_of_birth" name="date[]" type="text" value="" />
<span class="stepbirthVal"></span>
I want show error message only on the element which has a response 0. At the moment error message showing on all element even some element has response code 1. I want to validate the each field separately and error message should be shown on the element which has code:0.
Here is my JS code
//GET JSON from Validation.php and extract the nodes
var response = xmlhttp.responseText;
var parseJson = JSON.parse(response);
var resultCode = parseJson.code;
var resultMessage = parseJson.message;
console.log(parseJson);
var element = document.getElementById('stepbirth');
element.classList.toggle("disabled", parseJson.some(resp => !resp.code))
//Show Validation Message
parseJson.map(response => {
var items = document.getElementsByClassName("stepbirthVal"),i, len;
for (i = 0, len = items.length; i < len; i++) {
items[i].innerHTML = response.message;
}
});
Till toggle class my code is working fine, only error message is not showing how I want. It should only on a element which has response code 0.
You need a forEach in plain JS
Since the message is empty when it is "1", we should take advantage of that and fill the span with that empty string
const parseJson = [{
code: 0,
message: "Please fill valid date of birth."
}, {
code: 1,
message: "OK" // or blank
}]
const items = document.querySelectorAll(".stepbirthVal");
parseJson.forEach((response, i) => items[i].innerHTML = response.code === 0 ? response.message : "");
// OR just
// parseJson.forEach((response, i) => items[i].innerHTML = response.message);
<input class="date_of_birth" name="date[]" type="text" value="" />
<span class="stepbirthVal"></span>
<hr/>
<input class="date_of_birth" name="date[]" type="text" value="" />
<span class="stepbirthVal"></span>
jQuery:
const parseJson = [{
code: 0,
message: "Please fill valid date of birth."
}, {
code: 1,
message: ""
}]
const $items = $(".stepbirthVal");
$.each(parseJson,(i,response) => $items.eq(i).html(response.message))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="date_of_birth" name="date[]" type="text" value="" />
<span class="stepbirthVal"></span><hr/>
<input class="date_of_birth" name="date[]" type="text" value="" />
<span class="stepbirthVal"></span>
Based on your html and response structure I'd advise you to iterate over your response and for those with message only use code as array element index. Smth like this:
const respMock = [{
code: 0,
message: "Please fill valid date of birth."
}, {
code: 1,
message: ""
}];
const inputs = $('.date_of_birth');
respMock.forEach(function(resp) {
if (resp.message) {
let errorSpan = $(inputs[resp.code]).next();
errorSpan.text(resp.message);
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="date_of_birth" name="date[]" type="text" value="" />
<span class="stepbirthVal"></span>
<input class="date_of_birth" name="date[]" type="text" value="" />
<span class="stepbirthVal"></span>
Related
Looks like my main issue was using .val() when I should have been using map, thank you #Barmar!
Though I'm still looking for a way to achieve the second array structure at the bottom of my post. It seems like the HTML structure would have to be:
<div>
<input type="text" name="student[1][name]">
<input type="number" name="student[1][score]">
<input type="text" name="student[2][name]">
<input type="number" name="student[2][score]">
<input type="text" name="student[3][name]">
<input type="number" name="student[3][score]">
</div>
The challenge with this is the ID number is dynamic, so I'm not sure how to fit this in a Jquery selector. Would I just be selecting by "student" i.e.
let input_names = $('input[name^="student["]').map(function() {
return this.value;
}).get();
I have a lot of inputs that are of the same kind so I want them in arrays, i.e.
<div>
<input type="text" name="name_[1]">
<input type="number" name="score_[1]">
<input type="text" name="name_[2]">
<input type="number" name="score_[2]">
<input type="text" name="name_[3]">
<input type="number" name="score_[3]">
</div>
The number in-between the brackets is the ID grouping related elements together. I want to be able to send all the values in arrays in an AJAX request but can't seem to figure it out. Only the first elements get sent, not an array
let input_names = $('input[name^="name_"]').val();
let input_scores = $('input[name^="score_"]').val();
$.ajax({
url: "../util/funcs.php",
async: true,
data: {
a: "backendFunction",
input_names: input_names,
input_scores: input_scores
}
})
.done(function(data) {
console.log("Success");
})
.fail(function() {
console.log("Error");
.always(function() {
// alert( "complete" );
});
I want a way to neatly send them to the backend, either as separate arrays by name parameter or ideally grouped by ID. So the $_REQUEST would look something like:
[ids] =>
[1, 2]
[names] =>
["alex", "john"]
[scores] =>
[30, 70]
Or even better:
[1] =>
[name] => "alex"
[score] => "30"
[2] =>
[name] => "john"
[score] => "70"
Unfortunately either way I try, the AJAX only seems to send the first of each input, rather than arrays. Please help!
.val() only returns the value of the first element that matches the selector, not all of them. You need to loop over all the matches to get all the values.
let input_names = $('input[name^="name["]').map(function() {
return this.value;
}).get();
let input_scores = $('input[name^="score["]').map(function() {
return this.value;
}).get();
Here is a solution to get your desired object format:
$(function() {
let result = $('input').map(function() {
return { name: this.name, value: this.value };
}).get().reduce((acc, obj) => {
let num = obj.name.replace(/[^\d]+/g, '');
let key = obj.name.replace(/_.*$/, '');
if(!acc[num]) {
acc[num] = {};
}
acc[num][key] = obj.value;
return acc;
}, {});
console.log('result:', result);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input type="text" name="name_[1]" value="Alex">
<input type="number" name="score_[1]" value="101">
<input type="text" name="name_[2]" value="Berta">
<input type="number" name="score_[2]" value="102">
<input type="text" name="name_[3]" value="Dora">
<input type="number" name="score_[3]" value="103">
</div>
Output:
result: {
"1": {
"name": "Alex",
"score": "101"
},
"2": {
"name": "Berta",
"score": "102"
},
"3": {
"name": "Dora",
"score": "103"
}
}
Notes:
first, get all input elements and build an array of { name, value } objects
then, use a .reduce() to accumulate the desired object format
tweak the .replace() of num and key if you have different name input patterns
<input type="text" class="name_">
<input type="number" class="score_">
<input type="text" class="name_">
<input type="number" class="score_">
<input type="text" class="name_">
<input type="number" class="score_">
<input class="submit" type="button" value="submit" />
<script>
$('.submit').click(function(){
nam = $('.name_');
scr = $('.score_');
naml = nam.length;
myar = new Array;
i=0;
for(i=0;i<naml;i+=1)
{
myar[i] = {'name':nam.eq(i).val(),'score':scr.eq(i).val()};
}
alert(JSON.stringify(myar));
});
</script>
I have an HTML form whose data I would like to be sent to a Google Sheet. This is done through Apps Script.
Here is the Apps Script code:
const sheetName = 'Sheet1'
const scriptProp = PropertiesService.getScriptProperties()
function initialSetup () {
const activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet()
scriptProp.setProperty('key', activeSpreadsheet.getId())
}
function doPost (e) {
const lock = LockService.getScriptLock()
lock.tryLock(10000)
try {
const doc = SpreadsheetApp.openById(scriptProp.getProperty('key'))
const sheet = doc.getSheetByName(sheetName)
const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
const nextRow = sheet.getLastRow() + 1
const newRow = headers.map(function(header) {
return header === 'Date' ? new Date() : e.parameter[header]
})
sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow])
return ContentService
.createTextOutput(JSON.stringify({ 'result': 'success', 'row': nextRow }))
.setMimeType(ContentService.MimeType.JSON)
}
catch (e) {
return ContentService
.createTextOutput(JSON.stringify({ 'result': 'error', 'error': e }))
.setMimeType(ContentService.MimeType.JSON)
}
finally {
lock.releaseLock()
}
}
I made a simple HTML form to test it out, and it seemed to have worked. Here is the code for it:
<form
method="POST"
action="https://script.google.com/macros/s/AKfycbwo9A2AKU8OB5YXs_l0w3wqKoZDYp6F5C3EuarHeQVILt4CK9zaIhmGQETz7StlOc2P/exec"
>
<input name="Email" type="email" placeholder="Email" required>
<input name="Name" type="text" placeholder="Name" required>
<button type="submit">Send</button>
</form>
However, when I made my own form, it did not seem to work. Here is the code for the actual HTML Form:
<form method="POST" action = "MY_WEB_APP_URL"id = "clothingExpenses" class = 'display'>
<div style = 'text-align:center;' class="row">
<div style = 'text-align:center;' class="six columns">
<label style = ' padding-bottom: 1pt; text-align:center;' for="exampleEmailInput">Clothing type</label>
<input name = "Type" id = 'type' astyle = "width: 50%;" type="email" placeholder="Enter the clothing type" id="exampleEmailInput">
</div>
</div>
<div>
<label style = ' padding-bottom: 1pt;' for="exampleEmailInput">Amount</label>
<input name = "Amount" id="amnt" style = "width: 24%;" type="number" placeholder="Enter number" id="exampleEmailInput">
</div>
<div>
<label style = 'padding-bottom: 1pt;' for="exampleEmailInput">Clothing brand</label>
<input name = "Brand" id="brand" style = "width: 24%;" type="text" placeholder="Enter the clothing brand" id="exampleEmailInput">
</div>
<button type = 'submit' class="button-primary" onclick="addExpense()">Add expense</button>
<button type = 'submit' class="button-primary" onclick="closeExpenseForm()">Close form</button>
</form>
addExpense() function:
function addExpense()
{
// A value clothingID stores the values of each clothing expense.
clothingID={'id':Date.now(),'clothingType':clothingType.value, 'brand': brand.value, 'amnt':amnt.value, };
//It is then pushed into the clothingArray array.
clothingArray.push(clothingID);
count1++;
showTotalBalance();
showDifference();
expenseHistory();
clothingType.value='';
amnt.value='';
brand.value = '';
setItemInStorage();
}
The web app URL in the second HTML form has been removed as I am not sure if it should be keep it private or not.
After numerous suggestions from the community and as confirmed by OP the issue was caused by:
clothingType.value=''; amnt.value='';
AND
brand.value = '';
In the addExpense() function
I wanted to have the message "This input field cannot be blank" appearing after each input text and email field. However, I failed to do so. Only one message was appeared after the last input field (i.e. Card Number)
Would you please help me spot out what happened? I tried for 1 hour.
Thank you very much.
//javascript file
const elementAction = {
createMessage: function(insertedElement, value, elementCollection, position ){
const newElement= document.createElement(insertedElement);
newElement.innerHTML= value;
elementAction.insertAlert(position, elementCollection, newElement);
},
insertAlert: function(position, elementCollection, insertedElement){
for(let i=0; i<elementCollection.length; i++){
elementCollection[i].insertAdjacentElement(position, insertedElement);
}
},
get: function(element){
const elementCollection = document.querySelectorAll(element);
return elementCollection;
}
};
const inputFieldCollection = elementAction.get("[type='email'], [type='text']");
elementAction.createMessage('p', 'This input field cannot be blank', inputFieldCollection, 'afterend');
//HTML file
<label for="name">Name:</label>
<input type="text" id="name" name="user_name">
<label for="mail">Email:</label>
<input type="email" id="mail" name="user_email">
<label for="cc-num">Card Number:</label>
<input id="cc-num" name="user_cc-num" type="text">
How I can get value from input and store it to the object?
When button is clicked value from the input - should to be stored in the object.
Thank you a lot in advance
var testObject = { 'name': nameOfbook.value,
'author': nameOfauthor.value,
'year': year.value
};
console.log(testObject);
<input type="text" id="nameOfbook" required="" placeholder="Book name" />
<input type="text" id="nameOfauthor" required="" placeholder="Athor name" />
<input type="text" id="year" required="" placeholder="Add year" />
<button id="addder" type="button">StoreEmail</button>
Here's a working JSfiddle for you.
The relevant JS code is here. Using the id tags on your html elements, I got all of the elements and stored them into variables. Next, I added an event listener on your button, and on click, I push the relevant value of each element into your testObject.
var testObject = [];
const button = document.getElementById("addder");
const name = document.getElementById("nameOfbook");
const author = document.getElementById("nameOfauthor");
const year = document.getElementById("year");
button.addEventListener("click", function() {
testObject.push({
name: name.value,
author: author.value,
year: year.value
})
console.log(testObject)
})
https://jsfiddle.net/991jqomq/
Here's how I did it
HTML:
<form id="new-post">
<label for="post-title">Title:</label>
<input id="post-title" type="text" />
<label for="post-body">Body:</label>
<textarea id="post-body"></textarea>
<button>Post</button>
</form>
JS:
document.getElementById("new-post").addEventListener("submit", function(e) {
e.preventDefault()
const postTitle = document.getElementById("post-title").value
const postBody = document.getElementById("post-body").value
const data = {
title: postTitle,
body: postBody
}
console.log(data)
})
Obviously, a beginner's question:
How do I get array data to display in an html element using html and javascript?
I'd like to display the user saved array data in a paragraph tag, list tag, or table tag, etc.
[http://www.mysamplecode.com/2012/04/html5-local-storage-session-tutorial.html]
Above is a link to the kindly provided example of localStorage except how to display the array on the html page rather than in the console.log.
Below is the code snip that demonstrates what I'm trying to do.
function saveArrayData() {
console.log("Saving array data to local storage.");
var myArrayObject = [];
var personObject1 = new Object();
personObject1.name = "Array1";
personObject1.age = 23;
myArrayObject.push(personObject1);
var personObject2 = new Object();
personObject2.name = "Array2";
personObject2.age = 24;
myArrayObject.push(personObject2);
var personObject3 = new Object();
personObject3.name = "Array3";
personObject3.age = 25;
myArrayObject.push(personObject3);
localStorage.setItem("persons", JSON.stringify(myArrayObject));
}
function restoreArrayData() {
console.log("Restoring array data from local storage.");
var myArrayObject = JSON.parse(localStorage.getItem("persons"));
for (var i = 0; i < myArrayObject.length; i++) {
var personObject = myArrayObject[i];
console.log("Name: " + personObject.name, "Age: " + personObject.age);
}
}
<label for="name">Name:</label>
<input type="text" data-clear-btn="true" name="name" id="name" value="">
<label for="age">Age:</label>
<input type="text" data-clear-btn="true" name="age" id="age" value="">
<br>
<br>
<input type="button" id="sArray" value="Save Array data" onclick="Javascript:saveArrayData()">
<input type="button" id="rArray" value="Restore Array data" onclick="Javascript:restoreArrayData()">
<p id="displayArrayDataHere"></p>
You should update your code like below:
function restoreArrayData() {
var myArrayObject = JSON.parse(localStorage.getItem("persons"));
$("#displayArrayDataHere").append("<table>");
myArrayObject.forEach(function(personObject) {
$("#displayArrayDataHere").append("<tr><td>"+personObject.name+"</td><td>"+personObject.age+"</td></tr>")
})
$("#displayArrayDataHere").append("</table>");
}