Edit - Updated JS code to display suggestions made in comments, still having issues.. Now the button <input id="edit" type="submit" value="Submit"> won't go to edit.html, instead it is returning action.html? It is nested inside of the editForm?
I have a simple form which I have managed to learn to submit, add, remove, and display bookings using the localStorage (thanks to those who helped on here!).
My last task is to amend a booking, I think I am almost there with it, but not sure how to call the indexes (excuse my jargon), to replace the values.
The form submits and the web address reads something like edit.html?OldFirstName=NewFirstName&OldLastName=NewLastName, however the values don't update in storage, and it throws an error saying
Uncaught TypeError: Cannot read property 'fname' of undefined`.
I expected this to happen as I know I am not finding the values correctly, but I can't figure out how I should be writing it out? My thought process was that it would be similar to the original submit function but with the [i] values for fname and lname?
Here's my JS code - if you need anything else from me let me know:
// ~~~ add bookings to localStorage
var bookings = localStorage.getItem("bookings");
$("#submit").click(function () {
bookings = (bookings) ? JSON.parse(bookings) : [];
var newBookings = {
fname: $('#fname').val(),
lname: $('#lname').val()
}
bookings.push(newBookings);
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
});
// ~~~ edit bookings in localStorage
$("#edit").click(function (e) {
e.preventDefault();
bookings = (bookings) ? JSON.parse(bookings) : [];
var parent_form = $('#editForm');
var fname = parent_form.find('.input:eq(0)').val();
var lname = parent_form.find('.input:eq(1)').val();
var newBookings = {
fname: fname,
lname: lname
}
bookings.push(newBookings);
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
});
// ~~~ display bookings in browser
function showBooking(i) {
var bookingResult = document.getElementById("result");
var ul = document.createElement("ul");
var bookingItems = JSON.parse(localStorage.getItem("bookings")) || [];
bookingResult.innerHTML = "";
for (let i = 0; i < bookingItems.length; i++) {
bookingResult.innerHTML += `<div class="card card-body bg-light m-4">
<h3>${bookingItems[i].fname + " " + bookingItems[i].lname}
<button onclick="deleteBooking(${i})" class="btn btn-danger text-light ">Delete</button>
<button onclick="editBooking(${i})" class="btn btn-danger text-light ">Edit</button>
</h3>
</div>`;
}
}
// ~~~ edit bookings in browser
function editBooking(i) {
var bookingResult = document.getElementById("editAppt");
var bookingItems = JSON.parse(localStorage.getItem("bookings")) || [];
bookingResult.innerHTML =
`<form id="editForm" name="editForm" onsubmit="return editForm(this)" class="col-sm-6">
<div class="row">
<input type="text" class="input" id="fname_${i}" placeholder="${bookingItems[i].fname}" name="${bookingItems[i].fname}" required>
<input type="text" id="lname_${i}" class="input" placeholder="${bookingItems[i].lname}" name="${bookingItems[i].lname}" required>
<input id="edit" type="submit" value="Submit">
</div>
</form>`;
}
// ~~~ delete bookings from localStorage
function deleteBooking(i){
var bookingItems = JSON.parse(localStorage.getItem("bookings"));
bookingItems.splice(i, 1);
localStorage.setItem("bookings", JSON.stringify(bookingItems));
showBooking();
}
// ~~~ form submit handlers
function setAction(form) {
form.action = "action.html";
}
function editForm(form) {
form.action = "edit.html";
}
I can see that the issue comes from this like :
$("#edit").click(function (i) {
You expect the click event to return an index but it's not, the i will represent the event object, so you may need to use $(this) to get the related inputs like :
$("#edit").click(function (e) {
var parent_form = $(this.form);
var fname = parent_form.find('.input:eq(0)').val();
var lname = parent_form.find('.input:eq(1)').val();
....
NOTE: The id must not be duplicated, so you need to avoid that, you may use prefix like:
<input type="text" class="input" id="fname_${i}" placeholder="${bookingItems[i].fname}" name="${bookingItems[i].fname}" required>
<input type="text" class="input" id="lname_${i}" placeholder="${bookingItems[i].lname}" name="${bookingItems[i].lname}" required>
Related
I have followed a tutorial "Create HTML Form that Moves through RecordSet on Google Sheets" done by Code With Curt.
https://www.youtube.com/watch?v=V9ptq7tZV50&t=152s
The project doesn't look that complicated. It is a simple CRUD app that I want to run in a modal dialog in google sheets, I am a newbie, I really tried to understand the code that I was copying from the video and not make any typos. The form shows up OK from the custom menu but it is not populating with the data from the sheet. The only error I can see is in the console which says "Uncaught ReferenceError: loadRecords is not defined" I have double checked the variable and function names but just can't see the error.
Any help would be appreciated.
Code.gs
function getList()
{
var url = 'https://docs.google.com/spreadsheets/d/1QkSdtybPHA9IrWH2VPw44WtQ9dN_-9KjRVNOuCylMCk/edit#gid=0';
var ss= SpreadsheetApp.openByUrl(url);
//var ss = SpreadsheetApp.getActiveSpreadsheet();
var recordSheet = ss.getSheetByName("WebInscriptions");
var getLastRow = recordSheet.getLastRow();
return recordSheet.getRange(2, 1, getLastRow -1, 9).getValues();
}
function startForm()
{
var form = HtmlService.createHtmlOutputFromFile("Modal");
SpreadsheetApp.getUi().showModalDialog(form, 'Manage New Submissions');
}
function addMenu()
{
var ui = SpreadsheetApp.getUi()
ui.createMenu('HR-Recruitment')
.addItem('New Submissions','startForm')
.addItem('Manage Recruits','startForm')
.addToUi();
}
function onOpen(e)
{
addMenu;
}
Modal.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function loadRecords(record)
{
google.script.run.withSuccessHandler
(function(ar)
{
var record = document.getElementById("record").value;
//console.log (ar);
//console.log (record);
var recordCount = 0;
ar.forEach(function(item, index)
{
if(index == record - 1)
{
document.getElementById("inscriptionDate").value = item[0];
document.getElementById("firstName").value = item[1];
document.getElementById("lastName").value = item[2];
document.getElementById("gender").value = item[3];
document.getElementById("email").value = item[4];
document.getElementById("telNumWhatsApp").value = item[5];
document.getElementById("location").value = item[6];
document.getElementById("visaImageUpload").value = item[7];
document.getElementById("commentMessage").value = item[8];
document.getElementById("referrer").value = item[9];
}
recordCount ++;
});
console.log (recordCount);
document.getElementById("maxRecord").value = recordCount;
}).getList();
}
function NextRecord()
{
var record = document.getElementById("record").value;
var maxRecord = document.getElementById("maxRecord").value;
var nextRecord = Number record + 1;
if(nextRecord <= maxRecord)
{
document.getElementById ("record").value = nextRecord;
loadRecords();
}
}
function PreviousRecord()
{
var record = document.getElementById("record").value;
var previousRecord = Number record - 1;
if(previousRecord >= 1)
{
document.getElementById ("record").value = previousRecord;
loadRecords();
}
}
//loadRecords();
</script>
</head>
<body>
Inscription Date: <input type="text" id="inscriptionDate"/><br>
First Name: <input type="text" id="firstName"/><br>
Last Name: <input type="text" id="lastName"/><br>
Gender: <input type="text" id="gender"/><br>
Email: <input type="text" id="email"/><br>
Telephone Number (WhatsApp): <input type="text" id="telNumWhatsApp"/><br>
Location: <input type="text" id="location"/><br>
VISA Image Upload: <input type="text" id="visaImageUpload"/><br>
Comment or Message: <input type="text" id="commentMessage"/><br>
Referrer: <input type="text" id="referrer"/><br>
<input type="button" value = "PREVIOUS" onclick="PreviousRecord"/>
<input type="text" value="1" id="record" size="2px"/>
<input type="hidden" id="maxRecord"/>
<input type="button" value = "NEXT" onclick="NextRecord"/>
<script>loadRecords();</script>
</body>
</html>
Google Sheet image
Regarding the specific error, the parenthesis are missing in two lines:
var nextRecord = Number record + 1;
var previousRecord = Number record - 1;
Correct syntax
var nextRecord = Number(record) + 1;
var previousRecord = Number(record) - 1;
As mentioned in the Yuri's answer, the video that you used looks to have some problems. From my point of view it's obsolete, one hint is that it's using the now called "Classic Editor" instead of the current default editor. It's weird that the comment with the code was removed, next time start with a more recent example and once you have learned how to debug and learned the differences between the "old" Google Apps Script and the new (i.e. old runtime based on Mozilla Rhino, and the new runtime Chrome V8), go to old tutorials / examples.
P.S. It might be possible that if you are using new editor that your project is using the new runtime, if you want to try the code as is in the video, try enabling the Rhino runtime, for details see https://developers.google.com/apps-script/guides/v8-runtime.
Related
How to go about debugging JavaScript in the HtmlService in Google Scripts
Debugging client side code from Google Apps Script
Given that the youtube guy removed his code and doesn't answer on comments it's obviously that there is something terribly wrong with his code.
As far as I can tell the main problem was that you can't return an array from the function getList() into the HTML form. You need to convert it into a string with return JSON.stringify(array) and then (within HTML form) to convert it back into an array with var array = JSON.parse(array).
Basically, if you add the JSON.stringify and JSON.parse and add the brackets as #Rubén said, it should work.
Just in case, here is my a bit rewritten code:
Modal.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function NextRecord() {
var record = document.getElementById("record").value;
var maxRecord = document.getElementById("maxRecord").value;
var nextRecord = +record + 1;
if(nextRecord <= maxRecord) {
document.getElementById ("record").value = nextRecord;
google.script.run.withSuccessHandler(loadRecords).getList();
}
}
function PreviousRecord() {
var record = document.getElementById("record").value;
var previousRecord = +record - 1;
if(previousRecord >= 1) {
document.getElementById ("record").value = previousRecord;
google.script.run.withSuccessHandler(loadRecords).getList();
}
}
function loadRecords(ar) {
ar = JSON.parse(ar); // <--- here we parse the string back into an array
var record = document.getElementById("record").value;
document.getElementById("maxRecord").value = ar.length;
var item = ar[+record-1];
document.getElementById("inscriptionDate").value = item[0];
document.getElementById("firstName").value = item[1];
document.getElementById("lastName").value = item[2];
document.getElementById("gender").value = item[3];
document.getElementById("email").value = item[4];
document.getElementById("telNumWhatsApp").value = item[5];
document.getElementById("location").value = item[6];
document.getElementById("visaImageUpload").value = item[7];
document.getElementById("commentMessage").value = item[8];
document.getElementById("referrer").value = item[9];
}
google.script.run.withSuccessHandler(loadRecords).getList();
</script>
</head>
<body>
Inscription Date: <input type="text" id="inscriptionDate"/><br>
First Name: <input type="text" id="firstName"/><br>
Last Name: <input type="text" id="lastName"/><br>
Gender: <input type="text" id="gender"/><br>
Email: <input type="text" id="email"/><br>
Telephone Number (WhatsApp): <input type="text" id="telNumWhatsApp"/><br>
Location: <input type="text" id="location"/><br>
VISA Image Upload: <input type="text" id="visaImageUpload"/><br>
Comment or Message: <input type="text" id="commentMessage"/><br>
Referrer: <input type="text" id="referrer"/><br>
<input type="button" value = "PREVIOUS" onClick="PreviousRecord()"/> // <-- don't forget the brackets here
<input type="text" value = "1" id = "record" size = "2px"/>
<input type="hidden" value = "" id = "maxRecord"/>
<input type="button" value = "NEXT" onClick="NextRecord()"/> // <-- don't forget the brackets here
</body>
</html>
Code.gs
function getList(){
var url = 'https://docs.google.com/spreadsheets/d/1QkSdtybPHA9IrWH2VPw44WtQ9dN_-9KjRVNOuCylMCk/edit#gid=0';
var ss= SpreadsheetApp.openByUrl(url);
// var ss = SpreadsheetApp.getActiveSpreadsheet();
var recordSheet = ss.getSheetByName("WebInscriptions");
var lastRow = recordSheet.getLastRow();
var list = recordSheet.getRange(2, 1, lastRow-1, 10).getValues();
return JSON.stringify(list); // <--- here we return a string instead of the array
}
function startForm() {
var form = HtmlService.createHtmlOutputFromFile("Modal.html");
SpreadsheetApp.getUi().showModalDialog(form, 'Manage New Submissions');
}
function addMenu() {
var ui = SpreadsheetApp.getUi()
ui.createMenu('HR-Recruitment')
.addItem('New Submissions','startForm')
.addItem('Manage Recruits','startForm')
.addToUi();
}
function onOpen(e) { addMenu() }
I have managed to get data registering to my localStorage as arrays, however I have three queries:
Why are there double square brackets around my array?
How do I change the name field to the respective html ID?
Data returning as undefined when I try to retrieve it from the localStorage?
The output I am looking for in my localStorage is:
bookings: [
[0]{fname: "John", lname: "Smith" }
[1]{fname: "Jane", lname: "Doe" }
]
But I am currently getting:
bookings: [
[0][{name: "fname" value: "John"},{name: "lname": value: "Smith" }]
[1][{name: "fname" value: "Jane"},{name: "lname": value: "Doe" }]
]
I understand how to change the name value when items are hardcoded but I am initialising an empty array in my JS and not sure where the error is, I have tried assigning a value to the array [0] but then it doesn't register anything. I have also tried the data.flat() method which does nothing.
The issue is my next step is to amend and delete items so I need to try and understand the structure. Currently I am getting undefined when I try to get data from storage, I have provided my remove function (currently to show) below, I know it is wrong but I think the issue is to do with how I am storing the data. Sorry I have asked so many questions on this but I am new to JS and still learning. I am struggling with searches as there are so many variations of Javascript and getting a lot of answers relating to C# or Python which isn't helping.
Here is my code:
//var bookings = [];
var bookings = localStorage.getItem("bookings");
$("#submit").click(function () {
//bookings = JSON.parse(localStorage.getItem("bookings")) || [];
bookings = (bookings) ? JSON.parse(bookings) : [];
var newBooking = $("#regForm").serializeArray();
bookings.push(newBooking)
var json = JSON.stringify(bookings);
const newData = bookings.flat();
window.localStorage.setItem("bookings", json);
});
$("#remove").click(function () {
var strBookings;
var i;
strBookings = localStorage.getItem("bookings");
//document.write("<p>" + strBookings + "</p>");
bookings = JSON.parse(strBookings);
for (i = 0; i < strBookings.length; i++) {
document.write("<p>" + strBookings[i].value + "</p>");
}
//localStorage.removeItem('bookings');
});
Form
<form id="regForm" name="regForm" class="col-sm-6">
<div class="row">
<input type="text" id="fname" placeholder="First Name" name="fname" required>
<input type="text" id="lname" placeholder="Last Name" name="lname" required>
<input id="submit" type="submit" value="Submit">
</div>
</form>
Show
//var bookings = [];
var bookings = localStorage.getItem("bookings");
$("#submit").click(function () {
//bookings = JSON.parse(localStorage.getItem("bookings")) || [];
bookings = (bookings) ? JSON.parse(bookings) : [];
var newBooking = $("#regForm").serializeArray();
bookings.push(newBooking)
var json = JSON.stringify(bookings);
const newData = bookings.flat();
window.localStorage.setItem("bookings", json);
});
$("#remove").click(function () {
var strBookings;
var i;
strBookings = localStorage.getItem("bookings");
//document.write("<p>" + strBookings + "</p>");
bookings = JSON.parse(strBookings);
for (i = 0; i < strBookings.length; i++) {
document.write("<p>" + strBookings[i].value + "</p>");
}
//localStorage.removeItem('bookings');
});
<form id="regForm" name="regForm" class="col-sm-6">
<div class="row">
<input type="text" id="fname" placeholder="First Name" name="fname" required>
<input type="text" id="lname" placeholder="Last Name" name="lname" required>
<input id="submit" type="submit" value="Submit">
</div>
</form>
<button id="remove" value="Remove">Show</button>
I am sorry to keep asking this question but I am really struggling with it and I cannot figure out what is going wrong, I have read countless SO pages and general internet searches with no luck. A few people have helped me on here but the values are updating incorrectly so I thought it would be best to ask a fresh question with my most recent trials.
The challenge is to create a client-side (only) mock dog walking application based on localStorage, I so far am able to add, delete, and view appointments in the browser. I also have an edit function set up, however when I hit submit (#edit), the value at position [x] (end index) updates no matter which index I try to edit. Here is an example of my stored arrays in localStorage under key 'bookings':
[0]{fname: "John", lname: "Smith"}
[1]{fname: "Jane", lname: "Doe"}
[2]{fname: "David", lname: "Miller"}
When I hit edit on John Smith, for example, it will replace the values of David Miller, rather than Johns details. I thought of trying to find the index of each person similar to what I have done when finiding the values to display in HTML (bookings[i].lname), however this throws an error saying that i cannot be used before initialisation (makes sense, but not sure how to work around it).
Here is my most recent JS:
// ~~~ add bookings to localStorage
var bookings = JSON.parse(localStorage.getItem("bookings")) || [];
window.onload = showBooking();
$("#submit").click(function() {
var newBookings = {
fname: $('#fname').val(),
lname: $('#lname').val()
}
bookings.push(newBookings);
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
showBooking();
});
// ~~~ edit bookings in localStorage
$(document).on('click','#edit',function (e) {
e.preventDefault();
var parent_form = $(this.form);
var fname = parent_form.find('.input:eq(0)').val();
var lname = parent_form.find('.input:eq(1)').val();
const i = bookings.findIndex(booking => bookings.fname == fname && bookings.lname == lname);
deleteBooking(i);
bookings.push({
fname,
lname
});
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
// showBooking();
});
// ~~~ display bookings in browser
function showBooking() {
var bookingResult = document.getElementById("result");
var ul = document.createElement("ul");
bookingResult.innerHTML = "";
for (let i = 0; i < bookings.length; i++) {
bookingResult.innerHTML += `<div class="card card-body bg-light m-4">
<h3>${bookings[i].fname + " " + bookings[i].lname}
<button onclick="deleteBooking(${i})" class="btn btn-danger text-light ">Delete</button>
<button onclick="editBooking(${i})" class="btn btn-danger text-light ">Edit</button>
</h3>
</div>`;
}
}
// ~~~ edit bookings in browser
function editBooking(i) {
// $('#regForm').hide();
$('#result').hide();
var currentItem = document.getElementById("currentItem");
var editBooking = document.getElementById("editAppt");
currentItem.innerHTML += `<div class="card card-body bg-light m-4">
<h3>${bookings[i].fname + " " + bookings[i].lname} </h3>
</div>`;
editBooking.innerHTML = `<input type="text" class="input" id="fname_${i}" placeholder="${bookings[i].fname}" name="${bookings[i].fname}" value="${bookings[i].fname}" required>
<input type="text" class="input" id="lname_${i}" placeholder="${bookings[i].lname}" name="${bookings[i].lname}" value="${bookings[i].lname}" required>
<input id="edit" type="submit" value="Edit">`;
}
// ~~~ delete bookings from localStorage
function deleteBooking(i) {
bookings.splice(i, 1);
localStorage.setItem("bookings", JSON.stringify(bookings));
showBooking();
}
My form for creating an appointment (this changes when editBooking is called):
<form id="regForm" name="regForm" action="" class="col-sm-6">
<div id="editAppt" class="row">
<input type="text" class="input" id="fname" placeholder="First Name" name="fname" required>
<input type="text" class="input" id="lname"placeholder="Last Name" name="lname" required>
<input id="submit" type="submit" value="Submit">
</div>
</form>
You need to assign a unique identifier to each appointment. This will help fix your problem as you are currently identifying appointments by their first name, last name and position in the array.
When you edit an appointment, it removes it from its current position and adds it at the end which changes the index of all the current elements leading to your problem.
This would also cause problems if you had two appointments with the same name.
For a unique identifier, I suggest using new Date().getTime() for now.
var newBookings = {
id: new Date().getTime(),
fname: $('#fname').val(),
lname: $('#lname').val()
}
Once you've assigned a unique identifier to each appointment, you can change your Edit button so that it looks like this:
<input data-id="${bookings[i].id}" id="edit" type="submit" value="Edit">
Then in your Edit event handler, change the bottom part so that it looks like this:
let i = bookings.findIndex(booking => booking.id == $(this).data("id"));
bookings[i].fname = fname;
bookings[i].lname = lname;
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
So to explain, assign a unique identifier to each appointment, store the id in the data-id attribute, retrieve the data-id, find the index of the appointment with that id, update the appointment properties, save the bookings.
If you also want to improve the readability of your code, I suggest not mixing vanilla JavaScript and jQuery, i.e. document.getElementById("result") could be $("#result")
here what I am trying to do is when a user clicks the + button function should get called, it looks for the cookie shopping_cart. Then it tries to find the JSON with key 'item_qty', which is key-value pair of all the items in the cart. But the cart is not updating, moreover when clicked on + button is showing Unexpected token N in JSON at position 0
In browser console I am getting it as
"csrftoken=some_value; shopping_cart=None"
var updateCart = function (count) {
$('#cart-info').val($('#cart-info').val() + count);
};
var item_add = function (item_slug) {
var shopping_cart = JSON.parse($.cookie("shopping_cart"));
var item_slug = item_slug;
if(shopping_cart.hasOwnProperty('item_qty')){
item_qty_dict = shopping_cart['item_qty'];
if(item_qty_dict.hasOwnProperty(item_slug)){
var count_pre = item_qty_dict[item_slug];
item_qty_dict[item_slug] = count_pre + 1;
}
else {
item_qty_dict[item_slug] = 1;
shopping_cart['item_qty'] = item_qty_dict;
}
}
else {
shopping_cart = {}
shopping_cart['item_qty'] = {item_slug: 1};
}
$.cookie("shopping_cart", JSON.stringify(shopping_cart));
var temp= $.cookie('shopping_cart')
console.log(JSON.parse(temp));
};
var buttonPlus = $(".cart-qty-plus");
var incrementPlus = buttonPlus.click(function () {
var $n = $(this)
.parent(".qnty_chngr")
.find(".qty");
$n.val(Number($n.val()) + 1);
var product_slug = $(this).parent(".qnty_chngr").siblings('.product-slug').val();
console.log(product_slug);
updateCart(1);
item_add(product_slug);
});
HTML:
<div class="qnty_chngr">
<button class="cart-qty-plus" type="button" value="+">+</button>
<input type="text" name="qty" maxlength="12" value="1" class="input-text qty"/>
<button class="cart-qty-minus" type="button" value="-" title="Add less quantity">-</button>
</div>
<input type="hidden" class="product-slug" name="product_slug" value="{{ medicine.slug }}">
<div class="add_to_cart">
<button class="add_to_cart_txt" value="10"><span class="AddInfoBtn">Add </span></button>
</div>,
Seems in your cookie there is no valid JSON. None is not valid, it should be "None" (with quotes). Remove the cookie before testing.
Also if possible try using this library which works the way you expected.
https://github.com/js-cookie/js-cookie
I created multiplied input fields:
<div class="form-text-field first-name field-group">
<input data-index="1" type="text" id="firstName1" class="signup-input firstName" name="first[1]" placeholder="">
</div>
<div class="form-text-field email field-group">
<input type="text" data-index="1" id="inputMail1" class="signup-input text-value ignore" name="email[1]" placeholder="${message(code:"signup.redesign.placeholder.eg.email")}"/>
<span class="common-sprite disNone sign-up-cross first clone"></span>
</div>
I have a code in the JS file which clone every input.
I have to create arrays from the values of the inputs (one for the email, and one for the first name).
Here is the function:
var arrEmail = []
var arrName = []
function add() {
var obj = {};
var partner = {}
$('.email input[type="text"]').each(function() {
obj[this.data-index] = this.value;
});
arrEmail.push(obj)
$('.first-name input[type="text"]').each(function() {
partner[this.data-index] = this.value;
});
arrName.push(partner)
console.log(arrEmail[0])
}
I didn't succeed to get the arrays in this code. How do I fix it?
You have some mistakes.
Wrong syntax in line $('.email input[type="text"]').each(function({. You forgot to close bracket.
I don't understand why you tried get value this strange manner. You included jQuery. Use it!
I fix your code.
var arrEmail = [];
var arrName = [];
function add() {
var obj = {};
var partner = {};
$('.email input[type="text"]').each(function(item) {
obj[$(this).data('index')] = $(this).val();
});
arrEmail.push(obj);
$('.first-name input[type="text"]').each(function() {
obj[$(this).data('index')] = $(this).val();
});
arrName.push(obj);
console.log(arrEmail);
console.log(arrName);
}
$('#test').on('click', add);
jsFiddle demo
Upd #1
Haven't shown all conditions. Fixed it.
Use $(this).data('index') instead of this.data-index
You can handle this with a single array:
var myUsers= [];//this might be object that you store the user information
$('.first-name input[type="text"]').each(function(item) {
//first create the user information
var myUser = new Object();
myUser.Username = $(this).val();
myUser.Email= $(this).next().val();
//then add the user information to the myUsers array
myUsers.push(myUser );
});