Create an element using javascript - javascript

I have a html table
<table id = "rpttable" name = "rpttable">
<thead>
Column Headers here...
</thead>
<tbody id = "rptbody" name = "rptbody">
data here <3 ....
</tbody>
</table>
and here is my php (sample.php)
<?php
Query Code here..
Query Code there..
and so on
//this is the way I populate a table
while (query rows) {
echo '<tr>';
echo '<td>Sample Data</td>';
echo '</tr>;
}
?>
So to make this work and to populate the table this is what I do.
<table id = "rpttable" name = "rpttable">
<thead>
Column Headers here...
</thead>
<tbody id = "rptbody" name = "rptbody">
<?php
include 'folder_location/sample.php';
?>
</tbody>
</table>
Disregard the image of the ouput but when I go to Inspect Element or even Ctrl + u I will see my table structure now is like this.
<table id = "rpttable" name = "rpttable">
<thead>
Column Headers here...
</thead>
<tbody id = "rptbody" name = "rptbody">
<tr>
<td>Sample Data</td>
</tr>
</tbody>
</table>
Now here is the thing. I do not do that this is what I do.
$("#rpttable tr").remove();
for (i = 0; i < data.length; i++) {
tr = $("<tr />");
for (x in data[i]) {
td = $("<td />");
td.html(data[i][x]);
tr.append(td);
}
rpttable.append(tr);
}
Same output It does populate the table but when I go to Inspect Element or even Ctrl + u the output is.
<table id = "rpttable" name = "rpttable">
<thead>
Column Headers here...
</thead>
<tbody id = "rptbody" name = "rptbody">
**This is the part missing**
</tbody>
</table>
My question here is how can I literaly create an element usung javascript/ajax? same output in php. I mean write the element.
** Updated **
I am trying to run a css class from an external file and If I manualy edit it to suits my needs I will a long hour and also Its hard for me to explain its a class for table. I tried to use that class using default value in <table>. You know manualy write it at the back end. now Im trying to populate it using a php and ajax so, so far so good it does populate but when I try to run the class the class does not work.
TYSM

Using jquery you can add html rows to the tbody using:
$("#rptbody").html("<tr><td>value</td></tr>");
Is this what you want to do?

You can use JQuery append() method:
$('#rptbody').append('<tr><td>my data</td><td>more data</td></tr>');
In case you need to insert after last row:
$('#rptbody> tbody:last-child').append('<tr>...</tr><tr>...</tr>');

