Append table with jQuery after submitting form does not display - javascript

I have an HTML where I have a table that will fill with books info that can be added with a form.
I also have a js file where I'm using jQuery (just for practice) and I have created a Book constructor for every book object that is created. Every book is stored in an array (library) and each element will be a row in the HTML table. The problem is whenever I try to append my table with a new book object after submitting the form I see the new row for 1 second and then not displaying. Probably its a DOM loading problem, but I can't find a way.
Here is my HTML and JavaScript:
let library=[];
let book;
function Book(title,author,number_of_pages,read){
this.title=title;
this.author=author;
this.number_of_pages=number_of_pages;
this.read=read;
}
function addBook(title,author,number_of_pages,read){
let book=new Book(title,author,number_of_pages,read);
library.push(book);
}
addBook("Hobbit1","Tolkien",130,"read");
$(document).ready(function(){
//Show form to add a new Book
$("#newBook").on("click",function(){
$("form").slideDown(500);
})
$("#addBook").on("submit",function(){
let title=$("#title").val();
let author=$("#author").val();
let number_of_pages=$("#number_of_pages").val();
let read=$("#read").val();
addBook(title,author,number_of_pages,read);
})
//Remove rows
$(document).on("click", "#delete", function(){
$(this).closest('tr').remove();
library.splice(library.findIndex(x=>x.title==$(this).attr('class')),1);
});
function showLibrary()
{
library.forEach(function (item,index){
$("#books tbody").append("<tr> <td>"+item.title+"</td> <td> "+item.author+"<td> "+item.number_of_pages+"</td> <td> "+item.read+"</td> <td> <button id=delete class="+item.title+">Delete</button> </td> </tr>");
})
}
showLibrary();
});
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="mystyle.css">
<title>Whatever</title>
</head>
<body>
<h2>Books</h2>
<div id="books">
<table>
<thead><tr><th>Title</th><th>Author</th><th>Pages</th><th>Read</th></tr></thead>
<tbody>
</tbody>
</table>
</div>
<button id="newBook">New Book</button>
<form id="addBook" hidden>
<label>Title:</label><br>
<input id="title" type="text" name="title"><br>
<label>Author:</label><br>
<input id="author" type="text" name="author"><br>
<label>Number of pages:</label><br>
<input id="number_of_pages" type="text" name="number_of_pages"><br>
<label>Have you read this book ?:</label><input id="read" type="checkbox" name="read"><br>
<input type="submit" value="Add Book">
</form>
</body>
</html>
I know maybe it would be better to work with pure JavaScript and not jQuery but I just want to practice a little in jQuery.

The problems in your code:
You must prevent the form from submiting and refreshing the page. Use return false on the onsubmit for this. (thats the reason of the blank page after submission):
<form id="addBook" onsubmit="return false" hidden>
</form>
After adding a book, you must call showLibrary() in order for it to appear in the table:
$("#addBook").on("submit",function(){
//...
//...
//rerender the library after book add
showLibrary();
})
You must clear the table tbody before rerendering the library:
function showLibrary()
{
//Clear the tbody before rendering library:
$("#books tbody").html('');
//...
//...
}
Here is your original code, with these three updates:
let library=[];
let book;
function Book(title,author,number_of_pages,read){
this.title=title;
this.author=author;
this.number_of_pages=number_of_pages;
this.read=read;
}
function addBook(title,author,number_of_pages,read){
let book=new Book(title,author,number_of_pages,read);
library.push(book);
}
addBook("Hobbit1","Tolkien",130,"read");
$(document).ready(function(){
//Show form to add a new Book
$("#newBook").on("click",function(){
$("form").slideDown(500);
})
$("#addBook").on("submit",function(){
let title=$("#title").val();
let author=$("#author").val();
let number_of_pages=$("#number_of_pages").val();
let read=$("#read").val();
addBook(title,author,number_of_pages,read);
//rerender the library after book add
showLibrary();
})
//Remove rows
$(document).on("click", "#delete", function(){
$(this).closest('tr').remove();
library.splice(library.findIndex(x=>x.title==$(this).attr('class')),1);
});
function showLibrary()
{
//Clear the tbody before rendering library:
$("#books tbody").html('');
library.forEach(function (item,index){
$("#books tbody").append("<tr> <td>"+item.title+"</td> <td> "+item.author+"<td> "+item.number_of_pages+"</td> <td> "+item.read+"</td> <td> <button id=delete class="+item.title+">Delete</button> </td> </tr>");
})
}
showLibrary();
});
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="mystyle.css">
<title>Whatever</title>
</head>
<body>
<h2>Books</h2>
<div id="books">
<table>
<thead><tr><th>Title</th><th>Author</th><th>Pages</th><th>Read</th></tr></thead>
<tbody>
</tbody>
</table>
</div>
<button id="newBook">New Book</button>
<form id="addBook" onsubmit="return false" hidden>
<label>Title:</label><br>
<input id="title" type="text" name="title"><br>
<label>Author:</label><br>
<input id="author" type="text" name="author"><br>
<label>Number of pages:</label><br>
<input id="number_of_pages" type="text" name="number_of_pages"><br>
<label>Have you read this book ?:</label><input id="read" type="checkbox" name="read"><br>
<input type="submit" value="Add Book">
</form>
</body>
</html>

