Delete elements from observable array list - javascript

i was hoping if you could help me with a small javascript program, my program seems working fine when i add elements(customer and their type) to the array, but i am not sure how to add button next to the observable array elements so the user can delete their desired entries one by one? figure below shows what i want the program to look like:! many thanks!
function addCustomer()
{
var newIndex = customerList.length;
customerList[newIndex] = new Object;
customerList[newIndex].name = document.getElementById('name').value.trim();
customerList[newIndex].childOrAdult = childOrAdult.options[childOrAdult.selectedIndex].value;
displayCustomers();
}
function displayCustomers()
{
var message = '';
var message = '<tr><td><b> CUSTOMER NAME </b></td><td><b> CHILD/ADULT </b></td></tr>\n';
for (var i = 0 ; i < customerList.length ; i++)
{
message += '<br><tr><td> ' + customerList[i].name + ' </td><td> '
+ String(customerList[i].childOrAdult) + ' </br></td></tr>\n';
}
document.getElementById('outputDiv').innerHTML = message;
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta charset="utf-8" />
<title>Giant Trampoline Customers</title>
<script src="" type="text/javascript"></script>
</head>
<body onload="displayCustomers();">
<h1 style="text-align: center;">Giant Trampoline Customers</h1>
<div id="outputDiv" style="text-align: center;"></div>
<br>
<div id="inputDiv" style="text-align: center">
<h3>Add A Customer:</h3>
New customer's name: <input type="text" id="name" maxlength="30" value="" size="30">
</select>
<button type="button" onclick="addAndDisplayCustomer();">add</button>
</div>
</body>
</html>
![desired result ][1]

jsFiddle demo (http://jsfiddle.net/json/asdzgst9/)
First, you might want to replace the <div id="outputDiv"> with a <table>, if you want to display the data in a table. So,
<div id="outputDiv" style="text-align: center;"></div>
becomes:
<table id="outputTable" style="text-align: center;"></table>
Second, you need to update the function where you display all elements from the customerList so it renders an extra table column with a button.
function displayCustomers() {
var message = '<tr><td><b> CUSTOMER NAME </b></td><td><b> CHILD/ADULT </b></td><td></td></tr>';
for (var i = 0 ; i < customerList.length ; i++) {
message += '<tr><td> ' + customerList[i].name + ' </td>';
message += '<td>' + customerList[i].childOrAdult + ' </td>';
// Here, create a third column with a button.
message += '<td><button onclick="removeCustomer(' + i + ')">remove this customer</button></td></tr>';
}
// Note: we have replaced the outputDiv with outputTable here!
document.getElementById('outputTable').innerHTML = message;
}
Third, a function that handles a click on the new button and removes an element from the list by the provided index.
function removeCustomer(index) {
// remove 1 element from the array customerList from the given index.
customerList.splice(index, 1);
displayCustomers();
}
Sorting
To sort the array, you can call a build-in method sort. See the updated jsFiddle demo (http://jsfiddle.net/json/asdzgst9/).
Update the function displayCustomers and add the the following snippet before the for loop:
customerList.sort(function (customerA, customerB) {
if (customerA.name < customerB.name) {
return -1;
} else if (customerA.name > customerB.name) {
return 1;
} else {
return 0;
}
});

Related

Add checkbox from JavaScript

I have an HTML page that contains only an empty <div id="data"></div> and in javascript, I got the information from the database through the ajax and return it back to javascript then print it out in the <div id="data"></div>
I've set the data to be in the columns, now if I want to add another column and this column would contain a button if I click on it then the row will be deleted. (I know how to do the delete through ajax and return it back, etc..) but the question is how could I do the button?
If I add it inside the div = data it will be printed once, and if I add it inside the javascript file then I won't able to add a click listener .. how could I do that?
let printItems = document.getElementById("data");
function succes(user) {
let info = "<div class='infoTable'>";
for (let i = 0; i < user.length; i++) {
info += "<div class='info'>";
info += "<div class='fcol'>" + (i+1) + "</div>";
info += "<div class='scol'>" + user[i].name + "</div>";
info += "<div class='tcol'>" + user[i].quantity + "</div>";
info += "I NEED TO ADD THE BUTTON HERE TO HAVE user[i].ID";
info += "</div>";
}
info += "</div>";
printinfo.innerHTML = info;
}
<div id="data"></div>
Okay, you did the hard part. What you are looking is very easy and you can do that in more than one way. I can suggest you an easier way to me. Write a function which delete the row (from UI and ajax). Now your problem is how to call that function for each row. So you can attach a onclick function for every row you created.
For example:
info += '<button onclick="deleteRowFunction"> Delete This<button />';
Now every time you click the button your delete function called. But how to determine which function is called?
That can be solved by following ways:
info += '<button onclick="deleteRowFunction(\'' + user[i].ID + '\')"> Delete This<button />';
The other easy way is to use data- attribute:
For example:
info += '<button data-userId=' + user[i].ID + ' onclick="deleteRowFunction"> Delete This<button />';
In this way you can get the ID in the deleteRowFunction. You can read all the details here
const user = [{
name: "ABC",
quantity: 2,
}, {
name: "XYZ",
quantity: 1,
}, {
name: "abcdef",
quantity: 12,
}];
let printItems = document.getElementById("data");
function deleteButton(e){
const targetButton = e.target;
targetButton.parentElement.parentElement.remove();
}
function succes(user) {
let info = "<div class='infoTable'>";
for (let i = 0; i < user.length; i++) {
info += `<div class='info'>
<div class='fcol'>${(i + 1)}</div>
<div class='scol'>${user[i].name}</div>
<div class='tcol'>${user[i].quantity}</div>
<div class='tcol'><button onclick="deleteButton(event)">Delete</div>
</div>`;
}
info += "</div>";
printItems.innerHTML = info;
}
succes(user);
<div id="data"></div>

Cannot call methods on table prior to initialization; attempted to call method 'refresh'

I want to list all the data from the database table to the HTML page. There are a total of 3 rows of data currently, but only 2 rows of data are listed.
HTML.
<script src="lib/jquery-1.11.2.min.js"></script>
<script src="lib/jquery.mobile-1.4.5.min.js"></script>
<div class="expandable-content">
<div id="SearchResult" class="ui-content">
<table data-role="table" data-mode="reflow" class="uiresponsive" id="CoTable">
<thead>
<tr>
<th>User</th>
<th>Personnel</th>
<th>License</th>
</tr>
</thead>
<tbody id="mybody"></tbody>
</table>
</div>
</div>
JS.
function searchperson() {
var xmlhttp = new XMLHttpRequest();
var url = serverURL() + "/searchfriends.php";
url += "?userid=" + localStorage.getItem("userid") + "&search=" +
$("#search").val();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
getSearchResults(xmlhttp.responseText);
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function getSearchResults(response) {
var arr = JSON.parse(response);
var i;
$("#mybody").find("tr").remove();
for (i = 0; i < arr.length; i++) {
$("#mybody").append("<tr><td>" + arr[i].userid +
"</td><td>"
+ arr[i].personnel + "</td><td>"
+ arr[i].license + "</td></tr>");
}
$('#Results').bind('pageinit', function () {
$('#CoTable').table('refresh');
//$("#CoTable").table('refresh');
}
I expect all data to be listed but only 2 rows of data were listed. [Uncaught Error: cannot call methods on table prior to initialization; attempted to call method 'refresh'.] I made use of the jquery mobile page id and it gets rid of the error but there are still missing data. Please help, thank you so much.
For JQM table widget the method is called rebuild (reference: https://api.jquerymobile.com/table/).
Because of the asynchronous behavior of the http request, You may don't know when the response will be received, so IMHO the simplest way to handle that response is to check if the table widget has been already instanced or not, and then invoke the needed method:
function isInstanceOf(id, widget) {
var el = document.getElementById(id);
return !!$.data(el, 'mobile-' + widget);
}
function addRow(id, evt) {
var html = '',
$table = $('#' + id),
isInstance = isInstanceOf(id, 'table'),
tableMethod = isInstance ? 'rebuild' : null;
html += '<tr>';
html += '<td>' + id + '</td>';
html += '<td>' + evt + '</td>';
html += '<td>' + isInstance + '</td>';
html += '<td>' + (isInstance ? tableMethod : '[create]') + '</td>';
html += '</tr>';
$table.find('tbody').append(html);
$table.table(tableMethod);
}
$(document).ready(function() {
addRow("CoTable", "DomReady");
});
$(document).on("pagecontainercreate", function(e, ui) {
addRow("CoTable", e.type);
} );
$(document).on("tablecreate", function(e, ui) {
addRow(e.target.id, e.type);
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css" />
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.js"></script>
</head>
<body>
<div data-role="page">
<div data-role="header" data-theme="b">
<h1>jQuery Mobile Table</h1>
</div>
<div data-role="content">
<table data-role="table" data-mode="reflow" id="CoTable" class="ui-responsive">
<thead>
<tr>
<th data-priority="1">Id</th>
<th data-priority="persist">Source</th>
<th data-priority="2">Instanced</th>
<th data-priority="3">Method</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</body>
</html>
No worries about the event sequence.
Here is a plunker: https://plnkr.co/edit/S8m8BPYnsfUFklYLwEz7?p=preview

How to pass values to an html page from google script

I have a google sheet, maintaining a list of projects, with some scripting running behind it. I have been able to add functionality to click an Add Project button which opens an HTML window for entering the information, and on submit, add a new record to the sheet.
Now I am working on a process to remove a record if the status is changed to Cancelled. What I would like to do is show an html window listing certain details of the project, and give the user a chance to either go back without cancelling the project, or enter some notes as to why it's being cancelled and then continue.
Where I am stuck is populating the html window with the details of the project. I have figured out one way to do it, but I know that this isn't the best way.
Google Script:
function onEdit(e) {
if(e.range.getColumn() == 9 && e.value == "Cancelled" && e.source.getActiveSheet().getName() == "Summary") {
var cancelSheet = ss.getSheetByName(e.source.getActiveSheet().getName());
var cancelRange = cancelSheet.getRange(e.range.getRow(), 1, 1, cancelSheet.getLastColumn());
var cancelRow = cancelRange.getValues();
openCancelDialog(cancelRow);
}
}
function openCancelDialog(x) {
var html = HtmlService
//.createHtmlOutputFromFile('Cancel')
.createHtmlOutput(
'<table><tr><td colspan = \"2\"><b>You are cancelling the following project:</b></td></tr>' +
'<tr><td>Project Name: </td><td>' + x[0][4] + '</td></tr>' +
'<tr><td>Project Number: </td><td>' + x[0][0] + '</td></tr>' +
'<tr><td>Project Category: </td><td>' + x[0][1] + '</td></tr>' +
'<tr><td>Business Owner: </td><td>' + x[0][17] + '</td></tr>' +
'<tr><td>Project Manager: </td><td>' + x[0][18] + '</td></tr>' +
'</table>'
)
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
SpreadsheetApp.getUi()
.showModalDialog(html, 'Cancel a Project');
}
This way is writing the html directly in the gs. What I'd like to do is have a separate html page that gets created. That can be done with this method (and is how I'm creating the Add Project dialog elsewhere in the gs):
function openCancelDialog(x) {
var html = HtmlService.createHtmlOutputFromFile('Cancel').setSandboxMode(HtmlService.SandboxMode.IFRAME);
SpreadsheetApp.getUi()
.showModalDialog(html, 'Cancel a Project');
}
This would be Cancel.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script>
<!-- Scripting to get my values? -->
</script>
</head>
<body>
<!-- Layout the window
Add a Comments section
Add a button to go back without cancel
Add a button to submit the cancel and update -->
</body>
</html>
But what I haven't figured out is how to pass the array from the openCancelDialog function to the html, so it cab be shown on the page..
I suspect that I need to add scripting to the Cancel.html file to get those values. But is there a way to send that array to the html while it's being created?
Kos's answer gave me some ideas on how I could work it out. That, as well as some additional reading, especially https://www.w3schools.com/js/js_json_intro.asp and the follow up sections, helped me figure this one out.
New js code:
function onEdit(e) {
if(e.range.getColumn() == 9 && e.value == "Cancelled" && e.source.getActiveSheet().getName() == "Summary") {
var cancelSheet = ss.getSheetByName(e.source.getActiveSheet().getName());
var cancelRange = cancelSheet.getRange(e.range.getRow(), 1, 1, cancelSheet.getLastColumn());
var cancelRow = cancelRange.getValues();
//openCancelDialog(cancelRow);
var aSheet = e.source.getActiveSheet().getName();
var column = e.range.getColumn();
var row = e.range.getRow();
Logger.log("Col: " + column + " Row: " + row + " Sheet: " + aSheet);
Logger.log(cancelRow);
}
Logger.log(e);
}
function openCancelDialog(row) {
var ui = SpreadsheetApp.getUi();
// get template
var template = HtmlService.createTemplateFromFile('Cancel');
var myJSON = JSON.stringify(row);
// pass data to template
template.data = myJSON;
// get output html
var html = template.evaluate();
// show modal window
ui.showModalDialog(html, 'Cancel a Project');
}
New HTML:
<!DOCTYPE html>
<html>
<body>
<table>
<tr><td>Number: </td><td id="number"></td></tr>
<tr><td>Name: </td><td id="name"></td></tr>
<tr><td>Category: </td><td id="category"></td></tr>
<tr><td>Business Owner: </td><td id="owner"></td></tr>
<tr><td>Project : </td><td id="manager"></td></tr>
</table>
<script>
var objII = JSON.parse(<?=data?>);
document.getElementById("number").innerHTML = objII[0][0];
document.getElementById("name").innerHTML = objII[0][4];
document.getElementById("category").innerHTML = objII[0][1];
document.getElementById("owner").innerHTML = objII[0][17];
document.getElementById("manager").innerHTML = objII[0][18];
</script>
</body>
</html>
I suspect there may be more elegant ways to do this, and probably even more "correct" ways. But this seems to be working for what I needed it to do, so I figured I'd post it in case someone else was looking.
Thank you
Use HtmlService.createTemplateFromFile:
function openCancelDialog(row)
{
var ui = SpreadsheetApp.getUi();
// get template
var template = HtmlService.createTemplateFromFile('Cancel');
// pass data to template
template.data = {
row: JSON.stringify(row)
};
// get output html
var html = template.evaluate();
// show modal window
ui.showModalDialog(html, 'Cancel a Project');
}
Cancel.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<script>
var row = <?!=data.row?>;
//document.write(row);
</script>
</body>
</html>
Detailed template documentation: https://developers.google.com/apps-script/guides/html/templates
Here's another way to do it. I like to do it this way because I have a lot more control than I do with templates.
This is a script that I did when I was working on an email example script that is contained in a spreadsheet. This script is a little less complicated because it's just for giving the user the option for removing sent emails from the emailsetup page and archiving them on another page. It does it by creating html on the fly and collecting it as a string and then adding it to another page of html. I launch the html at the end of the script as a dialog that allows the users to select which emails to archive by checking checkboxes and clicking on a button called Archive Selected. I found it easier to put my javascript functions together in a standard html file and then run that through HtmlService first and append the string later.
Here's the script:
function archiveSelectedEmails()
{
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sht=ss.getSheetByName('EmailSetup');
var rng=sht.getDataRange();
var rngA=rng.getValues();
var s='<html><head><script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script></head><body>';
var s='';
for(var i=2;i<rngA.length;i++)
{
var dataA={};
for(var j=0;j<rngA[1].length;j++)
{
dataA[rngA[1][j]]=rngA[i][j];
}
var row=Number(i+1);
s+='<div id="row' + row + '"><input type="checkbox" name="email" value="' + Number(i+1) + '" />' + ' <strong>Row:</strong> ' + Number(i+1) + ' <strong>Name:</strong> ' + dataA.Name + ' <strong>Email:</strong> ' + dataA.Email + ' <strong>Subject:</strong> ' + dataA.Subject + ' <strong>DateSent:</strong> ' + Utilities.formatDate(new Date(dataA.DateSent), 'GMT-6', "M/dd/yyyy HH:mm:ss") + '</div>';
}
s+='<br /><input type="button" value="Exit" onClick="google.script.host.close();" /><input type="button" value="Archive Checked" onClick="getCheckedBoxes(\'email\');" />';
var html=HtmlService.createHtmlOutputFromFile('htmlToBody').setWidth(800).setHeight(250);
html.append(s);
SpreadsheetApp.getUi().showModelessDialog(html, 'Select Emails to Archive');
}
Here's the html file 'htmlToBody':
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
function getCheckedBoxes(chkboxName) {
var checkboxes = document.getElementsByName(chkboxName);
var rowsToArchive = [];
for (var i=0; i<checkboxes.length; i++)
{
if (checkboxes[i].checked)
{
rowsToArchive.push(Number(checkboxes[i].value));
}
}
google.script.run
.withSuccessHandler(setResponse)
.archiveSelectedRows(rowsToArchive);
}
function setResponse(a)
{
var s='<br />Rows: ';
for(var i=0;i<a.length;i++)
{
if(i>0)
{
s+=', ';
}
s+=a[i];
var id='#row' + a[i]
$(id).css('display','none');
}
s+='<br />Total: ' + a.length;
google.script.run.displayMessage(s,'Archived Rows')
}
console.log('script here');
</script>
</head>
<body>
I took your project idea and ran with it a little.
These are the google scripts. You'll notice I started with the name of your function.
function openCancelDialog1()
{
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sht=ss.getSheetByName('Projects');
var rng=sht.getDataRange();
var rngA=rng.getValues();
var s='';
for(var i=1;i<rngA.length;i++)
{
var dataA={};
for(var j=0;j<rngA[0].length;j++)
{
dataA[rngA[0][j]]=rngA[i][j];
}
var row=Number(i+1);
s+='<div id="row' + row + '"><input type="checkbox" name="project" value="' + row + '" />' + ' <strong>Row:</strong> ' + Number(i+1) + ' <strong>Name:</strong> ' + dataA.Name + ' <strong>Project:</strong> ' + dataA.Description + '</div>';
}
s+='<br /><input type="button" value="Exit" onClick="google.script.host.close();" /><input type="button" value="Cancel and Archive Checked" onClick="getCheckedBoxes(\'project\');" />';
var html=HtmlService.createHtmlOutputFromFile('htmlToBody').setWidth(800).setHeight(250);
html.append(s);
SpreadsheetApp.getUi().showModelessDialog(html, 'Select Project to Cancel');
}
function archiveSelectedRows(rows)
{
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sht=ss.getSheetByName('Projects');
var dest=ss.getSheetByName('ArchivedProjects');
var rng=sht.getDataRange();
var rngA=rng.getValues();
var deleted=[];
for(var i=rngA.length-1;i>1;i--)
{
if(rows.indexOf(i+1)>-1)
{
deleted.push(Number(i+1));
rngA[i][4]=Utilities.formatDate(new Date(), 'GMT-7', 'M/d/yyyy')
dest.appendRow(rngA[i]);
sht.deleteRow(i+1);
}
}
var msg='Row Numbers Deleted = ' + deleted;
var title='Rows Deleted';
var timeout=10;
return deleted;
}
function displayMessage(msg,title)
{
msg+='<br /><input type="button" value="Exit" onClick="google.script.host.close()"; />';
var html=HtmlService.createHtmlOutput(msg).setWidth(400).setHeight(300);
SpreadsheetApp.getUi().showModelessDialog(html, title);
}
This is the htmlTobody file. It's been modified a bit for this situation.
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
function getCheckedBoxes(chkboxName) {
var checkboxes = document.getElementsByName(chkboxName);
var rowsToArchive = [];
for (var i=0; i<checkboxes.length; i++)
{
if (checkboxes[i].checked)
{
rowsToArchive.push(Number(checkboxes[i].value));
}
}
google.script.run
.withSuccessHandler(setResponse)
.archiveSelectedRows(rowsToArchive);
}
function setResponse(a)
{
var s='<br />Row Numberss: ';
for(var i=0;i<a.length;i++)
{
if(i>0)
{
s+=', ';
}
s+=a[i];
var id='#row' + a[i]
$(id).css('display','none');
}
s+='<br />Total: ' + a.length;
google.script.run.displayMessage(s,'Canceled Rows')
}
console.log('script here');
</script>
</head>
<body>
And this is what my 'Projects' tab looks like. And I have a Projects tab and an ArchivedProjects tab. When I archive the projects they get copied into the ArchivedProjects sheet.

How to display user input data stored in array, using HTML table

I'm kinda new to html/javascript. I wanted to store the user input value in array (already done this part) and display it into HTML table(I'm stuck at this one). When user press the button, the table will show up at the bottom.
Here's my code so far:
HTML
<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script class="jsbin" src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style>
article, aside, figure, footer, header, hgroup,
menu, nav, section { display: block; }
</style>
</head>
<body>
<form>
<h1>Please enter data</h1>
<input id="title" type="text" placeholder="Title" />
<input id="name" type="text" placeholder="Name" />
<input id="tickets" type="text" placeholder="Tickets" />
<input type="button" value="Save/Show" onclick="insert()" />
</form>
<div id="display"></div>
</body>
</html>
This is my Javascript code:
var titles = [];
var names = [];
var tickets = [];
var titleInput = document.getElementById("title");
var nameInput = document.getElementById("name");
var ticketInput = document.getElementById("tickets");
var messageBox = document.getElementById("display");
function insert ( ) {
titles.push( titleInput.value );
names.push( nameInput.value );
tickets.push( ticketInput.value );
clearAndShow();
}
function clearAndShow () {
// Clear our fields
titleInput.value = "";
nameInput.value = "";
ticketInput.value = "";
// Show our output
messageBox.innerHTML = "";
messageBox.innerHTML += "<tr>Titles</tr>" + titles.join(" ") + "<td></td>";
messageBox.innerHTML += "<tr>Name</tr> <td>" + names.join(" ") + "</td>";
messageBox.innerHTML += "<tr>tickets</tr> <td>" + tickets.join(" ")+ "</td>";
}
I can't display the array into the tables. I'm quite new to Javascript/HTML so any help would be appreciated. :D
As I have already commented, you will have to loop over array and compute html and set it. Your function clearAndShow will set last value only.
I have taken liberty to update your code. You should not save data in different arrays. Its better to use one array with proper constructed object.
JSFiddle
var data = [];
var titleInput = document.getElementById("title");
var nameInput = document.getElementById("name");
var ticketInput = document.getElementById("tickets");
var messageBox = document.getElementById("display");
function insert() {
var title, name, ticket;
title = titleInput.value;
name = nameInput.value;
ticket = ticketInput.value;
data.push({
title: title,
name: name,
ticket: ticket
});
clearAndShow();
}
function clearAndShow() {
// Clear our fields
titleInput.value = "";
nameInput.value = "";
ticketInput.value = "";
messageBox.innerHTML = computeHTML();
}
function computeHTML() {
var html = "<table>";
console.log(data)
data.forEach(function(item) {
html += "<tr>";
html += "<td>" + item.title + "</td>"
html += "<td>" + item.name + "</td>"
html += "<td>" + item.ticket + "</td>"
html += "</tr>";
});
html += "</table>"
return html;
}
article,
aside,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<head>
<script class="jsbin" src=""></script>
<script class="jsbin" src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
<body>
<form>
<h1>Please enter data</h1>
<input id="title" type="text" placeholder="Title" />
<input id="name" type="text" placeholder="Name" />
<input id="tickets" type="text" placeholder="Tickets" />
<input type="button" value="Save/Show" onclick="insert()" />
</form>
<div id="display"></div>
</body>
Please try and change your js code like below, not the most elegant but a start:
function clearAndShow () {
// Clear our fields
titleInput.value = "";
nameInput.value = "";
ticketInput.value = "";
// Show our output
messageBox.innerHTML = "";
messageBox.innerHTML += "<tr>";
messageBox.innerHTML += "<td>Titles</td>";
messageBox.innerHTML += "<td>Name</td>";
messageBox.innerHTML += "<td>Tickets</td>";
messageBox.innerHTML += "</tr>";
for(i = 0; i <= titles.length - 1; i++)
{
messageBox.innerHTML += "<tr>";
messageBox.innerHTML += "<td>" + titles[i]+ "</td>";
messageBox.innerHTML += "<td>" + names[i] + "</td>";
messageBox.innerHTML += "<td>" + tickets[i]+ "</td>";
messageBox.innerHTML += "</tr>";
}
}
and your display html like so:
<table id="display"></table>
have a look at fiddle over here https://jsfiddle.net/gvanderberg/cwmzyjf4/
The data array in Rajesh's example is the better option to go for.
you deleted your last question about the numbering of authors, but I wrote a big answer to you for it. Just for you to have it :
Wow, man you have several problems in your logic.
First, you have to specify to your form not to submit when you click on one or the other submit buttons (Add a book, or Display book) :
<form onsubmit="return false;">
Second, you have to define your numbering var to 0 and use it when you want to assign a number to a book :
var numbering = 0;
Then, in your addBook function, you have to use that global numbering variable to set you no variable :
function addBook() {
numbering++; // increments the number for the books (1, 2, 3, etc)
var no, book, author;
book = bookInput.value;
author = nameInput.value;
no = numbering;
...
}
Then you have all kind of mistakes like double ";" on certain lines etc.
A huge mistake is also done on your code when you use "forEach". Notice this function only works when you use jQuery library ! You have to include it before you use it :
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
An other huge mistake you do is that your "Display" button has the id "display" and your messageBox also has this id. This is forbidden because when you want to use the element which has this ID, Javascript won't know which of the two is the good one. So rename your button id in displayAuthors :
<input type="submit" id="displayAuthors" value="Display" onclick="displayBook()" />
Now, what you also can do, is to call your displayBooks function everytime you add a new book like this :
function addBook() {
numbering++;
var no, book, author;
book = bookInput.value;
author = nameInput.value;
no = numbering;
data.push({
book: book,
author: author,
no: no
});
displayBook();
}
So I did all these things here on CodePen : https://codepen.io/liorchamla/pen/JMpoxM
The JQuery solution
Here you used the basics of Javascript (called Vanilla JS) which is very cool because you have to learn it, but I also wrote you a CodePen to show you how you could have done this with jQuery :-)
Here it is : http://codepen.io/liorchamla/pen/oxwNwd
Basicly, the javascript changed to this :
$(document).ready(function(){
var data = []; // data is an empty array
// binding the addBook button with the action :
$('#addBook').on('click', function(){
var book = {
title: $('#bookname').val(),
author: $('#authors').val(),
// note we won't use a numbering variable
};
data.push(book);
// let's automaticly trigger the display button ?
$('#displayBooks').trigger('click');
});
// binding the displayBooks button with the action :
$('#displayBooks').on('click', function(){
$('#display').html(computeHTML());
});
function computeHTML(){
// creating the table
html = "<table><tr><th>No</th><th>Book</th><th>Author</th></tr>";
// for each book in the data array, we take the element (book) and the index (number)
data.forEach(function(element, index){
// building the table row, note that index starts at 0, so we increment it to have a start at 1 if it is 0, 2 if it is 1 etc.
html += "<tr><td>" + parseInt(index++) + "</td><td>" + element.title + "</td><td>" + element.author + "</td></tr>";
})
html += "</table>";
// returning the table
return html;
}
})
You might find it complicated, but with time you will see that jQuery helps a lot !
They are lot of things we could enpower in this script but this is a good starting, don't you think ?
Cheers from Marseille, France !

JQuery - clone element and change attributes for multiple attributes

I have several elements like this:
<div class="image_insert clearfix">
<label for="userfile3">Image 3</label>
<input type="file" name="userfile3" id="userfile3">
<label for="slika_naziv_eng3">Image Title</label>
<input type="text" name="slika_naziv_eng3" id="slika_naziv_eng3"/>
</div>
And JS for cloning:
var img_add = $('.img_add');
img_add.on('click', function(){
var img_ins = $('.image_insert'),
i = img_ins.length,
clon = img_ins.first().clone().attr({'class' : 'image_insert clearfix', 'name' : 'userfile' + i}).insertAfter(img_ins.last());
});
I need to change all attributes where there is a number. Every time new element is added, it needs to count number of elements and the new number will be number of elements + 1. How can I do this?
I've grabbed this from something similar id written in the past
$("#containerDiv").find("div").each(function(){
lastVersionNumber = jQuery(this).attr("id").replace(/\D/g, "")/1;
});
newVersionNumber = lastVersionNumber + 1;
# build the new version HTML string
var sHTML = "<div name='mydiv'>";
sHTML += jQuery("#templateCode").html()
sHTML = sHTML.replace(/<input/i, "<input name='v"+newVersionNumber+"_name'");
sHTML += "</div>";
$("#containerDiv").append(sHTML);
try this: clon contains the new element, so, you need to find your element
<!DOCTYPE html>
<html>
<head>
<title>Clone Elements with Jquery by #MaoAiz + Sasha</title>
</head>
<body>
<button class="img_add">New</button>
<div class="image_insert clearfix">
<label for="userfile1" class="img-label">Image 1</label>
<input type="file" name="userfile1" id="userfile1">
<label for="slika_naziv_eng1">Image Title</label>
<input type="text" name="slika_naziv_eng1" id="slika_naziv_eng1"/>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script>
var img_add = $('.img_add');
img_add.on('click', function(){
var img_ins = $('.image_insert'),
i = img_ins.length + 1;
clon = img_ins.first().clone().insertAfter(img_ins.last());
// clon contains the new element, so, you need to find your element
clon.find("input").first().attr({
'name' : 'userfile' + i,
'id' : 'userfile' + i
});
clon.find("input").last().attr({
'name' : 'slika_naziv_eng' + i,
'id' : 'slika_naziv_eng' + i
});
//plus:
clon.find(".img-label").text("Image " + i)
// view you cosole in Chrome Ctrl + Shift + j
console.log("Elements: " + i)
});
</script>
</body>
</html>
I have a demo in github. https://github.com/MaoAiz/Formulario-Dinamico-JQuery

Categories