I am trying to remove item from the array by selecting a cell to the left of the button, I have tried using .previous selector but it doesn't work.
var films = [];
function test2(e) {
$("button").one("click", function(r) {
r.preventDefault();
var movie = $(e).attr("name");
if (films.includes(movie)) {
alert("This movie is in your basket")
} else {
films.push(movie);
var r = films.length;
$("#table1").empty();
for (var i = 0; i < r; i += 1) {
$("#table1").append("<tr><td>" + films[i] + "</td><td>" + "<button onclick='newtest2(this)'>Remove</button>" + "</td></tr>");
}
}
})
};
function newtest2(e) {
$(e).parents('tr').remove();
}
.cart {
float: right;
position: relative;
margin-right: 15%;
margin-top: 5%;
}
.cart2 {
background-color: white;
border-radius: 19px;
-moz-border-radius: 19px;
-webkit-border-radius: 19px;
padding: 2% 3%;
border: 2px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cart">
<div class="cart2">
<h1>Cart: </h1>
<table id="table1">
</table>
</div>
</div>
<button name="Black Mirror" id="BM" id="carttest" onclick="test2(this)" value="Black Mirror" class="button1">Book now (Black Mirror)</button>
<br>
<button name="Star Wars" id="SW" id="carttest" onclick="test2(this)" value="Star Wars" class="button1">Book now(Star Wars)</button>
I also have this bug that I have to click the button twice to fire the function.
Edit:
Whenever the user clicks Order button, it runs the loop that creates the table with a button "remove" and adds the item to 'Films[]' Array. I want the remove button to remove the selected row but I also want it to remove the item from the array.
Well it needs a lot of fixes in your code.
First. Identifiers must be unique for each element.
2nd. When you push in array, you'll have to remove it too.
Here is what was missing in your code
var films = [];
$(".button1").click(function(e){
var movie = $(this).attr("name");
if (films.includes(movie)) {
alert("This movie is in your basket")
} else {
films.push(movie);
var r = films.length;
$("#table1").empty();
for (var i = 0; i < r; i += 1) {
$("#table1").append("<tr><td>" + films[i] + "</td><td>" + "<button onclick='newtest2(this)'>Remove</button>" + "</td></tr>");
}
}
})
function newtest2(e) {
$(e).parents('tr').remove();
films.splice(films.indexOf($(e).parent().prev().text()), 1)
}
.cart {
float: right;
position: relative;
margin-right: 15%;
margin-top: 5%;
}
.cart2 {
background-color: white;
border-radius: 19px;
-moz-border-radius: 19px;
-webkit-border-radius: 19px;
padding: 2% 3%;
border: 2px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cart">
<div class="cart2">
<h1>Cart: </h1>
<table id="table1">
</table>
</div>
</div>
<button name="Black Mirror" id="BM" value="Black Mirror" class="button1">Book now (Black Mirror)</button>
<br>
<button name="Star Wars" id="SW" value="Star Wars" class="button1">Book now(Star Wars)</button>
Don't need prevent preventDefault() for a click
var films = [];
function test2(e) {
//Don't need preventDefault()
var movie = $(e).attr("name");
if (films.includes(movie)) {
alert("This movie is in your basket")
} else {
films.push(movie);
var r = films.length;
$("#table1").empty();
for (var i = 0; i < r; i += 1) {
$("#table1").append("<tr><td>" + films[i] + "</td><td>" + "<button onclick='newtest2(this)'>Remove</button>" + "</td></tr>");
}
}
};
function newtest2(e) {
const
//parents of the clicked button
parents = $(e).parents('tr'),
//children of the parents
children = parents.children(),
//text content from first child
text = children[0].textContent,
//position of the text in array
pos = $.inArray(text, films)
//if position is not -1 (not found)
if (pos !== -1 ) {
//use position to remove item from the array
films.splice(pos, 1)
}
console.log(`films:`,films)
//remove the tr element from the view
$(e).parents('tr').remove();
}
The muasif80's code works just fine too.
Related
In this test case, I am using append.child with plain JavaScript to add 3 kinds of divs (blue, red, green) to a parent multiple times according to their corresponding button onclicks, then I am adding another child inside the added div with another button (innerButton).
My issue is that, the onclick function which is assigned to the innerbutton and is nested within the initial function, listens only to the very first appended div, and it adds the input (which is supposed to be added to the div I'm clicking on) to the last append element of its 'kind'.
I am doing something wrong with my scoping but I can't see it.
I just started studying JavaScript, so I am not familiar yet with libraries, jQuery etc.
var countBlue = 0;
var countRed = 0;
var countGreen = 0;
function addBlue() {
var addTo = document.getElementById('div1')
var blue = document.createElement("div");
blue.id = "blueDiv";
blue.innerHTML = "<input id=blueInput><button id=innerButtonBlue onclick=addInputs()>ADD INPUTS</button>";
addTo.appendChild(blue);
document.getElementById("innerButtonBlue").onclick = function() {
var newInput = document.createElement("div");
newInput.innerHTML = '<input id="newInput" placeholder="NEW">';
blue.appendChild(newInput);
}
countBlue++;
}
function addRed() {
var addTo = document.getElementById('div1')
var red = document.createElement("div");
red.id = "redDiv";
red.innerHTML = "<input id=redInput><button id=innerButtonRed>ADD INPUTS</button>";
addTo.appendChild(red);
document.getElementById("innerButtonRed").onclick = function() {
var newInput = document.createElement("div");
newInput.innerHTML = '<input id="newInput" placeholder="NEW">';
red.appendChild(newInput);
}
countRed++;
}
function addGreen() {
var addTo = document.getElementById('div1')
var green = document.createElement("div");
green.id = "greenDiv";
green.innerHTML = "<input id=greenInput><button id=innerButtonGreen>ADD INPUTS</button>";
addTo.appendChild(green)
document.getElementById("innerButtonGreen").onclick = function() {
var newInput = document.createElement("div");
newInput.innerHTML = '<input id="newInput" placeholder="NEW">';
green.appendChild(newInput);
}
countGreen++;
}
function displayCounters() {
alert("Blue divs amount : " + parseInt(countBlue) + "\n" + " Red divs amount : " + parseInt(countRed) + "\n" + " Green divs amount : " + parseInt(countGreen) + "\n" + "\n" + " All together is : " + (parseInt(countBlue) + parseInt(countRed) + parseInt(countGreen)))
}
button {
margin-bottom: 10px;
}
#blueDiv {
margin-top: 10px;
margin-bottom: 10px;
width: 300px;
}
#redDiv {
margin-top: 10px;
margin-bottom: 10px;
width: 300px;
}
#greenDiv {
margin-top: 10px;
margin-bottom: 10px;
width: 300px;
}
input {
text-align: center;
}
#innerButtonRed {
position: relative;
float: right;
}
#innerButtonBlue {
position: relative;
float: right;
}
#innerButtonGreen {
position: relative;
float: right;
}
#newInput {
margin-top: 2px;
width: 162px;
height: 23px;
}
#redInput {
background: red;
}
#blueInput {
background: blue;
}
#greenInput {
background: green;
}
<html>
<body>
<script src="test.js"></script>
<link rel="stylesheet" type="text/css" href="test.css">
<button onclick="addBlue()">BLUE</button>
<button onclick="addRed()">RED</button>
<button onclick="addGreen()">GREEN</button>
<button onclick="displayCounters()">COUNTERS</button>
<div id="div1"></div>
</body>
</html>
The first thing you need to know is that, although you can technically add the same id to multiple elements, it is bad practice to do so. The id of an element should be unique. If you need to apply the same style or target multiple elements with your code you should use class instead of id.
I think that's what is causing issues in your code.
Second, since you say you are learning, i think it would be good if you tried to make a single function to add the elements since the code is repeated in all of the three functions, except for the color.
Try making the function accept the color as a variable so you can reuse it for the three colors. Imagine if it was a hundred colors.
var countBlue = 0;
var countRed = 0;
var countGreen = 0;
function addBlue() {
var addTo = document.getElementById('div1')
var div = document.createElement("div");
countBlue++; //set the counter to one so ids don't start at zero
div.id = `blueDiv-${countBlue}`; //creates a unique id depending on the counter
div.classList = "blueDiv";
div.innerHTML = `<input id="blueInput-${countBlue}" class="blueInput"><button id="innerButtonBlue-${countBlue}" onclick="addInputs">ADD INPUTS</button>`;
addTo.appendChild(div);
document.getElementById(`innerButtonBlue-${countBlue}`).onclick = function() {
var newInput = document.createElement("div");
newInput.innerHTML = `<input id="newInput-blue-${countBlue}" class="newInput" placeholder="NEW">`;
div.appendChild(newInput);
}
}
function addRed() {
var addTo = document.getElementById('div1')
var div = document.createElement("div");
countRed++
div.id = `redDiv-${countRed}`;
div.classList = "redDiv";
div.innerHTML = `<input id="redInput-${countRed}" class="redInput"><button id="innerButtonRed-${countRed}" onclick="addInputs">ADD INPUTS</button>`;
addTo.appendChild(div);
document.getElementById(`innerButtonRed-${countRed}`).onclick = function() {
var newInput = document.createElement("div");
newInput.innerHTML = `<input id="newInput-red-${countRed}" class="newInput" placeholder="NEW">`;
div.appendChild(newInput);
}
}
function addGreen() {
var addTo = document.getElementById('div1')
var div = document.createElement("div");
countGreen++
div.id = `greenDiv-${countGreen}`;
div.classList = "greenDiv";
div.innerHTML = `<input id="greenInput-${countGreen}" class="greenInput"><button id="innerButtonGreen-${countGreen}" onclick="addInputs">ADD INPUTS</button>`;
addTo.appendChild(div);
document.getElementById(`innerButtonGreen-${countGreen}`).onclick = function() {
var newInput = document.createElement("div");
newInput.innerHTML = `<input id="newInput-green-${countGreen}" class="newInput" placeholder="NEW">`;
div.appendChild(newInput);
}
}
function displayCounters() {
alert("Blue divs amount : " + parseInt(countBlue) + "\n" + " Red divs amount : " + parseInt(countRed) + "\n" + " Green divs amount : " + parseInt(countGreen) + "\n" + "\n" + " All together is : " + (parseInt(countBlue) + parseInt(countRed) + parseInt(countGreen)))
}
button {
margin-bottom: 10px;
}
.blueDiv {
margin-top: 10px;
margin-bottom: 10px;
width: 300px;
}
.redDiv {
margin-top: 10px;
margin-bottom: 10px;
width: 300px;
}
.greenDiv {
margin-top: 10px;
margin-bottom: 10px;
width: 300px;
}
input {
text-align: center;
}
.innerButtonRed {
position: relative;
float: right;
}
.innerButtonBlue {
position: relative;
float: right;
}
.innerButtonGreen {
position: relative;
float: right;
}
.newInput {
margin-top: 2px;
width: 162px;
height: 23px;
}
.redInput {
background: red;
}
.blueInput {
background: blue;
}
.greenInput {
background: green;
}
<button onclick="addBlue()">BLUE</button>
<button onclick="addRed()">RED</button>
<button onclick="addGreen()">GREEN</button>
<button onclick="displayCounters()">COUNTERS</button>
<div id="div1"></div>
IDs need to be unique in the whole document. Don't use IDs for this, you can just use a class. But even with a class how is the code supposed to know which element it should look for since there will be more than one existing with the class? The solution is to search only inside the element that you just created (e.g. blue.querySelector('.someClass') to search for the first element with class someClass inside the blue element).
I changed your code to use classes everywhere:
var countBlue = 0;
var countRed = 0;
var countGreen = 0;
function addBlue() {
var addTo = document.getElementById('div1')
var blue = document.createElement("div");
blue.className = "blueDiv";
blue.innerHTML = "<input class='firstInput'><button class='innerButton'>ADD INPUTS</button>";
addTo.appendChild(blue);
blue.querySelector(".innerButton").onclick = function() {
var newInput = document.createElement("div");
newInput.innerHTML = '<input class="newInput" placeholder="NEW">';
blue.appendChild(newInput);
}
countBlue++;
}
function addRed() {
var addTo = document.getElementById('div1')
var red = document.createElement("div");
red.className = "redDiv";
red.innerHTML = "<input class='firstInput'><button class='innerButton'>ADD INPUTS</button>";
addTo.appendChild(red);
red.querySelector(".innerButton").onclick = function() {
var newInput = document.createElement("div");
newInput.innerHTML = '<input class="newInput" placeholder="NEW">';
red.appendChild(newInput);
}
countRed++;
}
function addGreen() {
var addTo = document.getElementById('div1')
var green = document.createElement("div");
green.className = "greenDiv";
green.innerHTML = "<input class='firstInput'><button class='innerButton'>ADD INPUTS</button>";
addTo.appendChild(green)
green.querySelector(".innerButton").onclick = function() {
var newInput = document.createElement("div");
newInput.innerHTML = '<input class="newInput" placeholder="NEW">';
green.appendChild(newInput);
}
countGreen++;
}
function displayCounters() {
alert("Blue divs amount : " + parseInt(countBlue) + "\n" + " Red divs amount : " + parseInt(countRed) + "\n" + " Green divs amount : " + parseInt(countGreen) + "\n" + "\n" + " All together is : " + (parseInt(countBlue) + parseInt(countRed) + parseInt(countGreen)))
}
button {
margin-bottom: 10px;
}
.blueDiv {
margin-top: 10px;
margin-bottom: 10px;
width: 300px;
}
.redDiv {
margin-top: 10px;
margin-bottom: 10px;
width: 300px;
}
.greenDiv {
margin-top: 10px;
margin-bottom: 10px;
width: 300px;
}
input {
text-align: center;
}
.redDiv .innerButton {
position: relative;
float: right;
}
.blueDiv .innerButton {
position: relative;
float: right;
}
.greenDiv .innerButton {
position: relative;
float: right;
}
.newInput {
margin-top: 2px;
width: 162px;
height: 23px;
}
.redDiv .firstInput {
background: red;
}
.blueDiv .firstInput {
background: blue;
}
.greenDiv .firstInput {
background: green;
}
body {
height: 800px; /* Just for visibility here in Stack Overflow */
}
<html>
<body>
<script src="test.js"></script>
<link rel="stylesheet" type="text/css" href="test.css">
<button onclick="addBlue()">BLUE</button>
<button onclick="addRed()">RED</button>
<button onclick="addGreen()">GREEN</button>
<button onclick="displayCounters()">COUNTERS</button>
<div id="div1"></div>
</body>
</html>
There is a lot more that could be improved of course - the code duplication could be removed, a generalized function for all three types (red/green/blue) can be created that is differentiated just by an attribute on the button for example - but that's beyond the scope of this answer.
i have a code two filter a table by using color and value (refered to stackoverflow) , but am getting an error
Uncaught TypeError: Cannot read property 'addEventListener' of null .
It shows me this error .
$(document).ready(function(){
$('#load_data').click(function(){
$.ajax({
url:"OutputNew.csv",
dataType:"text",
success:function(data){
var employee_data = data.split(/\r?\n|\r/);
var table_data = '<button onclick="javascript:demoFromHTML()">PDF</button><input type="text" id="myInput" name="myInput" placeholder="color"><br><input type="text" id="myInputtext" name="myInput" placeholder="First Name"><br><div id="VMTable"><table id="myTable" class="table table-striped"">';
// var table_data = '<input type="text" id="myInput" name="myInput" placeholder="color"><br><input type="text" id="myInputtext" name="myInput" placeholder="First Name"><br><table id="myTable" class="table table-striped"">';
for(var count = 0; count<employee_data.length; count++) {
var cell_data = employee_data[count].split(',');
table_data += '<tr>';
for(var cell_count=0; cell_count<cell_data.length; cell_count++){
if(count === 0){
table_data += '<th>'+cell_data[cell_count]+'</th>';
}else{
if(cell_data[cell_count] .includes("Not Matching")){
var ret = cell_data[cell_count].replace('Not Matching','');
if (ret == ""){
table_data += '<td>'+ret+'</td>'
}else{
table_data += '<td data-color="red"><span class="badge-danger">'+ret+'</span></td>'
}
}else if(cell_data[cell_count] .includes("Matching")){
var ret = cell_data[cell_count].replace('Matching','');
if (ret == ""){
table_data += '<td>'+ret+'</td>'
}else{
table_data += '<td data-color="green"><span class="badge-complete">'+ret+'</span></td>';
}
}else{
table_data += '<td>'+cell_data[cell_count]+'</td>';
}
}
}
table_data += '</tr>';
}
table_data += '</table>';
$('#employee_table').html(table_data);
}
});
});
});
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("myInputtext");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
if (tr[i].style.display !== "none") {
tr[i].style.display = "";
}
} else {
tr[i].style.display = "none";
}
}
}
if (filter==="") {
document.getElementById("myInput").value="";
document.getElementById("myInputtext").value="";
[...document.querySelectorAll("#myTable tbody tr")].forEach(el => { el.style.display = "" });
}
}
function filterTable(event) {
var filter = document.getElementById("myInput").value.toUpperCase();
var rows = document.querySelector("#myTable tbody").rows;
if (filter === "RED" || filter === "R" || filter === "RE") {
filter = "badge-danger";
} else if (filter === "GREEN" || filter === "G" || filter === "GR" || filter === "GRE" || filter === "GREE") {
filter = "badge-complete";
}
for (var i = 0; i < rows.length; i++) {
var Col1 = rows[i].cells[0].innerHTML;
var Col2 = rows[i].cells[1].innerHTML;
var Col3 = rows[i].cells[2].innerHTML;
if (Col1.indexOf(filter) > -1 ||
Col2.indexOf(filter) > -1 ||
Col3.indexOf(filter) > -1) {
if (rows[i].style.display !== "none") {
rows[i].style.display = "";
}
} else {
rows[i].style.display = "none";
}
}
if (filter==="") {
document.getElementById("myInput").value="";
document.getElementById("myInputtext").value="";
[...document.querySelectorAll("#myTable tbody tr")].forEach(el => { el.style.display = "" });
}
}
document.querySelector('#myInputtext').addEventListener('keyup', myFunction, false);
document.querySelector('#myInput').addEventListener('keyup', filterTable, false);
function demoFromHTML() {
var pdf = new jsPDF('p', 'pt', 'letter');
source = $('#VMTable')[0];
specialElementHandlers = {
'#bypassme': function(element, renderer) {
return true
}
};
margins = {
top: 80,
bottom: 60,
left: 40,
width: 522
};
// all coords and widths are in jsPDF instance's declared units
// 'inches' in this case
pdf.fromHTML(
source, // HTML string or DOM elem ref.
margins.left, // x coord
margins.top, {// y coord
'width': margins.width, // max width of content on PDF
'elementHandlers': specialElementHandlers
},
function(dispose) {
// dispose: object with X, Y of the last line add to the PDF
// this allow the insertion of new lines after html
pdf.save('Test.pdf');
}
, margins);
}
<!DOCTYPE html>
<html>
<head>
<style>
div#loadbutton {
margin-left: 158px;
}
h1#Heading {
margin-left: 154px;
}
td {
border: 1px solid black;
word-wrap: break-word;
}
.table-responsive {
min-height: .01%;
overflow-x: auto;
WIDTH: 223%;
MARGIN-LEFT: -205PX;
}
.badge-Nill {
display: inline-block;
min-width: 49px;
padding: 9px 9px;
font-size: 12px;
font-weight: 700;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: middle;
background-color: blue;
border-radius: 10px;
width: 127px;
}
.badge-danger {
display: inline-block;
min-width: 49px;
padding: 9px 9px;
font-size: 12px;
font-weight: 700;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: middle;
background-color: red;
border-radius: 10px;
width: 127px;
}
th {
text-align: left;
width: 152px;
}
table {
border-collapse: collapse;
table-layout: fixed;
width: 310px;
}
table td {
border: solid 1px #fab;
width: 100px;
word-wrap: break-word;
}
.badge-complete {
display: inline-block;
min-width: 49px;
padding: 9px 9px;
font-size: 12px;
font-weight: 700;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: middle;
background-color: limegreen;
border-radius: 10px;
width: 127px;
}
h1#Heading {
margin-left: 154px;
margin-top: -44px;
}
div#employee_table {
margin-left: 170px;
margin-right: 70px;
}
</style>
<link rel = "icon" href = "https://media.geeksforgeeks.org/wp-content/cdn-uploads/gfg_200X200.png" type = "image/x-icon">
<title>TValidator</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript" src="jspdf.debug.js"></script>
</head>
<body>
<div class="container">
<div class="table-responsive">
<!-- <img src="banner.png" id="banner"> -->
<h1 id ="Heading">Validator</h1>
<br />
<div id ="loadbutton">
<button type="button" name="load_data" id="load_data" class="btn btn-info">Load Data</button>
</div>
<br />
<div id="employee_table">
</div>
</div>
</div>
</div>
</body>
</html>
and here is output.csv
Application,FileName,ADG,KLHJ,POWB
ads,FileName1,jhjkhkjhMatching,jhjkhkNot Matching,jhjkhkjhMatching
adr,FileName2,databaseMatching,databaseMatching,databaseMatching
popo,FileName3,POEBMatching,POEBMatching,POEBMatching
so here it tells me to add even listener and i don't know where to add event listener in this code . since table is created dynamically based on csv and after button click table is loaded and then filter (require event listener) is done to table .
So please help me with adding event listener
Try adding the event listeners once the page loads. It is unable to find the element with id "myInputtext" when it is trying to attach the event listener.
As the addition of the event listeners is done outside any function, when the script is imported, it tries to add the event listeners and as it can't find, it throws an error.
Uncaught TypeError: Cannot read property 'addEventListener' of null means you're trying to add an event listener to an element that doesn't exist. If the element you're listening to is baked into the HTML code (meaning it exists when the page loads), make sure your event listener is waiting for the DOM content to load first:
window.addEventListener('DOMContentLoaded', (event) => {
// My Code
});
If the element you're listening for is created dynamiacally with Javascript, add the listener after the element is created. (First create the element and append it to the DOM, then add a listener for the element)
Lastly, you may have removed the element, so put a check in place that the element exists before you listen for an event.
If you're still having trouble, maybe get a fiddle going so we can try out your code.
I would like to create a table that will prompt you to add your name and occupation and add them in a row in the table. The values are supposed to go into an array. The delete button will delete them from the array and remove the row. There is supposed to be a counter as well.
At the moment I tried to do it only for the array peopleArray[]. I encounter the issue that the remove button will not work outside the function for "add" and executes many times, deleting everything in the array with just one click. I am misplacing something.
* {
font-family: verdana;
}
.table-container {
border-radius: 10px;
overflow: hidden;
display: inline-block;
}
.table {
border-collapse: collapse;
border-spacing: 0;
}
.table tr {
text-align: center;
}
.table tr:nth-child(2n) {
background-color: #eeeeee;
}
.table tr:nth-child(2n-1) {
background-color: #fcfafa;
}
.table th {
padding: 0 10px;
font-size: 12px;
width: 150px;
background-color: #A9BABA;
color: #000;
}
.table th:first-child,
.table th:nth-child(4) {
width: 15px;
}
.counter {
font-size: 12px;
font-weight: bold;
padding: 5px;
}
.btn_img {
width: 20px;
}
.button_style {
border: none;
background: none;
transition: all 0.5s;
padding: 5px;
}
.button_style:hover {
transform: scale(1.2);
}
.button_style:focus {
transform: rotateY(180deg);
outline: none;
}
table td {
padding: 0 10px;
border: 1px solid white;
font-size: 15px;
}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
</head>
<body>
<div class="table-container">
<table class="table">
<tr>
<th class="">No.</th>
<th class="">Name</th>
<th class="">Occupation</th>
<th class="">
<button id="btn_add_people" class="button_style"><img class="btn_img" src="https://i.imgur.com/6FXVi7B.png" alt="options">
</button></th>
</tr>
<tr>
<td id="counter" class="counter" colspan="4"></td>
</tr>
</table>
</div>
<script>
$(document).ready(function() {
var peopleArray = [];
var occupArray = [];
var countP = 0;
$("#btn_add_people").click(function() {
var personName = prompt("Enter a name please!");
var personOccup = prompt("Enter an occupation please!");
peopleArray.push(personName);
occupArray.push(personOccup);
countP = peopleArray.length
var addedRow = '<tr id=""><td colspan="1" >' + peopleArray.length + '</td><td id="name' + peopleArray.length + '" colspan="1">' + peopleArray[peopleArray.length - 1] + '</td><td colspan="1">' + occupArray[occupArray.length - 1] + '</td><td colspan="1"><button id="' + peopleArray.length + '" class="button_style btn_remove_person"><img src="https://i.imgur.com/eiyNHjs.png" alt="close" class="btn_img" /></button></td></tr>';
$(".table").append(addedRow);
$("#counter").text("People added: " + countP);
$("tr").on('click', '.btn_remove_person', (function() {
$(this).parents("tr").remove()
var exitN = $(this).attr("id");
peopleArray.splice(exitN - 1, 1);
// get ID from button and connect with ID to splice name and occupation !!!
$("#counter").text("People added: " + countP);
}));
});
});
</script>
</body>
</html>
You could remove the $(document).ready(function() { }); as you are not really making great use of it. If you wanted to keep it to prevent users from entering information, then hide the add button first, then in the .ready display the button to indicate it is ready to use.
Keep the JQuery for adding entries but when creating the delete button add a onclick function to delete the entry.
I leave your counter calculations up to you as I do not know how you want to make the counters..people added being a total number to include deleted entries? People added being a count of entries in the table? Number next to entry being row number or could be 23 and 22 before it were deleted, etc...
var peopleArray = [];
var occupArray = [];
var countP = 0;
$("#btn_add_people").click(function() {
var personName = prompt("Enter a name please!");
var personOccup = prompt("Enter an occupation please!");
peopleArray.push(personName);
occupArray.push(personOccup);
countP = peopleArray.length
var addedRow = '<tr id=""><td colspan="1" >' + peopleArray.length + '</td><td id="name' + peopleArray.length + '" colspan="1">' + peopleArray[peopleArray.length - 1] + '</td><td colspan="1">' + occupArray[occupArray.length - 1] + '</td><td colspan="1"><button id="' + peopleArray.length + '" class="button_style btn_remove_person" onclick="_removeEntry(this)">Delete</button></td></tr>';
$(".table").append(addedRow);
$("#counter").text("People added: " + countP);
});
function _removeEntry(e) {
$(e).parents("tr").remove()
var exitN = $(e).attr("id");
peopleArray.splice(exitN - 1, 1);
$("#counter").text("People added: " + countP);
};
I have an input box which you can enter items, submit it, and create a box with it's own delete button to remove it. Problem is, after deleting a number of boxes, and then entering something new in input, all the previous items that were deleted get reloaded, including the new item.
How can I prevent reloading of already removed boxes?
Fiddle (Stacksnippets do not allow submit)
This is my Html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Shopping List Example</title>
<link rel="stylesheet" type="text/css" href="css-list.css">
</head>
<div id="centerPanel">
<form class="my-list-form">
<input type="text" class="input" name="add-input" id="add-input">
<button class="add-button" id="submitBtn">Add</button>
</form>
<ul class="my-list-ul"></ul>
</div>
<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<script src="js-list.js"></script>
</html>
JS:
var state = {items:[]};
var addItem = function(state, item)
{
state.items.push(item);
}
var displayItem = function(state, element){
var htmlItems = state.items.map(function(item){
return '<li class="box">' + item + '</br><button class="divBtns" id="deleteBtn">Delete</button>' + '</li>';
});
element.html(htmlItems);
}
//After deleting items, this button again loads all items that have been created since
//the page loaded up, including the new item.
//Needs to be fixed to not reload the deleted items
$('.my-list-form').submit(function(event){
event.preventDefault();
addItem(state, $('.input').val());
displayItem(state, $('.my-list-ul') );
/* alert(state.items[1]); shows that the items array holds everything that is turned into a div*/
})
$(document).ready(function(e){
$('ul').on('click', '#deleteBtn', function(event){
var rmvButton = $(this).closest('li');
rmvButton.remove();
});
})
css:
* {
font-family: sans-serif;
font-weight: normal;
}
#centerPanel {
margin-left: 50px;
margin-top: 50px;
padding-left: 10px;
}
h1 {
font-size: 34px;
}
.font-size {
font-size: 17px;
}
#add-input {
height:25px;
width: 190px;
font-size: 16px;
}
button {
font-size: 17px;
}
#submitBtn {
height: 30px;
width: 85px;
}
.divBtns {
margin-top: 10px;
}
.box {
border: 1px solid black;
border-color: grey;
width: 153px;
height: 65px;
padding: 20px;
font-style: italic;
font-size: 22px;
margin-bottom:10px;
margin-right: 10px;
}
ul {
list-style-type: none;
margin-left:-40px;
color: grey;
}
li {
float: left;
}
It appears you never remove anything from the state object, which is added to every time you run addItem().
You'd need a way to remove a specific item from this array, probably by getting the index of the li to delete and doing
state.items.splice(index, 1);
Store the index as a data attribute on the button:
var displayItem = function(state, element){
var i = 0;
var htmlItems = state.items.map(function(item){
return '<li class="box">' + item + '</br><button class="divBtns" ' +
'id="deleteBtn" data-index="' + (i++) + '">Delete</button>' + '</li>';
});
element.html(htmlItems);
}
Then you can get it in the click callback
var index = $(this).data('index');
You can update state to solve this problem.
It's my code:
...
var deleteItem = function(state, itemId) {
var index = 0;
var isFind = state.items.some(function(item, i) {
if (item.id == itemId) {
index = i;
return true;
} else {
return false;
}
});
if (isFind) {
state.items.splice(index, 1);
}
}
...
$(document).ready(function(e){
$('ul').on('click', '#deleteBtn', function(event){
...
// update state
deleteItem(state, $(this).parent().data('id'));
});
})
https://jsfiddle.net/q483cLp9/
I'm new to jQuery and web development. I have succesfully implemented other jQuery plugins like data tables or a simple sliders.
I'm having some problems when trying to make this run:
http://jsfiddle.net/KurtWM/pQnPg/
I know that is a must to initialize my code so I did the following:
<script type="text/javascript" language="javascript" class="init">
$(document).ready(function() {
$('#survey1').numericScale();
} );
</script>
I copied the js part exactly as it is from the provided link and uploaded to my server with the name:
jquery.numericScale.js
I have included jQuery and this plugin in the following way:
<script type="text/javascript" language="javascript" src="media/js/jquery.dataTables.js"></script>
<script type="text/javascript" language="javascript" src="media/js/jquery.numericScale.js"></script>
Regarding the HTML part I just copied it into my HTML body.
I really don't have a clue of what could I be doing wrong.
Try removing this from the end of your jquery.numericScale.js file:
var disciplines = $('#survey1').numericScale({
'responseRange' : 5,
'lowOpinionAnswer' : 'Least like me',
'highOpinionAnswer' : 'Most like me'
});
console.dir(disciplines);
Add this to your html page after your loaded plugins:
<script>
$('#survey1').numericScale({
'responseRange' : 5,
'lowOpinionAnswer' : 'Least like me',
'highOpinionAnswer' : 'Most like me'
});
</script>
This should work for you
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.survey-wrapper
{
position: relative;
display: table;
width: 100%; /*height: 500px;*/
max-width: 640px;
border-collapse: separate !important;
border-spacing: 1px !important;
}
ol.survey
{
list-style: decimal; /*margin-top: 160px;*/
list-style-position: inside;
}
ol.survey > li:last-child
{
border-bottom: 1px solid #CDCDCD;
}
ol.survey li
{
padding-left: -20px;
border-top: 1px solid #CDCDCD;
border-right: 1px solid #CDCDCD;
border-left: 1px solid #CDCDCD;
}
ol.survey li.alt, ol.survey li:nth-child(even)
{
background-color: #E8E8E4;
}
.scores > div
{
background: #E8E8E4;
}
.scores div.alt, .scores > div:nth-child(even)
{
background-color: #E8E8E4;
}
ol.survey li .opinion-question
{
margin-bottom: 0.5em;
font-weight: bold;
}
ol.survey li
{
padding-top: 6px;
padding-bottom: 1px;
padding-left: 12px;
}
ol.survey li .opinion-responses
{
display: table;
width: 100%;
margin-bottom: 1.0em;
}
ol.survey li .opinion-responses .bipolar-adjective
{
display: table-cell;
width: 25%;
text-align: center;
vertical-align: middle;
font-style: italic;
}
ol.survey li .opinion-responses .response-choice
{
display: table-cell;
width: 10px;
text-align: center;
vertical-align: middle;
}
ol.survey li .opinion-responses .response-choice input[type=radio], ol.survey li .opinion-responses .response-choice input.radio
{
}
.scores
{
width: 100%;
height: 400px;
position: relative;
}
.scores .discipline
{
display: block;
position: absolute;
bottom: 0;
text-align: center;
background: #E8E8E4 url(../images/gifts_orange.png) no-repeat 0 0;
border: 1px solid #FFFFFF;
}
.scores .discipline .discipline-name
{
text-align: center;
position: relative;
bottom: 24px;
z-index: 200;
font-family: "Futura Lt BT" , helvetica, sans-serif;
}
.scores .discipline .discipline-total
{
text-align: center;
display: block;
font-weight: bold;
font-size: 150%;
font-family: "Futura Md BT" , helvetica, sans-serif;
margin-top: 0px;
}
.scores .selected
{
background: #1047a9 url(../images/gifts_blue.png) no-repeat 0 0 !important;
}
.scores .selected .discipline-total
{
color: #FFFFFF !important;
}
.box
{
position: relative;
width: 60%;
background: #ddd;
-moz-border-radius: 4px;
border-radius: 4px;
padding: 2em 1.5em;
color: rgba(0,0,0, .8);
text-shadow: 0 1px 0 #fff;
line-height: 1.5;
margin: 60px auto;
}
.box:before, .box:after
{
z-index: -1;
position: absolute;
content: "";
bottom: 15px;
left: 10px;
width: 50%;
top: 80%;
max-width:300px;
background: rgba(0, 0, 0, 0.7);
-webkit-box-shadow: 0 15px 10px rgba(0,0,0, 0.7);
-moz-box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7);
box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7);
-webkit-transform: rotate(-3deg);
-moz-transform: rotate(-3deg);
-o-transform: rotate(-3deg);
-ms-transform: rotate(-3deg);
transform: rotate(-3deg);
}
.box:after
{
-webkit-transform: rotate(3deg);
-moz-transform: rotate(3deg);
-o-transform: rotate(3deg);
-ms-transform: rotate(3deg);
transform: rotate(3deg);
right: 10px;
left: auto;
}
.rotate
{
/* Safari */
-webkit-transform: rotate(-90deg); /* Firefox */
-moz-transform: rotate(-90deg); /* IE -ms-transform: rotate(-90deg); */ /* Opera */
-o-transform: rotate(-90deg);
}
</style>
</head>
<body>
<form>
<ol id="survey1" class="survey">
<li class="question" title="Prophecy">When a situation needs to be corrected I feel a burden to speak up about it in order to correct it.</li>
<li class="question" title="Shepherd">I feel a special concern for less mature Christians and feel compelled to care for them spiritually.</li>
<li class="question" title="Teaching">I find it easy and enjoyable to spend time in intensive Bible study.</li>
<li class="question" title="Encouraging">I am able to help others identify problems and offer solutions.</li>
<li class="question" title="Giving">I don't understand why others don't give as much and as freely as I do.</li>
<li class="question" title="Mercy">I am comfortable visiting people who are sick and disabled.</li>
<li class="question" title="Evangelism">I have greater desire than most to witness to non-Christians.</li>
<li class="question" title="Administration">If there is no leadership in a group I will step up and take charge.</li>
<li class="question" title="Serving">I enjoy being called upon to do special jobs around the church.</li>
<li class="question" title="Prophecy">When issues are being dealt with in a group, I speak up rather than just listening.</li>
<li class="question" title="Shepherd">I find myself especially concerned that newer Christians will be influenced by false teachers and be harmed in their spiritual growth as a result. </li>
<li class="question" title="Teaching">Others sometimes accuse me of being too technical or detail-oriented. </li>
<li class="question" title="Encouraging">I would rather talk personally with someone rather than refer them elsewhere. </li>
<li class="question" title="Giving">I find myself looking for opportunities to give my money without being asked to give. </li>
<li class="question" title="Mercy">I have a tendency to think about things for a while before making a decision. </li>
<li class="question" title="Evangelism">Witnessing to non-Christians comes easily to me. </li>
<li class="question" title="Administration">I enjoy handling the details of organizing ideas, people, resources, and time in order to have more effective ministry. </li>
<li class="question" title="Serving">I feel that I am not specifically skilled, but I enjoy doing what needs to be done around the church. </li>
</ol>
</form>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
(function( $ ) {
$.fn.extend({
numericScale: function(options) {
var defaults = {
responseRange: 5,
topNumber: 3,
lowOpinionAnswer: 'Lowest',
highOpinionAnswer: 'Highest'
};
var scores = []; // Array to hold scores
var key; // HTML5 localStorage key
var disciplines = []; // Array to hold disciplines
var aHighVals = []; // Array to hold n highest scores
var options = $.extend(defaults, options);
// Act on every target list of the plugin.
return this.each(function() {
var $list = $(this);
key = $list.attr('id') + "_key";
// Replace list items with survey controls.
$($list).children().each(function(index) {
createQuestion($list, $(this), index);
}).filter(':odd').addClass('alt');
// Create HTML for survey & scores containers and button
$list.wrap('<div id="wrap-' + $list.attr('id') +
'" class="survey-wrapper"></div>');
$list.after('<div id="scores-' + $list.attr('id') +
'" class="scores"></div>');
$list.after('<input type="button" id="submitBtn"' +
' class="button btnStyle" value="Show My Gifts"' +
' disabled="disabled" />');
// Hide scores initially
$('#scores-' + $list.attr('id')).hide();
loadScores();
setSubmitBtnState();
console.dir(scores);
// ====================
// Handler:
// ====================
$('input[type="radio"]').change(function(e) {
// Get the discipline of the question
var discipline = $(e.target).closest('li[class~="question"]').attr('data-discipline');
var qNum = $(e.target).attr('name').substr(1) - 1;
// Replace the question's object property 'value' in the Scores array with the new selection
scores[qNum].value = $(e.target).val();
storeScores();
setSubmitBtnState();
});
// ====================
// Function:
// ====================
function storeScores() {
var jsonScores = JSON.stringify(scores);
localStorage.setItem(key, jsonScores);
}
// ====================
// Function:
// ====================
function setSubmitBtnState() {
if (getFormFinished()) {
$('#submitBtn').removeAttr('disabled');
}
else {
$('#submitBtn').attr('disabled', 'disabled');
}
}
// ====================
// Function:
// ====================
function getFormFinished() {
//var boolFinished = true;
for (var i = 0; i < scores.length; i++) {
if (scores[i].value == 0) {
//boolFinished = false;
return false;
break;
}
}
//return boolFinished;
return true;
}
// ====================
// Function:
// ====================
function createQuestion(oList, oItem, index) {
// Add the 'title' of the list item
var title = oItem.attr('title');
var qName = "q" + (index + 1);
// Create score items in scores Array.
createScore(oItem, title, qName);
var question = "<div class='opinion-question'>" +
oItem.text() + "</div>" +
"<div class='opinion-responses'>" +
"<span class='bipolar-adjective'>" +
defaults.lowOpinionAnswer + "</span>";
// Create a radio button group for each question.
for (var i = 1; i <= defaults.responseRange; ++i) {
question += "<span class='response-choice'>" +
"<input type='radio' name='" + qName +
"' value='" + i + "' class='radio'";
// Create a LocalStorage item for each question.
//check if discipline's localstorage is set.
if (localStorage.getItem(oList.attr('id') + "_" + qName)) {
if (localStorage.getItem(oList.attr('id') + "_" + qName) == i) {
question += " checked='checked'";
}
}
// Add required attribute to first radio button in group to allow validation with the jquery.validate.js plugin.
if (i == 1) {
question += " validate='required:true'";
}
question += " />" + i + "</span>";
}
question += "<span class='bipolar-adjective'>" + defaults.highOpinionAnswer + "</span>" + "</div>";
oItem.empty().prepend(question).attr('data-discipline', oItem.attr('title')).removeAttr('title');
}
// ====================
// Function:
// ====================
function createScore(oItem, d, qName) {
var score = {};
score.question = qName;
score.value = oItem.val();
score.discipline = d;
scores.push(score);
}
// ====================
// Function:
// ====================
function addScoreToPage(score) {
if (replace(scores, score.question, score.value)) {
var scoreUl = document.getElementById('scores-' + $list.attr('id') + '-ul');
var li = document.createElement('li');
li.innerHTML = score.question + '; ' + score.value + '; ' + score.discipline;
if (scoreUl.childElementCount > 0) {
scoreUl.insertBefore(li, scoreUl.firstChild);
} else {
scoreUl.appendChild(li);
}
}
}
// ====================
// Function:
// ====================
function replace(arrayName, replaceTo, replaceWith) {
for (var i = 0; i < arrayName.length; i++) {
if (arrayName[i].question == replaceTo) {
arrayName.splice(i, 1, replaceWith);
return true;
} else {
return false;
}
}
}
// ====================
// Function:
// ====================
function getHighestScores(oItems, num) {
for (var key in oItems) {
var obj = oItems[key];
for (var prop in obj) {
}
}
}
// ====================
// Function:
// ====================
function surveySetup() {
var submitButton = document.getElementById("submitBtn");
submitButton.onclick = submitSurvey;
if (!window.localStorage) {
alert("The Web Storage API is not supported in your browser. You may still submit the form, but your answers will not be saved to your browser.")
} else {
loadScores();
}
}
// ====================
// Handler:
// ====================
$("#submitBtn").click(function() {
if (!window.localStorage) {
alert("The Web Storage API is not supported in your browser. You may still submit the form, but your answers will not be saved to your browser.")
} else {
submitSurvey();
$('html, body').animate({
scrollTop: $("html, body").offset().top
}, 1000);
}
});
// ====================
// Function:
// ====================
function submitSurvey() {
// Create visual elements for scores.
var surveyId = 'div#scores-' + $list.attr('id');
var dNumber = 0;
var dWidth;
var maxHeight = 350;
var tallBarHeight = 0;
$(surveyId).empty();
for (var i = 0; i < scores.length; i++) {
if ($('div#' + scores[i].discipline).length == 0) {
var dScore = tallyDiscipline(scores[i].discipline);
dNumber++;
var discipline = {};
discipline.name = scores[i].discipline;
discipline.value = dScore;
disciplines.push(discipline);
$(surveyId).append("<div id='" + scores[i].discipline + "' class='discipline'><div class='discipline-name'>" + scores[i].discipline + "</div><div class='discipline-total'>" + dScore + "</div>" + "</div>");
if (dScore > tallBarHeight) {
tallBarHeight = dScore;
}
};
$(surveyId).show('fast');
};
//console.dir(disciplines);
//return(disciplines);
dWidth = 100 / dNumber
for (var ii = 0; ii < dNumber; ii++) {
$('.scores .discipline').eq(ii).css({
'left': Math.floor(dWidth) * ii + '%'
});
$('.scores .discipline').eq(ii).css({
'width': (Math.floor(dWidth) - 1) + '%'
});
barHeight = Math.floor((disciplines[ii].value / tallBarHeight) * maxHeight)
$('.scores .discipline').eq(ii).animate({
height: barHeight
}, 2000);
$('.scores .discipline'); //.addClass('box');
};
getHighestValues();
$list.hide();
$('#submitBtn').hide();
$('[id*="btnSaveGifts"]').show();
};
// ====================
// Function:
// ====================
function getHighestValues() {
for (var i = 0; i < disciplines.length; i++) {
aHighVals[i] = [disciplines[i].value, disciplines[i].name];
}
aHighVals.sort(mySorting);
aHighVals.splice(defaults.topNumber, aHighVals.length - defaults.topNumber);
for (var ii = 0; ii < aHighVals.length; ii++) {
$('#' + aHighVals[ii][1]).addClass('selected');
$('input[id*="hdnSelectedVals"]').val($('input[id*="hdnSelectedVals"]').val() + aHighVals[ii][1]);
if (aHighVals.length - 1 > ii) {
$('input[id*="hdnSelectedVals"]').val($('input[id*="hdnSelectedVals"]').val() + ", ");
}
}
}
// ====================
// Function:
// ====================
function mySorting(a, b) {
a = a[0];
b = b[0];
return b == a ? 0 : (b < a ? -1 : 1)
}
// ====================
// Function:
// ====================
function tallyDiscipline(discipline) {
var total = 0;
for (var i = 0; i < scores.length; i++) {
if (scores[i].discipline == discipline) {
total += parseInt(scores[i].value);
}
}
return total;
}
// ====================
// Function:
// ====================
function loadScores() {
var jsonScores = localStorage.getItem(key);
if (jsonScores != null) {
scores = JSON.parse(jsonScores);
for (var i = 0; i < scores.length; i++) {
addScoresToPage(scores[i]);
}
}
}
// ====================
// Function:
// ====================
function addScoresToPage(score) {
$('input:radio[name=' + score.question + '][value=' + score.value + ']').attr('checked', 'checked');
}
});
}
});
})( jQuery );
var disciplines = $('#survey1').numericScale({
'responseRange' : 5,
'lowOpinionAnswer' : 'Least like me',
'highOpinionAnswer' : 'Most like me'
});
console.dir(disciplines);
</script>
</body>
</html>
I've put everything is one file