Related

How to using angular ng-view keeps content in input field

I am new to AngularJS and working on a small project. I want to build an editable table for courses including course Id and course Name. Users are able to click edit button and then they can edit content.
Howwever,I met a problem that when user clicks edit button, all the content just gone, like delete, but I want to keep the content editable. I try ng-value, but didn't work.
Here is my code and codepen link: http://codepen.io/marong125/pen/JRBQdo
Thank you so much!
<html>
<head>
<title>Online Learning</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-route.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-resource.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script>
var app = angular.module('app', []);
app.controller('courseController', function ($scope) {
$scope.courses = [
{
courseID: "CS602",
courseName: "Web Development",
isEditing:false
},
{
courseID: "CS502",
courseName: "Foundation of Java",
isEditing:false
}
];
$scope.addCourse = ()=>{
$scope.courses.push({
courseID: $scope.createIdInput,
courseName: $scope.createCourseInput
});
$scope.createIdInput = '';
$scope.createCourseInput = '';
console.log(1);
}
$scope.onEditClick = (course)=>{
course.isEditing = true;
}
});
</script>
</head>
<body ng-app="app">
<<h1>Course Manager</h1>
<div ng-controller = "courseController">
<form name="courseForm">
<input id="c_id_input" placeholder="Add course ID" ng-model="createIdInput" />
<input id= "c_name_input" placeholder="Add course name" ng-model="createCourseInput" />
<button class="btn btn-success pull-right" ng-click="addCourse()">Add Course</button>
</form>
<table class="table table-striped table-bordered table-condensed table-hover">
<tr>
<th>Course ID</th>
<th>Course Name</th>
<th>Actions</th>
</tr>
<tr ng-repeat = "course in courses">
<td>
<span ng-if="!course.isEditing" >{{course.courseID}}</span>
<form ng-submit="updateTask(course)">
<input type="text" ng-if="course.isEditing" class="form-control"
ng-value="course.courseID" ng-model="updatedCourseId" />
</form>
</td>
<td>
<span ng-if="!course.isEditing">{{course.courseName}}</span>
<form >
<input ng-if="course.isEditing" class="form-control"
ng-value="course.courseName" ng-model="updatedCourseName" />
</form>
</td>
<td>
<button class="btn btn-info" ng-click="onEditClick(course)" >Edit</button>
<button class="btn btn-danger">Delete</button>
</td>
</tr>
</table>
</div>
</body>
</html>
This is happening because of your ng-model in the edit fields. If you look closely you will find that ng-model for your ID field in updatedCourseId and Name is updatedCourseName. However your actual values are stored in course.courseID and course.courseName. Change your ng-model and point to the correct variables.
<input type="text" ng-if="course.isEditing" class="form-control"
ng-value="course.courseID" ng-model="updatedCourseId" />
<input ng-if="course.isEditing" class="form-control"
ng-value="course.courseName" ng-model="updatedCourseName" />
Alternatively
If you don't want to mix up the updated value and the non-updated value you can do that by copying the current value to another field when the user clicks on edit. I have created a codepen to demonstrate this, you can see it here.
JavaScript (Controller)
$scope.onEditClick = (course) => {
course.isEditing = true;
course.updatedCourseId = course.courseID;
course.updatedCourseName = course.courseName;
}
HTML
<input type="text" ng-if="course.isEditing" class="form-control"
ng-model="course.updatedCourseId" />
<input ng-if="course.isEditing" class="form-control"
ng-model="course.updatedCourseName" />
I think you are misunderstanding how ng-model works. ng-model represents the variable that your data is saved in, and it's a two way binding. You don't need a separate variable to store the "updated" values.
Instead of:
<input type="text" ng-if="course.isEditing" class="form-control"
ng-value="course.courseID" ng-model="updatedCourseId" />
you should use:
<input type="text" ng-if="course.isEditing" class="form-control"
ng-model="course.courseID" />
The changes will automatically be reflected, in real time, back to the array.

