I have rows that are dynamically created and I want to append a div at the end of each row. I tried different ways to get this to happen. one time I ended up appending the div to each row but the previous rows got additional divs every time a row was added. I want only one row to have 1 cancel div at all time. (this will be like a cancel button so the user can delete the row).
in this code i am trying to go through each row with the class of row and check to see if the row has a child with a class of "cancel" and if there is none append the div cancel. It works the first time but not the other times.
$('.row').each(function(){
if($(".row").children(".cancel").length == 0){
$("<div class = 'cancel'>test</div>").appendTo('.row')
}
})
I tried to add the div "cancel" in the else statement when I append the rows like this
if($(".table").html().length <= 0)
{
$('.table').append($("<table>").append(tableheader).append(tr));
}else{
if($(".table").html().length > 0){
$("table").append(tr).append("<div class = 'cancel'>test</div>")
}
}
but it didn't show up at all
I know I could probably add another td to the var tr to make a new column with the div, but I'm wondering why my efforts to doing it the above way was a unsuccessful. It should work. excuse my ignorance .
here is the jsfiddle for illustration. maybe there is something wrong with the code somewhere else.
I have another problem in the code that I think that you could help me out with. Its with the total amount in the total column. the format is coming out as 7.5 instead of 7.50, normal dollar pricing figures. and when im on grilled chicken cutlet and choose qnty = 3 the total is 38.849999999999994 i thought toFixed(2) and parseFloat would fix that but they didn't work. obviously I would like 38.85.
I think the problem is in the way you are accessing the table rows while appending the div.
$('.row').each(function(){
if($(".row").children(".cancel").length == 0){
$("<div class = 'cancel'>test</div>").appendTo('.row')
}
});
The above script always searches for the class .row while appending the div. So if you have a div appended to any one of the .row class, if condition fails.
Solution:
To fix the problem, use $(this) to access the each row in the loop.
$('.row').each(function(){
if($(this).children(".cancel").length == 0){
$("<div class = 'cancel'>test</div>").appendTo($(this))
}
});
Also to fix your second issue of price, change
$(".total",$row).html(parseFloat(qnty * price));
to
$(".total",$row).html(parseFloat(qnty * price).toFixed(2));
Check the updated Demo Fiddle.
try this:
$('.row').each(function(idx, val){
if($(val).children(".cancel").length == 0){
$("<div class = 'cancel'>test</div>").appendTo(val);
}
});
you can do this
a)console.log($('.row').length)// to see the length
$("test").appendTo('.row') //this.code should "$("test").appendTo($(this)) "
I think what i say above may helpful; try your self
Related
I have a slight problem in a feature I am trying to implement on a web page. I have two images, a plus and a minus sign, when plus is clicked it clones a div which consists of a few text box's. The minus image is meant to delete this div.
At the moment, I cannot seem to find a way to stop the last div from being deleted when I click on the minus. I want to just prevent the last row from being deleted and using an alert to inform the user that it cannot be deleted.
Can anyone give me some insight to this? I've searched on here for a while and found something similar, but it's all done using JQuery which I have no experience with.
Here is the code I am using to try and delete the div's.
function deleteRow1() {
// row-to-clone1 is the name of the row that is being cloned
var div = document.getElementById('row-to-clone1');
if (div) {
div.parentNode.removeChild(div);
}
if ((div).length != 1) {
alert("Cannot delete all rows.").remove();
}
}
When I try do delete the row it displays the alert but still deletes the div. I realise this is probably a very easy fix and my implementation of the above may not be correct, if anyone can help I would appreciate it.
ID of an element must be unique, so use a class to fetch them
function deleteRow1() {
// row-to-clone1 is the name of the row that is being cloned
var divs = document.getElementsByClassName('row-to-clone1');
if (divs.length > 1) {
divs[0].parentNode.removeChild(divs[0]);
} else {
alert("Cannot delete all rows.")
}
}
function add1() {
var div = document.getElementById('row-to-clone1');
if (div) {
var clone = div.cloneNode(true);
delete clone.id;
div.parentNode.appendChild(clone);
}
}
<button onclick="add1()">Add</button>
<button onclick="deleteRow1()">Delete</button>
<div id="row-to-clone1" class="row-to-clone1">div</div>
Here's my latest version of this code. The 1st line iterates through the rows of a table skipping over the 1st row. For each row I test to see if the (class='dim') state of one of 8 tag elements (index j) on that row matches the corresponding !'dim' state of a set of 8 filters that the user can toggle. The idea is to set any rows where the 'active' filter / 'dim' tag states line up, to the 'hide' class, so they can disappear from the table that the user sees. The CSS for disappearing it is: .hide {display:none;}
It's that last 'if' statement that's killing me. I've tried dozens of versions but I always get some form of syntax error, undefined variable, etc. In that line of code here I've removed my latest set of +, ', " characters to better show clearly what I'm trying to do.
I don't just want something that works to replace this code. And I'm not interested in the shortest trickiest way to do it. I'd like to see some simple obvious code that I could easily understand a year from now so I can solve problems like this myself. Thanks in advance.
var thisRow = $('tbody tr:gt(0)').each(function() {
for (var i=0,j=4;i<8;i++,j++) {
if (!$('.butt').eq(i).hasClass('dim')) {
if (thisRow.nth-child(j)).hasClass('dim')) $(this).addClass('hide');
else $(this).removeClass('hide');
}
}
}
Above this line is the question as I first asked it. Below this is the complete function in case anyone else might find this useful. Thanks to Mr. Pavlikov for the lesson!
function filterTbl() { //Hide rows that don't satisfy all active filters
var butts=$('.butt'); //Each filter button has class 'butt'
$('tbody tr:gt(0)').each(function() { //iterate each table row except the 1st
var thisRow = $(this); //the row being examined
var chilluns = thisRow.children(); //all td's in the row being examined
for (var i=0,j=4;i<8;i++,j++) {
if (!butts.eq(i).hasClass('dim')) { //If this filter is active
//and If the corresponding tag is not active (is 'dimmed'), then hide this row
if (chilluns.eq(j).hasClass('dim')) thisRow.addClass('hide');
else thisRow.removeClass('hide'); //else unhide this row
}
}
});
}
First of all you should be getting thisRow variable like this (not like you are currently doing)
$('tbody tr:gt(0)').each(function() {
var thisRow = $(this);
}
And what does nth-child stand for? Use nth-child selector correctly or use siblings at least if you are willing to compare one row with other rows. I didn't quite understand what are you trying to do, but hope this helps.
And some usefull tips. You do not need to find $('.butt') EVERY TIME in the loop, just find it once before your each loop:
var butts = $('.butt');
So now you will be able to replace
$('.butt').eq(i)
with
butts.eq(i)
This is significant speedup.
Also if n-th child you are trying to find is something that is inside thisRow, find children and do .eq() on them.
I have a List that shows Products. When I click on one, I need to change the class of the <li> so as to show that it is clicked. I got this working... But what I can't do is clear the other <li> that have been previously clicked so as to show it is not selected anymore.
This is part of my code, what am I doing wrong? btw, my logic here is to first refresh all classes to notselected, and then just update the list with my product id number. this can be seen on the second line of code.
I'm new to javascript, and did my research, and this is what I got.
function showdetails(ProductID) {
document.getElementsByName("ProductList").className = "notselected";
$("#"+ProductID).attr('class','selected');
Are you trying to do this?
function showdetails(ProductID) {
$("[name=ProductList].selected").removeClass('selected');
$("#"+ProductID).addClass('selected');
}
I think you need to iterate across all elements returned in document.getElementsByName("ProductList") and change className to each element individually.
var productLists = document.getElementsByName('ProductList');
for (i = 0; i < productLists.length; i++) {
productLists[i].className = 'notselected'
}
I seem to be doing something wrong in the following code: http://jsfiddle.net/yunowork/qKj6b/1/
When you click next, the text within the span .hiddentext should be displayed in the span .showtext on top and correspond to the right Race (Rn). For example when R3 is highlighted the content of that .hiddentext "Race 3Oregon 14:30" should be displayed within the span .showtext.
This is the line where I make a mistake:
$('.showtext').text($('.hiddentext').first('td:first').text());
What am I doing wrong here?
Let's start simple:
Your problem:
$('.showtext').text($('.hiddentext').first('td:first').text());
you are saing, that, grab all .hiddentext, choose the first that has a td ... witch is not what you have in code, you have, td that contains hiddentext... so, the other way around.
What you want to do is simply get the current NEXT td and grab the hiddentext, so, just change to:
$('.showtext').text($nextCol.find('.hiddentext').text());
Now, can you see that the <br/> is not correctly rendered? That's because you are setting the text property, and you should set the html property.
the final code should be something like:
$('.showtext').html($nextCol.find('.hiddentext').html());
live example: http://jsfiddle.net/qKj6b/8/
Your code:
every time you need to have placeholders to provide some data to a context, please, DO NOT USE HTML TAGS to hold such values and hide them... make the use of the data- attribute, witch is a HTML5 complience, and works very well in any browser even if it does not have not HTML5 support, like IE6.
your table definition (td) that currently is:
<td class="visible" id="r2">
<span class="hiddentext">Race 2<br />Santa Fe 12:00</span>
<strong>R2</strong>
</td>
should be something like:
<td class="visible" id="r2" data-text="Race 2<br />Santa Fe 12:00">
R2
</td>
witch is way easier to read, and from your javascript code, you can easily get this as:
var hiddenText = $nextCol.data("text");
Your code (part 2):
This one is quite simple to know
Every time you are repeating yourself, you're doing it wrong
You have the methods for Next and Prev almost exactly as each other, so, you are repeating everything, for this, you should refactor your code and just use one simple method, this way, any future change only happens in one place, and one place only.
$(".next").click(function(e){
e.preventDefault();
var $nextCol = $('.highlighted').next('td');
MoveCursor($nextCol, 'next');
});
$(".previous").click(function(e){
e.preventDefault();
var $prevCol = $('.highlighted').prev('td');
MoveCursor($prevCol, 'prev');
});
function MoveCursor(col, side) {
var maxCol = 8;
if((side === 'next' && col.length != 0) ||
(side == 'prev' && col.length != 0 && col.index() >= maxCol)) {
$('.highlighted').removeClass("highlighted");
col.addClass("highlighted");
// show current title
$('.showtext').html(col.data('text'));
if (col.hasClass("invisible")) {
col.removeClass("invisible");
col.addClass("visible");
var $toRem;
if(side == 'prev')
$toRem = col.next('td').next('td').next('td').next('td').next('td').next('td');
else
$toRem = $nextCol.prev('td').prev('td').prev('td').prev('td').prev('td').prev('td');
$toRem.removeClass("visible");
$toRem.addClass("invisible");
}
}
}
Live Example: http://jsfiddle.net/qKj6b/22/
It should be
$('.showtext').html($('.highlighted .hiddentext').html());
Similar for the prev link...
or even better, thanks to #balexandre:
$('.showtext').html($nextCol.find('.hiddentext').html());
$('.showtext').html($prevCol.find('.hiddentext').html());
Fiddle
Update to match #balexandre hint: Fiddle 2
Do the following:
var $currCol = $('.highlighted'); //to get the current column
$('.race strong').text($currCol.closest('.highlighted').first('td:first').text());
.hiddentext class selects all the spans and the first() will always return you the first td.
Just make sure you select .hiddentext from the currently highlighted column and you are good to go.
$('.showtext').text($('.highlighted .hiddentext').first('td:first').text());
Try this (Same for both)
$('.showtext').html($currCol.find('span.hiddentext').html());
Working Example.
I used to be able to append a child to a list dynamical but now for some reason the JavaScript functions stop working. Also the error console does not throw any errors and I have place several alert('') methods in between the code to make sure that the method is actually running. this is what I used to have and it used to work perfectly fine:
var o = document.getElementById('searchResults');
var li = document.createElement('li'); //creates a list item tag
//if counter is even then highlight the cell different than an odd one
if ((counter) % 2 == 0) {
li.setAttribute('class', 'par');
} else {
li.setAttribute('class', 'non');
}
// I copied the inner html from a row that was displaying. I got rid of the dynamic variables
// just so it is a little easier to understand.
li.innerHTML = "<label class='list3p1'>testing</label><label class='list3p2'>testing2</label><label class='list3p3'>2:23</label>";
o.appendChild(li);
this function was working but as I added other tables to index.php this functions stopped working. Moreover I have used this similar method in other pages. Also other methods are working and that is the only function that does not seem to work.
It had to do with the visibility. It took me a long time to find. I had the id of the table repeated and the visibility of the other table was hidden therefore I was adding items to a hidden table. sorry for the fool question.