assign id for table header in javascript - javascript

Please let me know how to assign id for table header (th) with class="tableHeader" and table id="requestview_table" using javascript(after html table is constructed). Currently, the table headers don't have any id.
Please let me know how to insert id (any number) for with class tableHeader.

$("#requestview_table").find("th.tableHeader").each(function(index) { $(this).attr('id','header' + index); });

m0sa's answer is cleaner (yeay! jQuery) but if you want a JavaScript only solution then this is my stab at it:
Firstly you need a method to get items based on class name (which is something I modified from here: http://www.tek-tips.com/viewthread.cfm?qid=1143850&page=1).
function getElementsByClassName(strClassName, obj) {
var arrClassElements = [];
if (obj) {
if (obj['className'] && obj.className.indexOf(strClassName) != -1) {
arrClassElements.push(obj);
}
for (var i = 0; i < obj.childNodes.length; i++) {
arrClassElements = arrClassElements.concat(getElementsByClassName(strClassName, obj.childNodes[i]));
}
}
return arrClassElements;
}
Then you use this to iterate through the elements it picked up, using setAttribute to add an ID to the element.
var headers = getElementsByClassName('tableHeader', document.getElementById('requestview_table'));
for(var i=0;i<headers.length;i++){
headers[i].setAttribute('id', 'header' + i)
alert(headers[i].id);
}
This is it working here: http://jsfiddle.net/jonathon/W6JyE/
Again, I recommend you use jQuery if you can. It's much better and cleaner for doing the type of operations you're looking to do. This is just one of many alternative solutions.

Related

Why can't use document.getElementById to replace $ in JavaScript?

I'm a newbie in JavaScript, I use a piece of code to convert JSON to HTML table.
And here is the JavaScript code:
function buildHtmlTable(myList,printSource,tablename) {
var columns = addAllColumnHeaders(myList);
var title = document.getElementsByTagName("caption");
title.innerHTML="<h>"+printSource+"</h>";
for (var i = 0 ; i < myList.length ; i++) {
var row$ = $('<tr/>');
for (var colIndex = 0 ; colIndex < columns.length ; colIndex++) {
var cellValue = myList[i][columns[colIndex]];
if (cellValue == null) { cellValue = ""; }
row$.append($('<td/>').html(cellValue));
}
$("#excelDataTable").append(row$);
}
}
// Adds a header row to the table and returns the set of columns.
// Need to do union of keys from all records as some records may not contain
// all records
function addAllColumnHeaders(myList) {
var columnSet = [];
var headerTr$ = $('<tr/>');
for (var i = 0 ; i < myList.length ; i++) {
var rowHash = myList[i];
for (var key in rowHash) {
if ($.inArray(key, columnSet) == -1){
columnSet.push(key);
headerTr$.append($('<th/>').html(key));
}
}
}
$("#excelDataTable").append(headerTr$);
return columnSet;
}
Here is my HTML code:
<body onload="buildHtmlTable(data_epgd, epgd);">
<table id="excelDataTable" border="1">
<caption>sn</caption>
</table>
</body>
As you can see, there is a usage of $("#excelDataTable"). I thought it's just like document.getElementById function to find an element in HTML.So I use document.getElementById to replace it. But when I did this, the code didn't work any more.So can somebody explain what is the difference between document.getElementById(excelDataTable) and $("#excelDataTable")? And why I can't use document.getElementById(excelDataTable) as alternative?
Using the $() is actually more than just a selector, it also wraps it in a jQuery object. Later in your script your using jQuery functions like .append, and those don't work on vanilla objects. What you can do is select it regularly and when you need jQuery functions you wrap ($()) it again.
Furthermore a selector should be a string ('element') and not a variable (element), like Fred mentioned.
The line below will return a jQuery object
$("#excelDataTable")
Meanwhile using
document.getElementById(excelDataTable)
will return you a DOMElement object, which obviously doesn't have jQuery methods.
jQuery accepts also a DOM element to be passed to the constructor. Thus eventually you could do so
$(document.getElementById(excelDataTable))
$() is a shorthand for jQuery(). it is actually a function which returns a collection of jquery compatible objects so that jquery functions can be used on these elements like append(),empty() etc.$() is commonly used as a selector function in Jquery but it is more than a selector...
we can pass it a selector to get a collection of matching elements wrapped into collection of jquery objects from the DOM ..like $('.btnClass'),$('#id'),$('table').
we can pass it a string of HTML to turn into a DOM element which you can then use it into the document.
3.we can pass it a DOM element or elements that you want to wrap with the jQuery object.
For more details refer documentation documentation

jQuery get items with attribute like

Lets say I've got
<div color-opacity="0.8" color-whatever="something" color-whateverbadinga="something">content</div>
What I want to do is to select every item that has attribute that begins with color- (attribute name, not attribute value)
so <div color-dsjdjkdskjsd="something">content</div> will match too.
Is it possible without iterating throught every item and checking every attribute?
jQuery selectors doesn't work with filtering the attribute names, you should read the attribute's name yourself, here is how you can filter the elements using .filter() method and attributes property. However, I don't recommend it as it is very inefficient and generally a bad practice. Adding a class name to the elements that have such attributes and using class selector makes more sense:
$('div').filter(function() {
var a = this.attributes;
for (var i = 0; i < a.length; i++) {
if (a[i].nodeName.indexOf('color') === 0)
return true;
}
return false;
});
I do not know of a way to get what you want directly from JQuery.
The easiest solution to the root problem is to add a class ("hasColor") on all elements when you add the color attribute. This is of course assuming that you are generating the elements.
I dont recommend creating your own attributes. However, You could do this with data attribute:
<div data-coloropacity="0.8" data-colorwhatever="something"
data-colorwhateverbadinga="something">content</div>
Then create your own jquery data2 selector:
jQuery.expr.pseudos.data2= $.expr.createPseudo(function(arg) {
var regexp = new RegExp(arg);
return function(elem) {
for(var i = 0; i < elem.attributes.length; i++) {
var attr = elem.attributes[i];
if(regexp.test(attr.name)) {
return true;
}
}
return false;
};
});
Then you can use it like this:
console.log($(":data2('color')").html());
DEMO

Improving jquery select speed

I have this code which manipulates the asp.net treeview html code.
This code gets run frequently, so its important that it runs as fast as possible.
I want to learn more about jquery selectors and improving its speed. So far I was able to get this code myself.
Some things I am not sure about is if you want the third child element, do I use [2] or .eq(2) or :nth-child(2)? Also what if I use $ to select something that was from an array of selected stuff, is this necessary, or is it already selected?
Does anyone know any tricks or hints I can do to improve my jquery select efficiency?
Thanks.
function showResultsOnTreeview(treeviewID, filenameDictionary) {
var sectionNodes = $("#" + treeviewID + " > table");
var numOfSections = sectionNodes.length;
var i, j, sectionName, divContainer, itemNodes, numOfItems, itemName, itemTag, itemPath;
for (i = 0; i < numOfSections; i += 1) {
sectionName = $(sectionNodes[i]).text();
divContainer = $(sectionNodes[i]).next('div');
divContainer.hide();
itemNodes = $('table', divContainer);
numOfItems = itemNodes.length;
for (j = 0; j < numOfItems; j += 1) {
itemTag = $('td', $(itemNodes[j])).eq(2);
itemTag.removeClass('treeViewResult');
itemName = getNameFromItem($(itemNodes[j]).text());
itemPath = filenameDictionary[itemName];
if (itemPath != null) {
if (itemPath.indexOf(sectionName + "/" + itemName) != -1) {
itemTag.addClass('treeViewResult');
divContainer.show();
}
}
}
}
}
There is some optimisation you can do. The first on is for sure to use .eq() instead of []. Like here, you hare creating a jQuery object :
var sectionNodes = $("#" + treeviewID + " > table");
But then later, you do this :
sectionName = $(sectionNodes[i]).text();
divContainer = $(sectionNodes[i]).next('div');
Here you are creating 2 more, unneeded, jquery object, you could just do this :
sectionName = sectionNodes.eq(i).text();
divContainer = sectionName.next('div');
Then, i do't know if you have a different way to do it, but if you can remove the "loop in a loop", that would be great.
After, instead of using context selectore ($('selector', $element)), use find. Context use find so it will reduce the number of function calls. Take this line for example :
$('td', $(itemNodes[j])).eq(2)
You are creating 2 jQuery object when you can do the same without an extra object and could use .find():
itemTag = itemNodes.eq(j).find('td').eq(2);
Basicly, use .find() instead of context and avoid creating unneeded jQuery object. Hope that will help.

showing selected names in a <div> by using a javascript array

I have a div which displays name of the people who are online, I have the following members in
the div
<div id="members">
<span>Amlan Karmakar</span>
<span>Atin Roy</span>
<span>Arpan Burman</span>
<span>Ramanuj Mukherjee</span>
</div>
I have another javascript array friends[], which has 'Amlan Karmakar' and 'Ramanuj Mukherjee' has friends, I want to display those members who are in the friends[] array, I am inserting the name of the friends by friends.push("Amlan Karmakar"). The names in div are auto generated by cometd chat, I have written the names in the div for simplicity. I hope there is a solution to this problem. My previous question didn't solve my problem.
You could try something like the below, i.e. split the HTML of the div containing the members, loop through them and check if they are in the friendsArray. Note that this is a rough implementation, and that it assumes a reasonably new browser as it uses Ecmascript 5 features. The concept can applied using old-fashioned for loops too.
var all = document.getElementById('members').getElementsByTagName('span');
var friendsOnly = '';
for(var i=0; i<all.length; i++){
if(friendsArray.some(function(friend){
return friend == all[i].innerHTML;
})){
friendsOnly += '<span>' + all[i].innerHTML + '</span>';
}
});
all.innerHTML(friendsOnly);
By the way, I'm assuming the friendsArray may contain people who are not already in the div. If that is not the case, then I'm not sure what the question is about.
So you want to put the data from the friends[] array into the <div id="members">
I want only those names to show in the which are there in the friends[] array
If you only want to display the names which are in the friends array, as you suggested in your comment, I suppose this will do the trick:
var target = document.getElementById("members");
// Remove this line if you want to keep the current names in the members div.
target.innerHTML = ""; // Clean before inserting friends
for (var i = 0; i <= friends.length; i++) {
target.innerHTML += friends[i] + "<br />"; // Add friend + break
}
Try this to get only the friends out of the list of members:
var friendMembers = document.getElementById('members').split(/<br\s*[\/]?>/gi)
.filter(function(member) { return (friends.indexOf(member) > -1) } );
You should try knockout.js, this framework will help you handle this case.