I cannot get 2 usually simple javascript functions to work with my PHP files

I am setting up a simple php form to collect entries and insert/show them to a myphpmyAdmin db, this works fine. The little problem I'm having is when i try to put in a small bit of js to clear text and also give a popup alert, neither will work, can somebody help me please.
Here is my Javascript file:
function clear(){
document.getElementById("in1", "in2", "in3", "in4", "in5",).value= "";
}
function saved() {
alert("Well done yourself, you have saved an entry to the database.");
}
And here is my php file:
<html>
<head>
<meta charset="utf-8">
<title>CS230 Assignment 3</title>
<link rel="stylesheet" href="style1.css" type="text/css" media="all" />
<script src="myjs.js" type="text/javascript"></script>
</head>
<body>
<h3>Diary:</h3>
<form action="insert.php" method="post">
<div id="table">
<table>
<tr>
<th>When/Where</th>
<th>Event</th>
<th>Emotion</th>
<th>Automatic Thoughts</th>
<th>Rational Response</th>
</tr>
<tr>
<td><input type="text" style="height:500px;" name="in1" id="in1"></td>
<td><input type="text" style="height:500px;" name="in2" id="in2"></td>
<td><input type="text" style="height:500px;" name="in3" id="in3"></td>
<td><input type="text" style="height:500px;" name="in4" id="in4"></td>
<td><input type="text" style="height:500px;" name="in5" id="in5"></td>
</tr>
</table>
</div>
<div id="buttons">
<input type="submit" name="save" id="save" value="Save Entry" onclick="saved()">
</div>
</form>
<div id="clearButton">
<button id="clear" onClick="clear();">clear</button>
</div>
<form action="show.php" method="post">
<input type="submit" name="show" id="show" value="Show Diary">
</form>
</body>
</html>
The document.getElementById() function takes one argument. If you want to fetch a list of elements, you can use .querySelectorAll():
var elements = document.querySelectorAll("#in1, #in2, #in3, #in4, #in5");
That returns a node list, so you'll have to iterate to perform an operation on each one:
function clear(){
var elements = document.querySelectorAll("#in1, #in2, #in3, #in4, #in5");
for (var i = 0; i < elements.length; ++i)
elements[i].value = "";
}
edit — you'll probably want to use a name other than "clear" as "clear" is likely to collide with something; in-line event handlers are highly susceptible to that sort of issue. Alternatively you could explicitly reference window.clear():
<button id="clear" onClick="window.clear();">clear</button>

Set form action dynamically depending on the field filled in by user

