First of all I have to find the number of cells with one class, this line works.
var numcells = $('.hidden-td').length
And now I have to find the element with the class .placeholder-style I use this line (only one <tr>have this class):
$(this).find('.placeholder-style')
Now I have to add the same number of var numcellslike <td>inside the <tr>with the clase .hidden-td I think this will be with .addClass('hidden-td').
How can I make this?
Thanks
I'm assuming this is the correct structure you're after... if not, post your HTML so I can amend it but either way, this is how you should do it.
var numcells = $('.hidden-td').length;
var content = $(this).find('.placeholder-style');
for (i = 0; i < numcells; i++) {
content.append('<td class="hidden-td"></td>');
}
Related
I am adding a simple toggle button through Javascript. Then I want to add three span tags inside it.
So, I am creating variable of span and trying to append it inside our very own basic FOR loop. Iteration count is 3 times.
Here's my basic code below. Please let me know what has been missing or misplaced that my span tag refuses to append more than once. I checked this in the inspect mode.
Then, I brought up console tab and the value of i was 3. Append is meant to append and NOT replace the element. Right ?
var $navbar_header = $('<div class="navbar-header"></div>');
var $button = $("<button></button>");
var $span = $('<span class="icon-bar"></span>');
for (var i = 0; i < 3; i++) {
$button.append($span);
}
$button.addClass('navbar-toggle');
$navbar_header.append($button);
$("#menu").append($navbar_header);
Here's a link to fiddle.
The DOM is a tree, where any element points to its parent (see parentNode). An element can have only one location. So when you append an element, you're removing it from its precedent location.
The solution here is either to clone the element:
$button.append($span.clone());
or just to create it in the loop:
for (var i = 0; i < 3; i++) {
$button.append('<span class="icon-bar"></span>');
}
I'm trying to get data from app engine datastore using javascript and json. it's also allowed jsonp service, here the javascript code:
$.getJSON("http://1.handy-post-402.appspot.com/show?callback=?", function(json) {
for (var i = 0; i < json.length; i++) {
var map = json[i].propertyMap;
var content = map.isi;
var user = map.No_HP;
var date = map.tanggal;
$('#date').text(date);
$('#nohp').text(user);
$('#content').text(content);
}
});
you can also check it here: http://jsfiddle.net/YYTkK/7/
unfortunately, it just retrieve 1 latest data from the datastore. am I doing something wrong with this code?
thanks in advance.
You're not appending elements, but simply changing the value of the same 3 elements in question three times. So you simply overwrite the value you put into it the time before. The easiest way to solve this is to designate the existing tr as a .template and clone it in your loop, make the necessary changes (filling in the values) and then appending it.
Fixing some other unclear things this gives the following
$.getJSON("http://1.handy-post-402.appspot.com/show?callback=?", function(records) {
for (var i = 0; i < records.length; i++) {
//Clone the row/unit which we will be using for each record (the class should refer to the type of item it /actually/ is)
row = $(".row.template").clone();
//The template class is hidden, so remove the class from the row/unit
row.removeClass("template");
var map = records[i].propertyMap;
var content = map.isi;
var user = map.No_HP;
var date = map.tanggal;
//Make the required changes (find looks for the element inside var row)
row.find('.date').text(date);
row.find('.nohp').text(user);
row.find('.content').text(content);
//Append it to the parent element which contains the rows/units
$("tbody").append(row);
}
});
See functional demo: http://jsfiddle.net/YYTkK/13/
You must append a new row in the table in every loop. Here's the working fiddle.
fiddle
$.getJSON("http://1.handy-post-402.appspot.com/show?callback=?", function(json) {
for (var i = 0; i < json.length; i++) {
var map = json[i].propertyMap;
var content = map.isi;
var user = map.No_HP;
var date = map.tanggal;
var row = '<tr><td>'+date+'</td><td>'+user+'</td><td>'+content+'</td></tr>';
$('#valuetable').append(row);
}
});
what you have to do is create dynamic "tr" s and append to tbody and use thead for header and separate the body using tbody and create tr s on each iteration and after the loop append that tr to tbody. that will do the job, as you do now it will override the values at each iteration.
#chamweer answer is correct you have to create a new tr with td's dynamically
like this:
http://jsfiddle.net/YYTkK/14/
Because you're overriding the same td's over and over again.
$.getJSON("http://1.handy-post-402.appspot.com/show?callback=?", function(json) {
for (var i = 0; i < json.length; i++) {
var map = json[i].propertyMap;
var content = map.isi;
var user = map.No_HP;
var date = map.tanggal;
// create a temporary tr
var tr = $("<tr />");
// append to the tr the td's with their values
tr.append($("<td />").text(date), $("<td />").text(user),
$('<td />').text(content));
// finally append the new tr to the table's tbody
$("#js-tbody").append(tr);
}
});
I need to dynamically add a couple of things like container then find it in DOM and fill with a list of numbers. Here is the way I do it but I feel like it is redundant and maybe I should do it another way. The only issue is that I have to do it all with javascript and cant hard code any container. That is why first I add it and then try to find it.
JS Bin working example http://jsbin.com/okikohu/1/
The code:
<script>
$(function(){
var obj = $('form'),
total = 6;
obj.before('<div class="container"/>');
var container = $('body').find('.container');
for (var i = 0, limit = total; i < limit; i++) {
container.append('-<span class="step" id="is'+(i+1)+'">'+(i+1)+'</span>-');
}
});
</script>
<form>some form</form>
obj.before('<div class="container"/>');
var container = $('body').find('.container');
Instead of using before() and then a DOM query, you could create the element with the jQuery(html) constructor and simply insertBefore() it somewhere while still holding the reference:
var total = 6,
container = $('<div class="container"/>').insertBefore('form');
for(var i=0; i<num_cols; i++)
{
//Wrapper for column
$('#cupcake-list').append('<div>');
//end wrapper
col_count++;
num_in_col = rowsInCol(total,num_perCol,col_count);
start = i*num_perCol;
end = start + num_in_col;
for(var d=start; d<end; d++)
{
$('#cupcake-list').append('<p>'+cupcakeData[d].name+'</p>');
}
//Wrapper for column
$('#cupcake-list').append('</div>');
//end wrapper
}
I just want to encapsulate my p tags within div tags to act as rows, however all I get are <div></div><p>ssdfsdf</p><p>sdfsdfdsf</p><div></div>etc....
What's the best way of doing it?
Start with a fragment so that you don't access the DOM more than once, and append it all at the end. You can skip the wrap by starting with your empty fragment, like so:
var $fragment;
for(var i=0; i<num_cols; i++)
{
$fragment = $('<div />');
col_count++;
num_in_col = rowsInCol(total,num_perCol,col_count);
start = i*num_perCol;
end = start + num_in_col;
for(var d=start; d<end; d++)
{
$fragment.append('<p>'+cupcakeData[d].name+'</p>');
}
//Wrapper for column
$('#cupcake-list').append($fragment);
//end wrapper
}
This is a much faster way to do it! Append parts of a string to an array and then you only have to update the DOM once.
var a = [];
for(var i=0; i<num_cols; i++)
{
a.push('<div>');
col_count++;
num_in_col = rowsInCol(total,num_perCol,col_count);
start = i*num_perCol;
end = start + num_in_col;
for(var d=start; d<end; d++)
{
a.push('<p>'+cupcakeData[d].name+'</p>');
}
a.push('</div>');
}
$('#cupcake-list').append(a.join(''));
EDIT:
I'll explain why yours wasn't working. When you were calling $('#cupcake-list').append('<div>'); you thought it would only add the opening div tag, but that is not the case. jQuery won't let you do this is because they want to make sure the html is valid after every function call. If you were to just add the opening div and then do some other stuff, the next closing div (</div>) in the document would close the div you just opened, changing the structure of the document entirely.
In summation:
$('#cupcake-list').append('<div>'); and $('#cupcake-list').append('</div>'); will both append <div></div> to the document. Also, access and update the DOM as if it costs you a million dollars because it is among the slowest things you can do in javascript.
jQuery has a method called .wrap, and some similar ones (.wrapAll).
If you are having the output that you showed, your code is not reaching the inner for, so you have a logic problem. I think your way of doing this is correct. When i need to build some structure on the fly i usually do the same thing.
JQuery append adds DOM nodes, not HTML. So you can accomplish your task like this:
for(var i=0; i<num_cols; i++)
{
col_count++;
num_in_col = rowsInCol(total,num_perCol,col_count);
start = i*num_perCol;
end = start + num_in_col;
for(var d=start; d<end; d++)
{
$('#cupcake-list').append($('<div></div>').append('<p>'+cupcakeData[d].name+'</p>'));
}
}
First, $('<div></div>') creates a new empty div element not yet attached to the page (you can also do $('<div>') as a shorthand if you want). Then .append('<p>...</p>') adds a p element inside the div. Finally, $('#cupcake-list').append(...) adds the whole div to the end of #cupcake-list.
I'm trying to change the name of a link, however, I have some restrictions. The link is placed in code that looks like this:
<li class='time'>
Review Time
<img alt="Styled" src="blah" />
</li>
Basically, I have a class name to work with. I'm not allowed to edit anything in these lines, and I only have a header/footer to write Javascript / CSS in. I'm trying to get Review Time to show up as Time Review, for example.
I know that I can hide it by using .time{ display: hide} in CSS, but I can't figure out a way to replace the text. The text is also a link, as shown. I've tried a variety of replace functions and such in JS, but I'm either doing it wrong, or it doesn't work.
Any help would be appreciated.
You could get the child elements of the li that has the class name you are looking for, and then change the innerHTML of the anchor tags that you find.
For example:
var elements = document.getElementsByClassName("time")[0].getElementsByTagName("a");
for(var i = 0, j = elements.length; i<j; i++){
elements[i].innerHTML = "Time Review";
}
Of course, this assumes that there is one element named "time" on the page. You would also need to be careful about checking for nulls.
Split the words on space, reverse the order, put back together.
var j = $('li.time > a');
var t = j.text();
var a = t.split(' ');
var r = a.reverse();
j.text(r.join(' '));
This could have some nasty consequences in a multilingual situation.
Old school JavaScript:
function replaceLinkText(className, newContents) {
var items = document.getElementsByTagName('LI');
for (var i=0; i<items.length; i++) {
if (items[i].className == className) {
var a = items[i].getElementsByTagName('A');
if (a[0]) a[0].innerHTML = newContents;
}
}
}
replaceLinkText("time", "Review Time");
Note that modern browsers support getElementsByClassName(), which could simplify things a bit.
You can traverse the DOM and modify the Text with the following JavaScript:
var li = document.getElementsByClassName('time');
for (var i = 0; i < li.length; i++) {
li[i].getElementsByTagName('a')[0].innerText = 'new text';
}
Demo: http://jsfiddle.net/KFA58/