for (i = 0; i < 5; i++) {
let tr = $("<tr />");
for (j=0; j < 5;j++)
tr.append($("<td />",{html:j,class:"tbl"}));
$("tbody").append(tr);
}
.tbl{border:1px solid pink;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody></tbody>
</table>

You have asked roughly two questions. Let's break it down.
My question here is how can I literaly create an element usung javascript/ajax?
You are already doing this with your Javascript (client-side) code. It looks like you're using jQuery syntax, so we'll stick with that. This does create an element and inserts it into the page.
var $el = $("<div>I'm a new div element</div>");
$('body').append( $el );
This creates a new element, assigns it to the $el variable, and then appends it to the body of the page. This will not show up in "View Page Source" view, however. Why? Because this modifies the DOM -- the Dynamic Object Model.
To see this new element, you'll either need to look at the rendered output (what the user/you sees), or open up your browser's DevTools (often <F12>, or right-click -> inspect). In the DevTools, find the "Inspector" tab (or equivalent), then look for your new element in this live view of the DOM.
... same output in php.
In short, you can't. What Ctrl+U / View Page Source shows is the page as it was initially received from the server. This would be the exact content you would see if you were to use a command line tool, like curl or wget:
curl http://url.to.your.com/page
Since you include 'folder_location/sample.php' at the server, this is included in the page before the browser sees it. For your edification, I would consider reading up on the DOM.
Wikipedia
W3

Try this:
$("#rpttable tbody tr").remove();
var content = '' ;
for (i = 0; i < data.length; i++) {
content += "<tr>" ;
for (x in data[i]) {
content += "<td>" + data[i][x] + "</td>" ;
}
content += "</tr>" ;
}
$("#rpttable tbody").html(content) ;
Updated
I am using Google Chrome too. Please try the below code, and check the inspect element each time you add a new row. You can see the html in the Inspect Element changing!
function AppendNewRowToTable() {
var trLen = $("table tbody tr").length ;
var content = "" ;
content += "<tr>" ;
for (i = 0; i < 5; i++) {
content += "<td>" + trLen + "-" + i + "</td>" ;
}
content += "</tr>" ;
$("table tbody").append(content) ;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Add new Row
<br />
<table>
<thead>
<tr>
<th>Title 01</th>
<th>Title 02</th>
<th>Title 03</th>
<th>Title 04</th>
<th>Title 05</th>
</tr>
</thead>
<tbody></tbody>
</table>

It seems your intent is to append extra rows to the table in your html response generated from your PHP script.
For that you don't need to clear all existing rows.
$("#rpttable tr").remove();
Build an array of rows and append once to your table body.
var $tbody = $('#rptbody');
var tableRowAdditions = [];
for (var i = 0; i < data.length; i++) {
var $tr = $("<tr></tr>");
for (var x in data[i]) {
var $td = $("<td></td>");
$td.html(data[i][x]);
$tr.append(td);
}
tableRowAdditions.push(tr);
}
$tbody.append(tableRowAdditions);

For a "pure" JavaScript approach, you can create elements using the createElement Web API
For example:
A paragraph with text "Hello" would be
var container = document.getElementById('rptbody');
var hello = document.createTextNode('Hello');
var helloParagraph = Document.createElement('p');
// Add text to paragraph
helloParagraph.appendChild(hello);
// Append to container
container.appendChild(helloParagraph);

The best way to create elements using jQuery is to use the following format:
// Create the TR and TD elements as jQuery objects.
var tr = $("<tr></tr>", {
"id":"tr1",
"class":"tr"
});
var td = $("<td></td>", {
"id":"td1",
"class":"td",
"text": "Sample Data",
click: function() {
// optional: Function to attach a click event on the object
alert("Clicked!");
}
});
// Attach the element to the document by appending it
// inside rptbody (after all existing content inside #rptbody)
$("#rptbody").append(tr);
tr.append(td);
// OR, Attach the element to the document by prepending it
// inside rptbody (before all existing content in #rptbody)
$("#rptbody").prepend(tr);
tr.append(td);
// OR, Attach the element to the document by completely replacing the content of #rptbody
$("#rptbody").html(tr);
tr.append(td);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id = "rpttable" name = "rpttable">
<thead>
Column Headers here...
</thead>
<tbody id = "rptbody" name = "rptbody">
</tbody>
</table>

Related

Adding button that removes object from array inside a table

Created a form and empty table, trough DOM i should create a new object from class Movie and insert it in empty table with a button to remove it.
Don't know how i would create the button with a function to remove the movies[i] in the table. Sorry I am still learning and don't know how to express my problems.
window.onload = function(){
let frmMovies = document.getElementById("frmMovies");
let txtTitle = document.getElementById("txtTitle");
let txtYear = document.getElementById("txtYear");
let txtGender = document.getElementById("txtGender");
frmMovies.addEventListener("submit", function (event) {
let newMovie = new Movies(txtTitle.value, txtYear.value, txtGender.value);
movies.push(newMovie);
refreshTable();
/*let btn = document.getElementsByClassName("btn");
btn.addEventListener("click", function (event) {
movies.splice(x, 1);
event.preventDefault();
})*/
event.preventDefault();
})
}
function refreshTable() {
let movieTable = document.getElementById("movieTable");
let txt = "";
txt = "<tr><th>TÍTULO</th><th>ANO</th><th>GÉNERO</th><th>!</th></tr>";
for(let i = 0 ; i < movies.length; i++){
txt += "<tr>";
txt += "<td>" + movies[i].title + "</td>";
txt += "<td>" + movies[i].year + "</td>";
txt += "<td>" + movies[i].gender + "</td>";
txt += "<td>" + "<button class='btn'>" + "Remove" + "</button>" + "</td>";
txt += "</tr>";
}
movieTable.innerHTML = txt;
}
You could add an onclick attribute to your Remove buttons when you build it. Upon clicking on the button, it will call a function passing current button element i.e. this.
let movies = [];
// etc
function refreshTable() {
let movieTable = document.getElementById("movieTable");
let txt = "";
txt = "<tr><th>TÍTULO</th><th>ANO</th><th>GÉNERO</th><th>!</th></tr>";
for(let i = 0 ; i < movies.length; i++){
txt += "<tr>";
txt += "<td>" + movies[i].title + "</td>";
txt += "<td>" + movies[i].year + "</td>";
txt += "<td>" + movies[i].gender + "</td>";
txt += "<td>" + "<button type='button' class='btn' onclick='deleteRow(this)'>" + "Remove" + "</button>" + "</td>";
txt += "</tr>";
}
movieTable.innerHTML = txt;
}
Create your new function which will delete the current row using .removeChild().
function deleteRow(button) {
let row = button.parentElement.parentElement;
document.getElementById("movieTable").removeChild(row);
}
This is untested of course but you could do something like this.
Event Delegation is the most efficient way of using one element to listen for an event for multiple child/descendant elements. Simply find an ancestor (tbody) element that the group of target elements (buttons) have in common.
Demo
// Reference the <tbody> by its tagName
var tbody = document.querySelector('tbody');
// Register the click event on <tbody> calls removeRow when clicked
tbody.addEventListener('click', removeRow, false);
// Pass through the Event Object
function removeRow(event) {
/* Event Object property Event.target always knows which
|| element was actually clicked. Use event.target to compare
|| or assert a true/false check in order to target the rest of
|| the DOM in reference to event.target.
|| Find the closest <tr> from event.target
|| `this` is the function owner <tbody> which removes the <tr>
*/
if (event.target.className === 'btn') {
var row = event.target.closest('tr');
this.removeChild(row);
}
return false;
}
<table>
<tbody>
<tr>
<td>Reservoir Dogs</td>
<td>1992</td>
<td>Male?</td>
<td><button class='btn'>Remove</button></td>
</tr>
<tr>
<td>The Usual Suspects</td>
<td>1995</td>
<td>Male?</td>
<td><button class='btn'>Remove</button></td>
</tr>
<tr>
<td>Pulp Fiction</td>
<td>1994</td>
<td>Male?</td>
<td><button class='btn'>Remove</button></td>
</tr>
<tr>
<td>Sin City</td>
<td>2005</td>
<td>Male?</td>
<td><button class='btn'>Remove</button></td>
</tr>
<tr>
<td>Old Boy</td>
<td>2003</td>
<td>Male?</td>
<td><button class='btn'>Remove</button></td>
</tr>
</tbody>
</table>
Since you're new to this, I would recommend really focusing on understanding the difference between an actual DOM element and the HTML tags that are used to create them.
The DOM is the actual mechanism that determines what is displayed on the page. HTML is just a way of serializing a DOM into text, so you can easily send it over networks to other computers. A web browser parses HTML and recreates the DOM on the client's computer.
The DOM consists of JavaScript objects that you can manipulate with Javascript. When you set movieTable.innerHTML, what you're doing is telling the browser: to do the following:
Parse the assigned string as HTML.
Delete all of the children of movieTable.
Add the new DOM elements parsed from the assigned string as children of movieTable.
This is wasteful because you're recreating the entire table every time you do it, even though you may only be adding or removing a single element. It also can be frustrating to maintain, since JS does not play well with long string literals. This is one of the reasons why stuff like this is often handled by templating libraries.
I'll keep it simple though, and show you how you can do this with just the standard DOM methods:
let frmMovies = document.getElementById("frmMovies");
let txtTitle = document.getElementById("txtTitle");
let txtYear = document.getElementById("txtYear");
let txtGender = document.getElementById("txtGender");
// You don't need to keep getting this every time.
// Just get it once and reuse the reference.
let movieTable = document.getElementById("movieTable");
frmMovies.addEventListener("submit", function (event) {
// You can do this anytime, as long as you do it before your
// handler returns. I usually do it right away.
event.preventDefault();
// First, let's create a new table row.
let movieRow = document.createElement("tr");
// Create the title cell.
let titleCell = document.createElement("td");
titleCell.innerText = txtTitle.value;
// Create the year cell.
let yearCell = document.createElement("td");
yearCell.innerText = txtYear.value;
// Create the gender cell.
let genderCell = document.createElement("td");
genderCell.innerText = txtGender.value;
// Create the remove button and a cell to put it in.
let buttonCell = document.createElement("td");
let removeButton = document.createElement("button");
removeButton.innerText = 'Remove';
// Attach the click handler for the remove button.
removeButton.addEventListener("click", function() {
// This handler will form a *closure*, which will store the
// reference to the movieRow, enabling you remove it by simply
// calling `remove` on it.
movieRow.remove();
});
// Now, let's put it all together:
// Add the remove button to its cell.
buttonCell.appendChild(removeButton);
// Add the cells to the table row.
movieRow.appendChild(titleCell);
movieRow.appendChild(yearCell);
movieRow.appendChild(genderCell);
movieRow.appendChild(buttonCell);
// Add the table row to the table.
movieTable.appendChild(movieRow)
});
MDN has some pretty solid documentation of standard HTML DOM that you'll probably want to check out:
https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model

jquery prev() return undef

After receiving the data via JSON and add content on a table, was used the event delegation to capture the links of this content, but when you click the link that was created dynamically want to access the prev () the tr element containing the data-id. But this is me returning undef. Can someone help me? The prev() is being called by editarComercial()
Javascript:
$(document).ready(function(){
function editarComercial(trthis) {
alert($(trthis).prev().prev().data('id'));
}
function listaComercial(){
url = BASE_URL + 'comercial/ajaxrequest/listagem';
$.getJSON(url,function(data){
var trs = [];
$.each(data,function (key){
tr = "<tr data-id=\""+data[key].id+"\">";
tr += "<td>"+data[key].nome+"</td>";
tr += "<td>Editar";
tr += "Excluir</td>";
tr += "</tr>";
trs.push(tr);
});
$("<tbody/>",{
html: trs.join("")
}).appendTo("#listagemComercial");
});
}
$(document).on('click','a.edit-comercial',function(){
editarComercial(this);
});
listaComercial();
});
HTML:
<div id="content">
<table id="listagemComercial">
<thead>
<tr>
<th>Nome</th>
<th>Ações</th>
</tr>
</thead>
</table>
</div>
.edit-comercial doesn't have a previous element, it's the first element in the TD.
You probably wanted closest() instead, to traverse up to the row
function editarComercial(trthis) {
alert( $(trthis).closest('tr').data('id') );
}

Table not showing on rows correctly when using JSON and Javascript

for(var i=0;i<Result.length;i++){
$('<tr>').appendTo('#resultstable');
for(var j=0;j<tableID.length;j++){
$('<td>' + Result[i][tableID[j]] + '</td>').appendTo('#resultstable');
}
$('</tr>').appendTo('#resultstable');
When trying to display a table from JSON data, it displays the headers correctly (not shown here), but when I want the data to show on a new row, it doesn't work. The first row of data is shown correctly, but what should be on the second row continues on from the end of the first row.
In the HTML (when loaded), it shows it as:
..Table headers..
<tbody>
<tr></tr>
</tbody>
<td>1</td>
...Rest of cell data is put in <td> tags...
That is happening because
$('<tr>').appendTo('#resultstable');
creates <tr></tr> dom element and adds it to #resultstable table.
With this statement
$('<td>' + Result[i][tableID[j]] + '</td>').appendTo('#resultstable');
you are not adding html after <tr>. You are creating td tag and assigning it to #resultstable table. But td tag can be assigned only to tr tag.
So the right syntax will be.
for(var i=0;i<Result.length;i++){
var tr = $('<tr>').appendTo('#resultstable');
for(var j=0;j<tableID.length;j++) {
$('<td>' + Result[i][tableID[j]] + '</td>').appendTo(tr);
}
You are appending your data after the table, not after the last row, see Add table row in jQuery for more information how to add a row after the last row.
You don't append <td> elements to the table, you have to append them to the row you just added.
for(var i=0;i<Result.length;i++){
var row = $('<tr>').appendTo('#resultstable');
for(var j=0;j<tableID.length;j++){
$('<td>' + Result[i][tableID[j]] + '</td>').appendTo(row);
}
}
Your code should be well
for(var i=0;i<Result.length;i++){
var tr = $('<tr>').appendTo('#resultstable');
for(var j=0;j<tableID.length;j++){
$('<td>' + Result[i][tableID[j]] + '</td>').appendTo(tr );
}
}

Remove particular row of text in string based on id selected

I am trying to remove a certain table row in a string. For instance, I have the code below in a string. Lets call the variable that stores the string below temp
<tr>
<td></td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td></td>
</tr>
I have several buttons with id's corresponding to the number of row above. If I click the first button it has a corresponding id of 1, the second button has 2, etc.
What I am getting at is that if I hit these delete buttons, I want to remove the corresponding table row above based on what id (button) I click.
Here is my code so far.
$(".delete").click(function() {
var id = $(this).attr("id");
var temp = $("#detailsBox").val();
for (i=1; i!=id; i++) {
if (i=1) {
}
}
$(this).closest('tr').remove();
}
How would I delete a part of that string in my variable temp based off of the id(button) I click? If I choose button 1, I want to delete the first table row. Button two, second table row, etc. I know I need to replace the string, but how do I remove certain instances within the string?
Parsing HTML is dangerous. Therefore I suggest you convert your string to DOM and then manipulate on the DOM tree.
Here is a simple solution with jQuery:
var row = 1; // the row I want to remove
var temp = $("#myTextarea").value(); // get HTML
var table = $("<tbody>" + temp + "<tbody>"); // creates DOM nodes from HTML
table.find("tr").eq(row - 1).remove();
var tempWithoutRow = table[0].innerHTML;
Try yourself in JSFiddle.
You are trying to use jQuery as if that elements are in DOM... and they are not. They are just one string. So you can do something like that:
var arr = yourString.split("<tr>");
$(".delete").click(function() {
var id = $(this).attr("id");
arr = arr.splice(parceInt(id, 10)-1, 1);
}
Now you have array with the right TRs inside. All you have to do is to convert them to string again:
var htmlString;
for (var i=0; i<arr.length; i++) {
htmlString += arr[i];
}
UPDATE jQuery WAY
You can do it with jQuery too. Look at the fiddle
http://jsfiddle.net/J6HJ2/2/
You can select all the table rows and then filter down to the one you want:
$(".delete").click(function() {
var id = $(this).attr("id");
$("#my-table").find("tr").eq(id + 1).remove();//since your IDs are not zero-indexed and .eq() is
});
Docs for .eq(): http://api.jquery.com/eq
$(".delete").click(function() {
var id = $(this).attr("id");
var temp = $("#detailsBox").val();
for (i=1; i!=id; i++) {
if (i=1) {
}
}
$(this).parentNode.remove();
}
if the .delete is on the td
else if u have <td><button class="delete"></button></td>
then it's $(this).parentNode.parentNode.remove();
no need for the id if the button is inside the <tr>
Easy solution would be to give the rows meaningful ID's and use the following code:
$(".delete").click(function() {
$('#row' + $(this).id).remove();
}
If you really want to count nameless TR elements in a string you could split them into an array with split("<tr>")

Jquery group by td with same class

I have the current table data:
<table>
<tr class="Violão">
<td>Violão</td>
<td class="td2 8">8</td>
</tr>
<tr class="Violão">
<td>Violão</td>
<td class="td2 23">23</td>
</tr>
<tr class="Guitarra">
<td>Guitarra</td>
<td class="td2 16">16</td>
</tr>
</table>
What I want to do is groupby the TDs which are the same, and sum the values on the second td to get the total. With that in mind I´ve put the name of the product to be a class on the TR (don't know if it is needed)
and I've coded the current javascript:
$(".groupWrapper").each(function() {
var total = 0;
$(this).find(".td2").each(function() {
total += parseInt($(this).text());
});
$(this).append($("<td></td>").text('Total: ' + total));
});
by the way the current java scripr doesn't groupby.
Now i'm lost, I don't know what else I can do, or if there is a pluging that does what I want.
</tr class="Violão"> This doesn't make sense. You only close the tag: </tr>. And I'm assuming you know that since the rest of your code is proper (except for your classnames. Check this question out).
If you want to add the values of each <td> with a class of td2, see below.
Try this jQuery:
var sum = 0;
$(".td2").each(function(){
sum = sum + $(this).text();
});
This should add each number within the tds to the variable sum.
<table>
<tr class="Violão">
<td>Violão</td>
<td class="td2 8">8</td>
</tr>
<tr class="Violão">
<td>Violão</td>
<td class="td2 23">23</td>
</tr class="Violão">
<tr class="Guitarra">
<td>Guitarra</td>
<td class="td2 16">16</td>
</tr>
</table>
var dictionary = {};
$("td").each(function(){
if(!dictionary[$(this).attr("class"))
dictionary[$(this).attr("class")] = 0;
dictionary[$(this).attr("class")] += parseInt($(this).html());
});
// declare an array to hold unique class names
var dictionary = [];
// Cycle through the table rows
$("table tr").each(function() {
var thisName = $(this).attr("class");
// Add them to the array if they aren't in it.
if ($.inArray(thisName, dictionary) == -1) {
dictionary.push(thisName);
}
});
// Cycle through the array
for(var obj in dictionary) {
var className = dictionary[obj];
var total = 0;
// Cycle through all tr's with the current class, get the amount from each, add them to the total
$("table tr." + className).each(function() {
total += parseInt($(this).children(".td2").text());
});
// Append a td with the total.
$("table tr." + className).append("<td>Total: " + total + "</td>");
}
Fiddler (on the roof): http://jsfiddle.net/ABRsj/
assuming the tr only has one class given!
var sums = [];
$('.td2').each(function(){
var val = $(this).text();
var parentClass = $(this).parent().attr('class');
if(sums[parentClass] != undefined) sums[parentClass] +=parseFloat(val);
else sums[parentClass] = parseFloat(val);
});
for(var key in sums){
$('<tr><td>Total ('+key+')</td><td>'+sums[key]+'</td></tr>').appendTo($('table'));
}
I would give the table some ID and change to appendTo($('#<thID>'))
The solution:
http://jsfiddle.net/sLysV/2/
First stick and ID on the table and select that first with jQuery as matching an ID is always the most efficient.
Then all you need to do is match the class, parse the string to a number and add them up. I've created a simple example for you below
http://jsfiddle.net/Phunky/Vng7F/
But what you didn't make clear is how your expecting to get the value of the td class, if this is dynamic and can change you could make it much more versatile but hopefully this will give you a bit of understanding about where to go from here.

Categories

Resources