I'd like to have a few different options that all map to different actions, but I only want one submit button. I cannot for the life of me get this to work. Here is the code I have so far:
<!DOCTYPE html>
<html lang="en-US">
<head>
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/main.css') }}">
<meta charset="UTF-8">
</head>
<body>
<script type=text/javascript>
function clicked() {
document.getElementById('id').action = "/query";
document.getElementById('filename').action = "/fname";
document.getElementById('dep').action = "/dependency";
return true;
}
</script>
<div id="header">
<h1>TestPy</h1>
</div>
<hr>
<div id="wrapper">
<div class="query-menu" id="nav">
<form name="query_form" id="query" onsubmit="clicked()" method=post>
<fieldset class="fieldset-auto-width">
<legend>Query</legend>
<table style="width:25%">
<tr>
<td>Plugin ID:</td>
<td><input type=text name=script_id id="id" placeholder="19506"></td>
</tr>
<tr>
<td>Filename Search:</td>
<td><input type=text name=filename id="fname" placeholder="test.file"></td>
</tr>
<tr>
<td>Dependency:</td>
<td><input type=text name=dep id="dep" placeholder="dependency"></td>
</tr>
<tr>
<th rowspan="2"><td><input type=submit value=Query class="btn"></td></th>
</tr>
</table>
</fieldset>
</form>
</div>
<div class="content" id="section">
{% block body %}{% endblock %}
</div>
</div>
</body>
</html>
What I'd like to do is have those three form fields each map back to a separate url, however I cannot get this to work. If I take the javascript out and hard code the URL, it works fine. HTML/JavaScript are not my strong language at all so I appreciate any feed back you can provide. Thanks!
I used the OnBlur method that triggers whenever a user leaves the input field.
<td><input type=text name=filename id="fname" onblur="myFunctionY()" placeholder="test.file"></td>
<td><input type=text name=dep id="dep" onblur="myFunctionY(this)" placeholder="dependency"></td>
<td><input type=text name=script_id id="id" onblur="myFunctionY(this)" placeholder="19506"></td>
In Javascript:
function myFunctionY(vari) {
console.log(vari.id);
if(vari.id=="fname")
{
var x = document.getElementById("fname");
var link='http://www.google.com?q='+x.value;
console.log("This is the URL "+link);
document.query_form.setAttribute("action",link);
}
if(vari.id=="id")
{
var x = document.getElementById("id");
var link='http://www.google.com?q='+x.value;
console.log("This is the URL "+link);
document.query_form.setAttribute("action",link);
}
if(vari.id=="dep")
{
var x = document.getElementById("dep");
var link='http://www.google.com?q='+x.value;
console.log("This is the URL "+link);
document.query_form.setAttribute("action",link);
}
}
You can have 3 functions/ as per your requirement.Upon submitting, it goes to the new action link.
Using jQuery, I'd do something like this:
$('#query').submit(function (e) {
// prevent the default action of form submission
e.preventDefault();
// create a variable using the 3 field values
$form_action = '/'+$('#id').val()+'/'+$('#fname').val()+'/'+$('#dep').val();
// set the form action attribute to the variable value
$(this).attr('action') = $form_action;
// submit the form as normal now that the action is changed
$(this).submit();
});

Submit specific form inside foreach loop

