Find last td without using Jquery - javascript

I need to find the Last td of every row in a HTML table, and remove a css from that td. Can I do it without using Jquery.
How?

You can use css3 last-child property for this. Write like this:
tr td:last-child{
color:red;
}
But it's not work in IE8 & below.

Use CSS
td:last-child: {
//your style here
}
Docs on CSS3 selectors here
or using traverse the DOM using JavaScript :
var mytable = document.getElementById('tableid');
var myrows = mytable.getElementsByTagName("tr");
var lastrow = myrows[myrows.length -1];
var mycells = lastrow.getElementsByTagName("td");
var lastcell = mycells[mycells.length -1];
// set CSS property here
lastcell.style.color = "red";
lastcell is your last td
Working example using JavaScript

Have you tried using CSS3 selectors? E.g
tr td:last-child
{
YOUR CODE HERE
}
You could also look at using classes to show which td's are the last. But of course this isnt dynamic.
I believe there is also a normal javascript answer but im not very good at that :P
http://www.w3.org/TR/selectors/
http://www.quirksmode.org/css/firstchild.html

Assuming that you are not looking for css type solution
rows=document.getElementsByTagName('tr')
for (var i=0; i<rows.length; i++){
columns=rows[i].getElementsByTagName('td');
mytd = columns[columns.length-1];
classname = mytd.className;
arr = classname.split(' ');
mytd.className = arr.filter(function(e){return e!=CLASSTOREMOVE}).join(' ');
}

For a pure JavaScript solution:
function removeCssClass(tableId, cssClass) {
var trs = null;
var tr = null;
var tds = null;
var td = null;
var classes = [];
var i = 0;
trs = document.getElementById(tableId).getElementsByTagName('tr');
tds = trs[trs.length - 1].getElementsByTagName('td');
td = tds[tds.length - 1];
classes = td.className.split(' ');
for (i = 0; i < classes.length; i += 1) {
if (classes[i] === cssClass) {
classes.pop(i);
}
}
td.className = classes.join(' ');
return false;
}​
Working fiddle.

What are you trying to do with the last TD? If you are wanting to have a border in-between each td why don't you use border-left and then you can use first-child to remove it. There might be a better approach that is more compatible with browsers.

Related

Creating a table of divs

