Not able to display all values in an html table - javascript

For unknown reasons to me I cannot display the last (sProductLink) value in this table :
<thead>
<tr>
<th>Id</th>
<th>Product Name</th>
<th>Brand</th>
<th>Price</th>
<th>Link</th>
</tr>
</thead>
I cannot see any reason for this issue. The html is the same as for the other elements.
Whne I look in the DOM I don't see the "Link" <td> at all, which means it is not added for some reason.
Here is the code for this. I will really appreciate if someone has a look at this.
$("#lblEditDeleteProducts").append('<tr><th class="idDom" scope="row">'
+sProductId+"<span data-i-user-id='"
+sProductId+"'</span>"
+"<button type='button' id='editBtn' class='btn btn-warning editBtn' data-toggle='modal' data-target='#myModal'>Edit</button>"
+ "<button id='deleteBtn' class='btn btn-danger deleteBtn'>Delete</button>"
+'</th><td class="nameDom">'
+sProductName+'</td><td class="brandDom">'
+sProductBrand+'</td><td class="priceDom">'
+sProductPrice+'</td><td class="linkDom">'
+sProductLink+'</td></tr>');
P.S. I'd also appreciate any tips on how can I do what I am doing here in an alternative(better) way. Without all the apostrophes and etc.

This part of your string:
"<span data-i-user-id='" +sProductId+"'</span>"
Should probably be:
"<span data-i-user-id='" +sProductId+"'></span>"
This is why building HTML via string concatenation is a colossal pain.