I'm trying to submit a form like below
{foreach from=$myInfo item=list}
<tr>
<td>
<form id="formq" method="post" action="{eval var=$rootPath}/devt/index?request=getme">
<input type="text" name="taskida" value="{$list.pa_id}" >
<input type="button" onclick="addFunction();" value="Add Task">
</form></td></tr>{/foreach}
How will I submit only the pa_idwhich I click submit and not the entire list.
<script type="text/javascript">
function addFunction() {
document.getElementById('formq').submit();
}
First of all, You can assign one id to only one element. You can NOT use single ID for mutliple elements on the same page.
For example in the loop you have multiple forms after execution of loop with the same id formq. That is wrong. You have to use unique ID for each element.
So try your code in something like this:
HTML/PHP
{foreach from=$myInfo item=list}
<tr>
<td>
<form id="formq_{$list.pa_id}" post" action="{eval var=$rootPath}/devt/index?request=getme">
<input type="text" name="taskida" value="{$list.pa_id}" >
<input type="button" onclick="addFunction({$list.pa_id});" value="Add Task">
</form></td></tr>
{/foreach}
Javascript
<script type="text/javascript">
function addFunction(id) {
document.getElementById('formq'+id).submit();
}
solved it
using $list.pa_id as form id and passing it to script
<input type="button" onclick="addFunction($list.pa_id);" value="Add Task">
<script type="text/javascript">
function addFunction(id) {
document.getElementById(id).submit();

Create a "calculation form" in javascript

so I have a project now, as an addition to my company's website, we want to show our clients how much they can save on gas by buying one of our electric cars, I'm responsible for making it happen, I don't know how to approach this using javascript, can you guys give me a hand? our marketing guy got the idea from this website, that is basically what we want, but I was hoping i could make it a little better on some aspects:
1st-the client wouldn't have to press submit to see the results, as they fill the last field, the calculated part is populated automatically, for this i've been fiddling with the onChange event, unsuccessfully though xD
here's what I have so far, it is not working, at least on dreamweaver's live mode, haven't tested it online yet as I was hoping to develop the whole thing offline:
<script type="text/javascript">
function calc(){
var km=document.getElementById(km).value;
var euro=document.getElementById(euro).value;
var consumo=document.getElementById(consumo).value;
var cem_km=consumo*euro;
var fossil_day=(cem_km*km)/100;
return fossil_day;
}
</script>
<form name="calc" id="calc" >
<p>
Km/dia
<input type="text" name="km" id="km" value="" />
</p>
<p>
€/Litro
<input type="text" name="euro" id="euro" value="" />
</p>
<p>
Litros/100km
<input type="text" onChange="calc()" name="consumo" id="consumo" value="" />
</p>
<input type="button" onClick="calc()" name="submit" id="submit" value="Calcular" />
<script type="text/javascript">
var fossil_day = calc();
document.write('<p>'+fossil_day+'</p>');
</script>
</form>
Please note that although I have this already, I wouldnt mind not doing this at all and using another solution, even if it doesnt use forms, I'm just showing what i have already so you can tell me how I'm wrong and how I can have a better approach at it
there are many errors inside your code
document.getElementById() needs the element id in brackets ''
you can't create a element with the same name,id as a function calc else it will throw an error as it's an object and not a function.
your executing the function onload... but you want it to be executed when the button is clicked & onchange.
you don't need to add value if empty and name if you use getElementById
return false in the function on buttons inside form else it could send the form and so refresh the page.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>calc</title>
<script>
function calc(){
var km=document.getElementById('km').value;
var euro=document.getElementById('euro').value;
var consumo=document.getElementById('consumo').value;
var cem_km=consumo*euro;
var fossil_day=(cem_km*km)/100;
document.getElementById('result').innerHTML=fossil_day;
return false
}
</script>
</head>
<body>
<form>
<p>Km/dia<input type="text" id="km"/></p>
<p>€/Litro<input type="text" id="euro" /></p>
<p>Litros/100km<input type="text" onChange="calc()" id="consumo" /></p>
<input type="button" onClick="calc()" value="Calcular" />
</form>
<div id="result"></div>
</body>
</html>
Useing jQuery (and html5 type="number" form fields):
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<form>
<p>
Km/dia
<input type="number" name="km" id="km" value="" />
</p>
<p>
€/Litro
<input type="number" name="euro" id="euro" value="" />
</p>
<p>
Litros/100km
<input type="number" name="consumo" id="consumo" value="" />
</p>
<div id="fossil-day"></div>
</form>
<script src="http://codeorigin.jquery.com/jquery-1.10.2.min.js"></script>
<script>
function calculate(){
var km = $('#km').val();
var euro = $('#euro').val();
var consumo = $('#consumo').val();
var cem_km = consumo*euro;
var fossil_day = (cem_km*km)/100;
$('#fossil-day').html(fossil_day);
}
$(function() {
/*when #consumo input loses focus, as per original question*/
$('#consumo').blur(function(){
calculate();
});
});
</script>
</body>
</html>

Categories