Using .attr() with .get() Issues

I am trying to store an array of objects in an array by going through each paragraph element in a div container with the .get() method. I try to access the attribute with .attr() but it doesn't seem to work. How would I modify this code in order to be able to access the 'id' attribute of each message?
var messages = $("#message_container p").get();
var idstest = [];
for (int i = 0; i < messages.length; i++){
idstest.push(messages[i].attr("id"));
}
I think it has to do with some fundamental incompatibility with .get() and .attr(). When I 'alert' the objects provided by .get() I get [object HTML---]. I'm assuming that is not the form necessary in order to use .attr?
get will give you the DOM element. These are NOT jquery objects so you can't use attr on them. There's no reason to use get at all here.
var messages = $("#message_container p");
var idstest = [];
messages.each(function(){
idstest.push($(this).attr("id"));
});
http://jsfiddle.net/ujdeH/
EDIT: You also can't use int.
If for some reason you did want to use get to get the raw DOM elements, you would then just use .id:
http://jsfiddle.net/ujdeH/1/
var messages = $("#message_container p").get();
var idstest = [];
for (var i = 0; i < messages.length; i++) {
idstest.push(messages[i].id);
}
try instead:
var idstest = [];
$("#message_container p").each(function(i){
idstest.push($(this).attr("id"));
});
Just wanted to add the $.map shortcut: http://jsfiddle.net/UuWq3/.
var idstest = $.map(messages, function(elem) {
return $(elem).attr("id");
});
$.map returns a new array based on the original array (or jQuery object). The array returned is constructed with the function you pass (in this case, messages is transformed by the function such that each element is replaced with it's ID).
You should wrap the object in jQuery container:
$(messages[i]).attr("id")
Actually no need for jQuery here, this pure JavaScript will work just fine on all browsers:
var idstest = [];
var container = document.getElementById("message_container");
if (container) {
var messages = container.getElementsByTagName("p");
for (var i = 0; i < messages.length; i++) {
idstest.push(messages[i].id);
}
}
jQuery is all good and powerful, but if you can achieve the same task with short/easy enough pure JS then why not?
This said, if all your existing code is jQuery then you might be better off sticking with it (using the code from other correct answers here) just for sake of consistency and readability.

Categories