In the area where the skull 💀 is indicating, there's no greater than bracket > to close the inside of the <span>.
$("#lblEditDeleteProducts").append(
'<tr>
<th class="idDom" scope="row">'+sProductId+'
<span data-i-user-id="'+sProductId+'"💀</span>
<button type="button" id="editBtn" class="btn btn-warning editBtn" data-toggle="modal" data-target="#myModal">
Edit
</button>
<button id="deleteBtn" class="btn btn-danger deleteBtn">
Delete
</button>
</th>
<td class="nameDom">'+sProductName+'</td>
<td class="brandDom">'+sProductBrand+'</td>
<td class="priceDom">'+sProductPrice+'</td>
<td class="linkDom">'+sProductLink+'</td>
</tr>');
SNIPPET
var sProductId = 'sProd01';
var sProductName = 'sProExtreme';
var sProductBrand = 'sProâ„¢';
var sProductPrice = 54.99;
var sProductLink = 'http://shop.spro.com';
$("#lblEditDeleteProducts").append('<tr><th class="idDom" scope="row">' + sProductId + '<span data-i-user-id="' + sProductId + '"></span><button type="button" id="editBtn" class="btn btn-warning editBtn" data-toggle="modal" data-target="#myModal">Edit</button><button id="deleteBtn" class="btn btn-danger deleteBtn">Delete</button></th><td class="nameDom">' + sProductName + '</td><td class="brandDom">' + sProductBrand + '</td><td class="priceDom">' + sProductPrice + '</td><td class="linkDom">' + sProductLink + "</td></tr>");
table {
border: 5px inset orange;
}
tr {
background: rgba(0, 0, 0, .7);
}
th {
border: 5px dashed green;
color: yellow;
}
td {
border: 2px inset blue;
color: cyan;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/g/fontawesome#4.6.3,bootstrap#3.3.7(css/bootstrap.min.css+css/bootstrap-theme.min.css)">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="lblEditDeleteProducts"></table>

I strongly suggest that you write the HTML that you're trying to append inside an editor, spaced out so you can see the structure properly and debug from there. You can minify it afterwards and test to ensure that it's in working order.
<tr>
<th class="idDom" scope="row">
+ sProductId +
<span data-i-user-id='"+sProductId+"'><!-- Closing '>' added (Thanks Matt) --></span>
<button type='button' id='editBtn' class='btn btn-warning editBtn' data-toggle='modal' data-target='#myModal'>
Edit
</button>
<button id='deleteBtn' class='btn btn-danger deleteBtn'>
Delete
</button>
</th>
<td class="nameDom">
+ sProductName +
</td>
<td class="brandDom">
+ sProductBrand +
</td>
<td class="priceDom">
+ sProductPrice +
</td>
<td class="linkDom">
+ sProductLink +
</td>
</tr>
Dont forget the "" marks around your HTML

Related

Extracting the column data corresponding to the button which is clicked in the same table row

I am working on deleting functionality. Based on the search the table generates rows along with the delete buttons. when the button is clicked, the show id column value should be extracted from the table column and it should be sent to backend through ajax.
As a first step i am trying to extract show id column value from the same row where the delete button is clicked. but i am facing two issues
When i try to click the delete button, other search button is getting triggered.
I am not able to extract show id column value corresponding to the button click of the same row.
<script>
$(document).ready(function(){
$('#search-movie').on('submit',function (e) {
$.ajax({
type: 'POST',
url: '/search',
data: $('#search-movie').serialize(),
success: function (q) {
var trHTML='';
$.each(q, function (i, userData) {
for(j=0; j<userData.length; j++)
{
trHTML +=
'<tr><td style="padding-right: 10px">'
+ userData[j].showid
+ '</td><td style="padding-right: 10px">'
+ userData[j].typeof
+ '</td><td style="padding-right: 10px">'
+ userData[j].title
+ '</td><td style="padding-right: 10px">'
+ userData[j].directors
+ '</td><td style="padding-right: 10px">'
+ userData[j].cast
+ '</td><td style="padding-right: 10px">'
+ userData[j].country
+ '</td><td style="padding-right: 10px">'
+ userData[j].releaseyear
+ '</td><td style="padding-right: 10px">'
+ userData[j].rating
+ '</td><td style="padding-right: 10px">'
+ userData[j].duration
+ '</td><td style="padding-right: 10px">'
+ userData[j].listedin
+ '</td><td style="padding-right: 10px">'
+ userData[j].description
// + '</td></tr style="padding-right: 10px">'
+ '</td><td style="padding-right: 10px">'
+ '<button id="button2" class="btn btn-info" onClick="clickme()">delete</button>'
+ '</td></tr>'
}
});
$('#table1').append(trHTML);
}
});
e.preventDefault();
});
})
</script>
<script>
function clickme()
{
$(".btn btn-info").click(function() {
var $item = $(this).closest("tr").find(".nr").text();
console.log($item);
$("#table1").append($item);
});
}
</script>
<div class="form-group">
<input type="submit" name="submit" class="btn btn-info btn-md" value="submit">
<button class="btn btn-info btn-md" id="button1" onClick="window.location.reload();">reset</button>
</div>
<table id="table1" name="table1">
<thead>
<tr>
<th style="padding-right: 10px">Show ID</th>
<th style="padding-right: 10px"> Type</th>
<th style="padding-right: 10px">Title</th>
<th style="padding-right: 10px">Director</th>
<th style="padding-right: 10px">Cast</th>
<th style="padding-right: 10px">Country</th>
<th style="padding-right: 10px">Release Year</th>
<th style="padding-right: 10px">Rating</th>
<th style="padding-right: 10px">Duration</th>
<th style="padding-right: 10px">Listed In</th>
<th style="padding-right: 10px">Description</th>
</tr>
</thead>
<tbody>
</table>
Issue 1: This is due to button vs input type='submit'
seems your form submission happening and it goes to search functionality - when you click the delete button.
Use input type=button (Solution1)
or button on click as return false to avoid submission (solution 2)
Note: Don't forget, type="submit" is the default with button, so leave it off! Ref: input type="submit" Vs button tag are they interchangeable?
2. For on click, you can attach event using the CSS value. $(".btn btn-info").click(function() { .... or in DOM attach the clickme in onClick. Not required to have bot in the function definition.
<script>
function clickme()
{
$(".btn btn-info").click(function() {
var $item = $(this).closest("tr").find(".nr").text();
console.log($item);
$("#table1").append($item);
});
}
</script>

How to fix table row no being clicked after append function?

I am trying to create a new table row every time the associated button is clicked. However, once I click the button and I go to select the row, it does not get highlighted. I have an append function that passes a <tr> to the html. My end goal is to have the the new row that was appended become clickable and can be selected.
Code:
<div class="col-md-3 left-pane">
<div class="row justify-content-md-center">
<button class="btn btn-sm btn-block eNew">New Tier</button>
</div>
<hr>
<table class="table table-sm table-hover tAdd">
<tbody>
<tr>
<td>IIS</td>
<td><button class="btn btn-sm btnD">Delete</button></td>
</tr>
<tr>
<td>SQL</td>
<td><button class="btn btn-sm btnD">Delete</button></td>
</tr>
<tr>
<td>Windows File Share</td>
<td><button class="btn btn-sm btnD">Delete</button></td>
</tr>
<tr>
<td>Etc</td>
<td><button class="btn btn-sm btnD">Delete</button></td>
</tr>
</tbody>
</table>
</div>
Javascript:
$(".eNew").on("click", function(event){
$(".tAdd tbody").append(
"<tr>" +
"<td>New Selector</td>" +
"<td><button class=\"btn btn-sm btnD\">Delete</button></td>" +
"</tr>"
);
$(".tAdd tr").click(function() {
$(".tAdd tr").removeAttr('class');
$(this).toggleClass("table-active");
});
Also, it works for the original <tr> that is in the html file but for some reason when I append a table row it does not work.
This is entirely due to the fact that dynamic content is not bound using the event handler you have declared:
$(".eNew").on("click", function(event){
Although this will bind to all .eNew elements when the code first runs, new elements will not be bound.
Instead, bind to the document and specify .eNew as a selector for the click event and it will work:
$(document).on("click", ".eNew", function(event){
Edit following OP comment about not working
Just to verify that your code should now look like this:
$(document).on("click", ".eNew", function(event){
$(".tAdd tbody").append(
"<tr>" +
"<td>New Selector</td>" +
"<td><button class=\"btn btn-sm btnD\">Delete</button></td>" +
"</tr>"
);
});
$(document).on("click", ".tAdd tr", function(event){
$(".tAdd tr").removeAttr('class');
$(this).toggleClass("table-active");
});

Pass appendTo dynamic rows value to bootstrap modal

I am currently using appendTo to add dynamic rows. What I want to happen is that if I will click one of the td (not including the remove button), It will open a bootstrap modal window and get the value of other td of its belonging row. here's the image.
Here's my code adding dynamically that I want to get the value of td and pass it to bootstrap modal.
function AddOrder(new_code, new_name, new_qtty, new_cost) {
var rows = "";
var code = new_code;
var name = new_name;
var cost = new_cost;
var qtty = new_qtty;
rows +=
'<tr>"' +
'<td class="item_code" data-toggle="modal" data-target="#mymodal">'+code+'</td>'+
'<td class="item_name" data-toggle="modal" data-target="#mymodal">'+name+'</td>'+
'<td class="item_qtty" data-toggle="modal" data-target="#mymodal">'+qtty+'</td>'+
'<td class="item_cost" data-toggle="modal" data-target="#mymodal">'+cost+'</td>'+
'<td>'+'<button class="btn remove-button">X</button>'+'</td>'+
'</tr>';
$(rows).appendTo("#dynamic_added tbody");
}
I tried putting putting onclick on td with data-toggle="modal" data-target="#mymodal" but only the modal is working not the function I'm using for example:
function GetData() {
$('.item_code').click(function(){
alert($(this).closest('tr').find('.item_code'));
});
}
I just solved my own problem just a bootstrap modal call is all I am missing.
I addded a class getdata that I will call to my javascript function
function AddOrder(new_code, new_name, new_qtty, new_cost) {
var rows = "";
var code = new_code;
var name = new_name;
var cost = new_cost;
var qtty = new_qtty;
rows +=
'<tr>"' +
'<td class="item_code getdata" onclick="GetData();">'+code+'</td>'+
'<td class="item_name getdata" onclick="GetData();">'+name+'</td>'+
'<td class="item_qtty getdata" onclick="GetData();">'+qtty+'</td>'+
'<td class="item_cost getdata" onclick="GetData();">'+cost+'</td>'+
'<td>'+'<button class="btn remove-button">X</button>'+'</td>'+
'</tr>';
$(rows).appendTo("#dynamic_added tbody");
}
If I will click anywhere to the td except the button It will pop up the modal and pass the current data of that row.
function GetData() {
$(document).on('click', '.getdata', function(){
$('#mymodal').modal();
var modal_code =$(this).closest('tr').find('.item_code').text();
var modal_name =$(this).closest('tr').find('.item_name').text();
var modal_qtty =$(this).closest('tr').find('.item_qtty').text();
var modal_cost =$(this).closest('tr').find('.item_cost').text();
var modal = $("#mymodal"); // this is the id of my modal
modal.find('.modal-body').text(modal_code + modal_name + modal_qtty + modal_cost);
});
}
Do you want something like this:
$('.item_code, .item_name, .item_qtty, .item_cost').click(function() {
$('.modal-body').html($(this).closest('tr').html());
$('#myModal').modal('show');
});
td {
border: 1px solid black;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<table id="dynamic_added">
<tbody>
<tr>
<td class="item_code">code_1</td>
<td class="item_name">name_1</td>
<td class="item_qtty">qtt_1</td>
<td class="item_cost">cost_1</td>
<td>
<button class="btn remove-button">X</button>+</td>
</tr>
<tr>
<td class="item_code">code_2</td>
<td class="item_name">name_2</td>
<td class="item_qtty">qtt_2</td>
<td class="item_cost">cost_2</td>
<td>
<button class="btn remove-button">X</button>+</td>
</tr>
<tr>
<td class="item_code">code_3</td>
<td class="item_name">name_3</td>
<td class="item_qtty">qtt_3</td>
<td class="item_cost">cost_3</td>
<td>
<button class="btn remove-button">X</button>+</td>
</tr>
</tbody>
</table>
<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>

Bootstrap table row detail - ajax data

Im loading row detail information in a bootstrap table via an Ajax call with the id as parameters .
This details show within a collapsible row using a glyph icon button.
However,clicking back on the button to collapse the row end up in distorting the display.
I've been struggling to find a fix to it although the code seems correct.
May you find the jsFiddle here
var parentsData = {
"success": true,
"parents": [{
"id": 1531,
"Firstname": "Austin",
"Surname": "Ana\u00eblle",
"schoolId": "046039",
"schoolName": "ARCAMBAL",
"commune": "ARCAMBAL"
}, {
"id": 2032,
"Firstname": "Ramos",
"Surname": "L\u00e8i",
"schoolId": "046043",
"schoolName": "J CALVET",
"commune": "CAHORS"
}, {
"id": 3036,
"Firstname": "Baker",
"Surname": "Salom\u00e9",
"schoolId": "046043",
"schoolName": "Z LAFAGE",
"commune": "CAHORS"
}, {
"id": 1724,
"Firstname": "Berry",
"Surname": "Marl\u00e8ne",
"schoolId": "046044",
"schoolName": "J CALVET",
"commune": "CAHORS"
}]
};
var $table = $('.js-table');
$table.find('.js-view-parents').on('click', function(e) {
e.preventDefault();
if (!$(this).closest('tr').next('tr').hasClass('expand-child')) {
$(e.target).toggleClass('glyphicon-eye-close glyphicon-eye-open');
$(".expand-child").slideUp();
var $this = $(this).closest('tr');
var rowId = $(this).data('id');
var newRow = '<tr class="expand-child">' + '<td colspan="12" id="collapse' + rowId +
'">' +
'<table class="table table-condensed table-bordered" width=100% >' +
'<thead>' +
'<tr>' +
'<th>Surname</th>' +
'<th >FirstName</th>' +
'<th >School Id</th>' +
'<th >School name</th>' +
'</tr>' +
'</thead>' +
'<tbody>';
$.ajax({
url: '/echo/json/',
dataType: "json",
data: parentsData,
success: function(parentsData) {
if (parentsData.parents) {
var parents = parentsData.parents;
$.each(parents, function(i, parent) {
newRow = newRow + '<tr scope="row">' +
'<td>' + parent.Firstname + '</td>' +
'<td>' + parent.Surname + '</td>' +
'<td>' + parent.schoolId + '</td>' +
'<td>' + parent.schoolName + ' ' + parent.commune +
'</td>' +
'</tr>';
});
newRow = newRow + '</tbody></table></td></tr>';
}
$(newRow).insertAfter($this);
}
});
} else {
$(this).closest('tr').slideToggle();
var $detailRow = $(this).closest('tr').next('tr').hasClass('expand-child');
$detailRow.style.visibility.toggle('table-row collapse');
$(e.target).toggleClass('glyphicon-eye-close glyphicon-eye-open');
}
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<container>
<table class="table table-striped table-hover js-table">
<thead>
<tr>
<th>Training</th>
<th>Title</th>
<th>Date</th>
<th>End date</th>
<th>Description</th>
<th>nb of Applicants</th>
<th>Actions</th>
</tr>
</thead>
<tr data-toggle="collapse" data-target="#collapse4039" class="clickable">
<td>Activités nautiques</td>
<td>Activités nautiques - 16/10/2016</td>
<td>16/oct./2016</td>
<td>13/oct./2016</td>
<td>Sequelae of viral hepatitis</td>
<td>15</td>
<td>
<div class="btn-group btn-group-sm" role="group" aria-label="...">
<div class="btn-group " role="group" aria-label="Voir le detail">
<a href="#" class="parents js-view-parents" data-href="formation_json_parents" data-id=4039 data-toggle="tooltip" data-placement="top" alt="Voir les details" title="Voir les inscrits">
<span class="glyphicon glyphicon-eye-close" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group " role="group" aria-label="Valider les candidats">
<a href="valider" data-href='' alt="Valider les candidats" data-toggle="tooltip" data-placement="right" title="Valider les candidats">
<span class="glyphicon glyphicon-check" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group " role="group" aria-label="Imprimer la liste d'emargement pour cette formation">
<a href="/edsa-AgrementEPS/app_dev.php/formation/4039/liste?print=pdf" data-href="" alt="Download PDF list of applicants" data-toggle="tooltip" data-placement="right" name="Activités nautiques - 16/10/2016" title="Download PDF list of applicants">
<span class="glyphicon glyphicon-download-alt" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
</div>
</td>
</tr>
<tr data-toggle="collapse" data-target="#collapse4095" class="clickable">
<td>Activités nautiques</td>
<td> Activités nautiques - 24/10/2016</td>
<td>24/oct./2016</td>
<td>21/oct./2016</td>
<td>Severe pre-eclampsia, third trimester</td>
<td>0</td>
<td>
<div class="btn-group btn-group-sm" role="group" aria-label="...">
<div class="btn-group hidden" role="group" aria-label="Voir le detail">
<a href="#" class="parents js-view-parents" data-href="formation_json_parents" data-id=4095 data-toggle="tooltip" data-placement="top" alt="Voir les details" title="Voir les inscrits">
<span class="glyphicon " aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group hidden" role="group" aria-label="Valider les candidats">
<a href="/valider" data-href='' alt="Valider les candidats" data-toggle="tooltip" data-placement="right" title="Valider les candidats">
<span class="glyphicon glyphicon-check" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group hidden" role="group" aria-label="Imprimer la liste d'emargement pour cette formation">
<a href="/print=pdf" data-href="" alt="Download PDF list of applicants" data-toggle="tooltip" data-placement="right" name="Activités nautiques - 24/10/2016" title="Download PDF list of applicants">
<span class="glyphicon glyphicon-download-alt" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
</div>
</td>
</tr>
<tr data-toggle="collapse" data-target="#collapse3188" class="clickable">
<td>Activités nautiques</td>
<td>Activités nautiques - 29/10/2016</td>
<td>29/oct./2016</td>
<td>26/oct./2016</td>
<td>Other secondary chronic gout</td>
<td>0</td>
<td>
<div class="btn-group btn-group-sm" role="group" aria-label="...">
<div class="btn-group " role="group" aria-label="Voir le detail">
<a href="#" class="parents js-view-parents" data-href="formation_json_parents" data-id=4039 data-toggle="tooltip" data-placement="top" alt="Voir les details" title="Voir les inscrits">
<span class="glyphicon glyphicon-eye-close" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group " role="group" aria-label="Valider les candidats">
<a href="valider" data-href='' alt="Valider les candidats" data-toggle="tooltip" data-placement="right" title="Valider les candidats">
<span class="glyphicon glyphicon-check" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group " role="group" aria-label="Imprimer la liste d'emargement pour cette formation">
<a href="/liste?print=pdf" data-href="" alt="Download PDF list of applicants" data-toggle="tooltip" data-placement="right" name="Activités nautiques - 16/10/2016" title="Download PDF list of applicants">
<span class="glyphicon glyphicon-download-alt" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
</div>
</td>
</tr>
</table>
</container>
The main problem is that you attached the ID for collapsing on the wrong element. It should be attached to the tr.expand-child element and not the .expand-child td element.
I would build the .expand-child row in its entirety only once you have an AJAX response.
And it's a good habit to cache elements that you will be re-using.
Here's how I would revise your code:
var $table = $('.js-table');
$table.find('.js-view-parents').on('click', function(e) {
e.preventDefault();
// cache elements
var $btn = $(e.target), $row = $btn.closest('tr'),
// find next immediate .expand-child
$nextRow = $row.next('tr.expand-child');
// toggle button
$btn.toggleClass('glyphicon-eye-close glyphicon-eye-open');
// if .expand-child row exist already, toggle
if ($nextRow.length) {
// show or hide .expand-child row if eye button is open or not, respectively
$nextRow.toggle($btn.hasClass('glyphicon-eye-open'));
// if not, create .expand-child row
} else {
$.ajax({
url: '/echo/json/',
dataType: "json",
data: parentsData,
success: function (parentsData) {
var newRow = '<tr class="expand-child" id="collapse' + $btn.data('id') + '">' +
'<td colspan="12">' +
'<table class="table table-condensed table-bordered" width=100% >' +
'<thead>' +
'<tr>' +
'<th>Surname</th>' +
'<th>FirstName</th>' +
'<th>School Id</th>' +
'<th>School name</th>' +
'</tr>' +
'</thead>' +
'<tbody>';
if (parentsData.parents) {
$.each(parentsData.parents, function(i, parent) {
newRow += '<tr>' +
'<td>' + parent.Firstname + '</td>' +
'<td>' + parent.Surname + '</td>' +
'<td>' + parent.schoolId + '</td>' +
'<td>' + parent.schoolName + ' ' + parent.commune + '</td>' +
'</tr>';
});
}
newRow += '</tbody></table></td></tr>';
$row.after(newRow);
}
});
}
});
Demo
For demo purposes, I have commented out the AJAX call.
There are several things wrong in your else block. First of all,
$(this).closest('tr').slideToggle();
is going to slide up your parent row, which is not what you want - you want to hide the child row.
var $detailRow = $(this).closest('tr').next('tr').hasClass('expand-child');
hasClass() will return a boolean, you cannot use it to filter a jQuery collection. What you are trying to do is select the next <tr> that has the class .expand-child, like this:
var $detailRow = $(this).closest('tr').next('tr.expand-child');
The next line makes absolutely no sense.
$detailRow.style.visibility.toggle('table-row collapse');
I guess you want to toggle the classes of that row instead:
$detailRow.toggleClass('table-row collapse');
These changes will make the first showing/hiding work. But then there's a problem in your if block as well:
$(".expand-child").slideUp();
This will select all elements with the class .expand-child in the DOM. But you'll probably want to only select the child row of the current parent row.
I am, however, not going to debug this whole code for you. I think, I have made some of the main issues clear (see this updated fiddle: https://jsfiddle.net/r7sgL7vy/2/) and you'll hopefully be able to go on from here yourself.
One more tipp: For performance, store jQuery collections that you use more than once in variables instead of querying them every time you need them. You already do this with $detailRow for example, and with $this = ... - but it's not used consequently. Why not select and declare all the needed dom elements at the start of the click event handler and then use them everywhere? Besides the performance factor, it also makes your code much cleaner, easier to understand (for you and for others) and easer to spot any mistakes in your logic.

Stop duplicate values when appending from array to table in real time

I am currently running through a loop to pull values our of an array, and most of it works, but when I add a 2nd value it duplicates the new value and previous value into the table.
So when I add a row with value 488 it works fine:
<tr class="exe">
<td class="sipname">1446033619.75</td>
<td class="siptd">SIP/488-00000027</td>
<td><button class="btn btn-default unmute" id="mute" type="submit">Unmute</button></td>
<td><button class="btn btn-default kick" id="kick" type="submit">Kick</button></td>
</tr>
When I add another value then say 487 then duplicates the same row 488, 488, 487 in that order as so:
<tbody id="sip">
<tr class="exe">
<td class="sipname">1446033619.75</td>
<td class="siptd">SIP/488-00000027</td>
<td><button class="btn btn-default unmute" id="mute" type="submit">Unmute</button></td>
<td><button class="btn btn-default kick" id="kick" type="submit">Kick</button></td>
</tr>
<tr class="exe">
<td class="sipname">1446033619.75</td>
<td class="siptd">SIP/488-00000027</td>
<td><button class="btn btn-default mute" id="mute" type="submit">Mute</button></td>
<td><button class="btn btn-default kick" id="kick" type="submit">Kick</button></td>
</tr>
<tr class="exe">
<td class="sipname">1446033747.78</td>
<td class="siptd">SIP/487-00000028</td>
<td><button class="btn btn-default mute" id="mute" type="submit">Mute</button></td>
<td><button class="btn btn-default kick" id="kick" type="submit">Kick</button></td>
</tr>
</tbody>
All I need is 488,487 in table rows without duplicates, when i refresh the page it works fine. I am using socket.io (Express), node.js and Jquery.
I did find a small workaround using jquery remove, but it affects functionality I have meaning a minor bug so I need to not use the jquery remove.
socket.on('sipname', function (data, datad) {
var sipname = '';
var sipid = '';
$('.exe').remove();
for (var i = 0; i < data.length; i++) {
sipname = data[i];
sipid = datad[i];
if (sipname) {
$sip.append('<tr class="exe">\
<td class="sipname">' + sipid + '</td>\
<td class="siptd">' + sipname + '</td>\
<td><button class="btn btn-default mute" id="mute" type="submit">Mute</button></td>\
<td><button class="btn btn-default kick" id="kick" type="submit">Kick</button></td>\
</tr>');
}
}
});
Any ideas or guidance would be appreciated, this is stopping me from completing my first version of my application.
1st : again and again ID must be unique
2nd: you can try this code .. I changed Ids to Class so be sure to change it in your css stylesheet .. and use data-sipname in siptd class
socket.on('sipname', function (data, datad) {
var sipname = '';
var sipid = '';
$('.exe').remove();
for (var i = 0; i < data.length; i++) {
sipname = data[i];
sipid = datad[i];
if (sipname) {
if($('#sip > tr > .siptd[data-sipname = "'+sipname+'"]').length < 1){
$sip.append('<tr class="exe">\
<td class="sipname">' + sipid + '</td>\
<td class="siptd" data-sipname="'+ sipname +'">' + sipname + '</td>\
<td><button class="btn btn-default mute" type="submit">Mute</button></td>\
<td><button class="btn btn-default kick" type="submit">Kick</button></td>\
</tr>');
}
}
}
});
hope it help
It looks like $sip is a "global"-ish value outside the socket.on function. It gets filled with values on the first .on() call, and then adds any values again on the second .on() call.
The way to fix could be one of:
Only send new data to any .on() function. That way when you append, you don't have any duplicates.
If data into the .on() function is complete each time, you can just empty the $sip array each call. $sip = [] and then append everything fresh each time.
The more complicated option is a check on each element of the array to see if it exists yet. If not, add it, otherwise skip it. Using a hash could make that easier as well, storing the ID as the key and that HTML string as the value. Then checking for existence is quick, !!$sip[ sipname ] (does the property sipname in the object $sip evaluate to true).

Categories

Resources