I want to create a 16*16 table in html that holds div container in each cell. I'm not sure to what degree I'm allowed to mix jquery and pure javascript but what I have is
$( document ).ready(function() {
var table = Doucument.getElementById('table');
for (var i = 0; i <16; i++) {
var row = table.insertRow(i);
for(var j = 0; j < 16; j++){
row.insertCell(i);
}
};
});
This is adding a row to my table and then adding 16 cells. However I'm not sure how to add the div element to each cell. Perhaps theres a simpler way to do this with jquery? I'm not so proficient in jquery
Change "Document" to "document", remove the loop indexes (i, j) from the insertRow() and insertCell methods, and capture the newly inserted cell so that you can populate it. I've set each div's ID to be a combination of row and cell number in the example below.
I should also point out that there are better ways to do this. Tables should only be used for displaying data that requires tables. Also, this kind of thing would ideally be done on the server side unless there's a reason for you to do it in JavaScript.
That being said, here is a working example using JavaScript:
HTML:
<table id="myTable"></table>
JavaScript:
$(document).ready(function () {
var table = document.getElementById('myTable');
for (var i = 0; i < 16; i++) {
var row = table.insertRow();
for (var j = 0; j < 16; j++) {
var cell = row.insertCell();
var id = 'r' + i + 'c' + j;
cell.innerHTML = '<div id="' + id + '">' + id + '</div>';
}
};
});
CSS (after reading your comment about controlling size):
#myTable TD DIV {
height: 30px;
width: 30px;
}
Demo: http://jsfiddle.net/BenjaminRay/ugm613zg/
Do you have a specific reason to create a "table" - it is frowned upon by UX and CSS experts. It is considered a better approach to consider creating a table-like layout using Div/Spans and CSS. There are frameworks available that can provide you this layout style out of the box.
One of the most popular ones is Bootstrap's Grid - and here are some layout examples - http://getbootstrap.com/examples/grid/. The benefit of using this approach instead of tables is that your layout will adjust better to screen size changes like say viewing on a mobile device (called responsive layout).
In the interest of full disclosure Bootstrap supports 12 columns out of the box - but modifications are available for 16 and 24 columns - How to use bootstrap with 16 or 24 columns.
This is a longer route but a better solution than tables overall.
And using jQuery, you could do the following.
function addElems(ele, howMany, append) {
var $items = $();
for (var i = 0; i < howMany; i++) {
var $ele = $("<" + ele + "/>");
typeof append !== "undefined" && $ele.append(append);
$items = $items.add($ele);
}
return $items;
}
var $table = $("#myTable").append("<tbody></tbody>");
var $trs = addElems('tr', 16);
$table.append($trs);
$table.find("tbody > tr").each(function() {
var $tds = addElems('td', 16, "<div>My Div</div>");
$(this).append($tds);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable"></table>

How to get list of html content of all the elements having a certain class?

Here is what I am trying (jquery):
var lis = $('.options.high');
for (var i = 0; i<lis.length; i++){
console.log(lis[i].html());
}
but this is not allowed I believe. Please suggest some alternative.
Update: Resolved. It was quite silly question. Please ignore.
.html() is method for jQuery objects. Wrap lis[i] like this
$(lis[i]).html()
JS :
var lis = $('.options.high');
for (var i = 0; i<lis.length; i++){
console.log($(lis[i]).html());
}
Demo
A preferable way is to use .each().
var lis = $('.options.high');
lis.each(function(index){
console.log($(this).html()); //OR $(lis[index]).html()
});
Demo
You can use .each() in jquery for this
$('options.high').each(function () {
alert($(this).html());
});
Note: Remove the . before options, if it is not the class name.

How to add 'style' in dynamically created table?

I have created table through DOM, now want to add style to that table but its not working.
code :
<script>
var nrCols=4;
var maxRows=10;
var nrRows=maxRows+1;
while(nrRows>maxRows)
{
nrRows=Number(prompt('How many rows? Maximum '+maxRows+' allowed.',''));
}
var root=document.getElementById('mydiv');
var tab=document.createElement('table');
var style=document.createElement('style');
style.setAttribute('background-color','red');
tab.appendChild(style);
tab.setAttribute('Border','1');
tab.className="mytable";
var tbo=document.createElement('tbody');
var tr1= document.createElement('tr');
var th1= document.createElement('th');
th1.appendChild(document.createTextNode('No.'));
var th2= document.createElement('th');
th2.appendChild(document.createTextNode('Surah.'));
tr1.appendChild(th1);
tr1.appendChild(th2);
tbo.appendChild(tr1);
var row, cell;
for(var i=0;i<nrRows;i++){
row=document.createElement('tr');
for(var j=0;j<nrCols;j++){
cell=document.createElement('td');
cell.appendChild(document.createTextNode('Allah'+' '+j))
row.appendChild(cell);
}
tbo.appendChild(row);
}
tab.appendChild(tbo);
root.appendChild(tab);
</script>
i have used style.setAttribute('background-color','red'); but no difference. how to fix it ?
Replace
var style=document.createElement('style');
style.setAttribute('background-color','red');
tab.appendChild(style);
with :
tab.style.backgroundColor = 'red';
All elements have a style attribute to which you can add the appropriate style values.
try to change the name of var style it might be causing the css style confusion, try this way
var menu = document.createElement("menu");
menu.style.backgroundColor = "#555";
Well, style is a HTML tag, when you create a element with that name it expects CSS info inside it. You maybe want this:
If you want to target the <th> element you should use this instead:
var th1 = document.createElement('th');
th1.style.backgroundColor = 'red';
Demo
it should be something like this
document.body.style.backgroundColor="#333333";
in your case
tab.style.backgroundColor="#333333"
Below code will create style tag
var css = 'table { background: red; }'
var style = document.createElement('style');
style.styleSheet.cssText = css;

Variable in getElementById

I need to go over all radio buttons of the form and paint the td that contain the checked ones.
Cant pass the variable of the TD id, in the loop (aca):
function veamos() {
var allElems = document.getElementsByTagName('input');
for (i = 0; i < allElems.length; i++) {
if (allElems[i].type === 'radio' && allElems[i].checked) {
var aca="pinta"+i;
document.getElementById(aca).style.backgroundcolor = '#9e0000';
} else {
//document.getElementById(estetd).style.backgroundColor = '#ffffff';
}
}
}
document.getElementById('pinta1').style.backgroundColor = '#9e0000', seems to work... cant build the variable to loop all form
Any ideas?
Thanks in advanced.
If i understand your question right I think you have 2 options.
function veamos () {
var allElems = document.getElementsByTagName('input');
for (var i = 0, len = allElems.length; i<len; i++) { /* do not use .length in the loop condition, that will have very bad performance on element arrays returned by getElementsByTagName. */
var elem = allElems[i];
if (elem.type==='radio') {
/* Option 1: This depends on the HTML structure, where is the TD in relation to the input? */
var td = elem.parentNode; /* if it is 2 levels up then use elem.parentNode.parentNode */
/* Option 2: This depends on having an ID on the <input> and <td> that are similar, like this <input id="r1"> <td id="r1TD"> */
var td = document.getElementById(elem.id + 'TD');
td.style.backgroundColor = elem.checked ? '#9e0000' : '#ffffff';
/* I would recommend using a class name (CSS) instead of using a hard coded color! */
}
}
}
You have a typo. Javascript is case sensitive. Change
document.getElementById(aca).style.backgroundcolor = '#9e0000';
to
document.getElementById(aca).style.backgroundColor = '#9e0000';
...
UPDATE See a working example
Instead
document.getElementById(aca).style.backgroundcolor = '#9e0000';
should be
allElems[i].style.backgroundcolor = '#9e0000';

jQuery/javascript replace tag type

Is there an easy way to loop through all td tags and change them to th? (etc).
My current approach would be to wrap them with the th and then remove the td, but then I lose other properties etc.
jQuery.replaceTagName
The following is a jQuery plugin to replace the tag name of DOM elements.
Source
(function($) {
$.fn.replaceTagName = function(replaceWith) {
var tags = [],
i = this.length;
while (i--) {
var newElement = document.createElement(replaceWith),
thisi = this[i],
thisia = thisi.attributes;
for (var a = thisia.length - 1; a >= 0; a--) {
var attrib = thisia[a];
newElement.setAttribute(attrib.name, attrib.value);
};
newElement.innerHTML = thisi.innerHTML;
$(thisi).after(newElement).remove();
tags[i] = newElement;
}
return $(tags);
};
})(window.jQuery);
Minified Source
(function(e){e.fn.replaceTagName=function(t){var n=[],r=this.length;while(r--){var i=document.createElement(t),s=this[r],o=s.attributes;for(var u=o.length-1;u>=0;u--){var a=o[u];i.setAttribute(a.name,a.value)}i.innerHTML=s.innerHTML;e(s).after(i).remove();n[r]=i}return e(n)}})(window.jQuery);
Usage
Include the above minified source in your javascript after jQuery.
Then you can use the plugin like this:
$('div').replaceTagName('span'); // replace all divs with spans
Or in your case this:
$('td').replaceTagName('th');
jQuery selectors work as expected
$('.replace_us').replaceTagName('span'); // replace all elements with "replace_us" class with spans
$('#replace_me').replaceTagName('div'); // replace the element with the id "replace_me"
More resources
jsFiddle with Qunit tests
Completely untested, but giving this a whirl:
$("td").each(function(index) {
var thisTD = this;
var newElement = $("<th></th>");
$.each(this.attributes, function(index) {
$(newElement).attr(thisTD.attributes[index].name, thisTD.attributes[index].value);
});
$(this).after(newElement).remove();
});
I'm looking and looking at it, and I can't think of a reason why it wouldn't work!
1) loop through each td element
2) create a new th element
3) for each of those td's, loop over each of its attributes
4) add that attribute and value to the new th element
5) once all attributes are in place, add the element to the DOM right after the td, and remove the td
Edit: works fine: http://jsbin.com/uqofu3/edit
$("td").each(function() {
var tmp = $('<div/>').append($(this).clone(true)).html().replace(/td/i,'th');
$(this).after(tmp).remove();
});
or pure DOM
function replaceElm(oldTagName, newTagName, targetElm) {
var target = targetElm || window.document;
var allFound = target.getElementsByTagName(oldTagName);
for (var i=0; i<allFound.length; i++) {
var tmp = document.createElement(newTagName);
for (var k=0; k<allFound[i].attributes.length; k++) {
var name = allFound[i].attributes[k].name;
var val = allFound[i].attributes[k].value;
tmp.setAttribute(name,val);
}
tmp.innerHTML = allFound[i].innerHTML;
allFound[i].parentNode.insertBefore(tmp, allFound[i]);
allFound[i].parentNode.removeChild(allFound[i]);
}
}
replaceElm('td','th',document.getElementsByTagName('table')[0]);
DOM is always faster: http://jsperf.com/replace-tag-names
This might work, but I haven't tested it extensively:
var tds = document.getElementsByTagName("td");
while(tds[0]){
var t = document.createElement("th");
var a = tds[0].attributes;
for(var i=0;i<a.length;i++) t.setAttribute(a[i].nodeName,a[i].nodeValue);
t.innerHTML = tds[0].innerHTML;
tds[0].parentNode.insertBefore(t,tds[0]);
tds[0].parentNode.removeChild(tds[0]);
}
I hope it helps in some way.
Slight addition to #GlenCrawford answer, to also preserve inner text with the line:
newElement.text($(value).text());
All together now:
$("td").each(function(index) {
var thisTD = this;
var newElement = $("<th></th>");
newElement.text($(value).text());
$.each(this.attributes, function(index) {
$(newElement).attr(thisTD.attributes[index].name, thisTD.attributes[index].value);
});
$(this).after(newElement).remove();
});
Well this question is pretty old but this could help anyway: the only jQuery plugin that actually works as expected (you can't reuse the returned object in the other one, to add attributes for example):
jQuery.fn.extend({
replaceTagName: function(replaceWith) {
var tags=[];
this.each(function(i,oldTag) {
var $oldTag=$(oldTag);
var $newTag=$($("<div />").append($oldTag.clone(true)).html().replace(new RegExp("^<"+$oldTag.prop("tagName"),"i"),"<"+replaceWith));
$oldTag.after($newTag).remove();
tags.push($newTag.get(0));
});
return $(tags);
}
});
Besides the basic $("td").replaceTagName("th"); you can also chain calls like $("td").replaceTagName("th").attr("title","test");
Minified version:
jQuery.fn.extend({replaceTagName:function(a){var b=[];this.each(function(d,c){var e=$(c);var f=$($("<div />").append(e.clone(true)).html().replace(new RegExp("^<"+e.prop("tagName"),"i"),"<"+a));e.after(f).remove();b.push(f.get(0))});return $(b)}});
This is a bit cleaner than #GlenCrawford's answer and additionally copies the children of the replaced element.
$('td').each(function(){
var newElem = $('<th></th>', {html: $(this).html()});
$.each(this.attributes, function() {
newElem.attr(this.name, this.value);
});
$(this).replaceWith(newElem);
});

Categories

Resources