Having jQuery string comparison issues - javascript

I've got a fiddle going here to show what I'm trying to do.
I have a table that is generated dynamically, so the columns could appear in whatever order the user chooses. So, I'm trying to get the index of two specific headers so that I can add a CSS class to those two columns for use later.

You should use .filter() here instead (and whenever you need to restrict the element set), since your .each() return is getting thrown away, like this:
//Loop thru the headers and get the Supp elem
var suppCol = $("#my_table th").filter(function() {
return $(this).html() == "Supp";
});
//Loop thru the headers and get the Report elem
var reportCol = $("#my_table th").filter(function() {
return $(this).html() == "Report";
});
You can test the updated/working fiddle here. The alternative using .each() would look like tis:
var suppCol, reportCol;
$("#my_table th").each(function() {
var $this = $(this), html = $this.html();
if(html == "Supp") suppCol = $this;
if(html == "Report") reportCol= $this;
});
You can test that version here.

Related

how to use $(this) with foreach in javascript using jquery

I am working on a personal project in Javascript to allow people to create a table of "dream plays" in Scrabble. Here is the link: http://psyadam.neoclaw.net/tables8.html
I am currently trying to allow the user to edit a dream play.
Here is my code:
function editRow(e)
{
var eventEl = e.srcElement || e.target,
parent = eventEl.parentNode
parent = parent.parentNode
var test = $(parent.cells[0]).text()
$('tr').each(function(){
$(this).children("td:contains(test)").each(
function()
{
pageEnd.innerHTML += "success"
$(this).addClass('selected')
}
)
})
pageEnd.innerHTML += test
//pageEnd.innerHTML += $(parent.cells[3]).text()
insertRow()
}
// insertRow assumes that the correct row in the table has the "selected" class added to it
function insertRow()
{
var Row = $('<tr>').append(
$('<td>').append('<input id="input1">'),
$('<td>').append('<select id="input2"><option value=""></option><option value="Yes">Yes</option><option value="No">No</option></select>'),
$('<td>').append('<select id="input3"><option value=""></option><option value="Natural">Natural</option><option value="1 Blank Used">1 Blank Used</option><option value="2 Blanks Used">2 Blanks Used</option></select>'),
$('<td>').append('<select id="input4"><option value=""></option><option value="vs Computer">vs Computer</option><option value="Online Game">Online Game</option><option value="Friendly Game">Friendly Game</option><option value="Club Game">Club Game</option><option value="Tournament Game">Tournament Game</option></select>'),
$('<td>').append('<input id="input5">')
)
$("#myTable tr.selected").after(Row)
}
Right now I'm just trying to get my code to insert a row into the table. I am trying to do this by using the code $(this).addClass('selected') to tag the row the user selected and then use it in my insert function to insert a row. However, nothing seems to happen. I am using pageEnd.innerHTML += "success" as a debugging tool to see if it is even getting there. Unexpectedly, it prints success twice when it should only print once, as in the test I ran every word was unique.
In any case I can't figure out why it's not working. Any help is appreciated. Thanks, ~Adam
You have two options to achieve this:
The first one as the others are suggesting i.e. by keeping a variable of outer this and then using this:
$('tr').each(function() {
var outerThis = this;
// inside another loop (not sure about children method, just an example)
$(outerThis).children("td:contains(test)").each(function() {
// do something with outerThis to operate on further
});
});
Another option to use Javascript's bind() method:
$('tr').each(function(i, trElement) {
// this == trElement
// inside another loop
$(outerThis).children("td:contains(test)").each(function(index, tdElement) {
$(this) // will be now tr element
$(tdElement) // will be td element
}.bind(this));
});
Try this:
function editRow(e) {
var eventEl = e.srcElement || e.target,
parent = eventEl.parentNode
parent = parent.parentNode
var test = $(parent.cells[0]).text()
$('tr').each(function(){
var outerThis = this;
outerThis.children("td:contains(test)").each(
function()
{
pageEnd.innerHTML += "success";
$(this).children().css('text-align', 'center');
}
)
})
pageEnd.innerHTML += test
//pageEnd.innerHTML += $(parent.cells[3]).text()
insertRow()
}
I set the outer this to a variable which you can use. Also textAlign is not a jQuery function. You need to use .css() and then specify text-align in that.

How to iterate over htmlCollection

I'm having some difficulty with this. In Backbone, I have a function like this:
functionOne: function(){
$('#myTExtbox-' + budgetLine.attr('id')).on('change keyup paste', function(){
that.mySecondFunction(this);
});
}
In this case, the this is a textbox, which is in a table, inside a div. Then:
mySecondFunction: function(tb){
var tbody = tb.parentElement.parentElement.parentElement.parentElement.parentElement;
//gets main parent, which is a tbody, inside a table, inside a div
}
I then want to iterate over tbody, to go through each row and find a textbox in a specific cell. The problem is that this code:
$.each(tbody, function(index, item){
cost = item;
var t= index;
});
Doesn't seem to allow me to get to any of the items. In this example, if I try to do something like:
item.getElementById('test');
I get an error:
TypeError: Object #<HTMLCollection> has no method 'getElementById'
Why can't I iterate over this object and access objects within?
Thanks
UPDATE
Here's a fiddle: http://jsfiddle.net/HX8RL/14/
Essentially, what should happen is this: When a text box changes, I want to iterate over all the rows in the tb's parent table and sum all the Tb values. Keeping in mind, all the tb's in the same cell position, as there could be other tb's in other places that I dont want to include.
There wont be any collection of TBody
try using children() instead
$.each(tbody.children('tr'), function(index, item){
cost = item;
var t= index;
});
Demo Fiddle
Iterate over all input elements directly to get values.
var tbody = tb.parentElement.parentElement.parentElement;
alert(tbody.id);
var input = $('#tbody').find('input');
alert(input);
console.log(input);
for (var i = 0; i < input.length; i++) {
alert(input[i].value);
alert(i);
}
See fiddle-http://jsfiddle.net/HX8RL/18/
I think there are a few things going wrong here. You know you can only have one ID per page? So you have to do document.getElementByid('test') instead.
Since you are also using jQuery you can use the find function, item.find('#test'). But I think this wouldn't solve you problem. Not sure what you want to achieve, maybe I can help you if you explain a bit more in detail what your problem is.
Also
tb.parentElement.parentElement.parentElement.parentElement.parentElement;
can be written as (in jQuery)
$(tb).parents('tbody');
I've setup a fiddle, maybe it can help you.
Code used in fiddle:
var myFuncs = (function() {
function funcA() {
$('input').on('keyup', function() {
funcB(this);
});
}
function funcB(myInput) {
var $table = $(myInput).parents('table');
$table.find('tr > td > input').each(function() {
var $input = $(this);
if($(myInput).attr('id') != $input.attr('id'))
$input.val("I'm called from another input");
});
}
return {
funcA : funcA
}
})();
myFuncs.funcA();

jQuery TableSorter - textExtraction based on external variable

I have a TableSorted table, and in each TD element are five SPAN elements. Four are always hidden, but upon clicking a div outside the table, certain spans are hidden dependent on which div is clicked.
I have the table sorting fine, but what I need is for the textExtraction to grab a different SPAN, depending on the value of the div which has been selected.
I've tried the following to no avail:
textExtraction:function(node){
var filter=$("div.career a.sel").text();
if(filter=="a"){var theindex=0;}
if(filter=="b"){var theindex=1;}
if(filter=="c"){var theindex=2;}
if(filter=="d"){var theindex=3;}
if(filter=="e"){var theindex=4;}
return $(node).find("span").eq(theindex).text();
}
What is the best way to achieve this?
The textExtraction function is only called when tablesorter is initialized or updated. Try triggering an update after the selection has changed.
var indexes = 'abcde'.split(''),
// Is this a select box?
$sel = $("div.career a.sel").on('change', function(){
$('table').trigger('update');
});
$('table').tablesorter({
textExtraction: function(node){
// if this is a select, get val(), not text()
var filter = $sel.val(),
theindex = $.inArray( filter, indexes );
return $(node).find("span").eq(theindex).text();
}
});
Update: for a link, try this:
var indexes = 'abcde'.split(''),
$careers = $("div.career a").on('click',function(){
var searcher = $(this).attr("rel");
$("div.career a").removeClass("sel");
$(this).addClass("sel");
$("td.stat span").hide();
$("td.stat span.career_" + searcher).show();
});
$('table').tablesorter({
textExtraction: function(node){
// find selected
var filter = $careers.filter('.sel').text(),
theindex = $.inArray( filter, indexes );
return $(node).find("span").eq(theindex).text();
}
});
Note: Don't use live() in jQuery version 1.9+, it was removed.

Java Script : get the string equivalent of a elements ID

my naming convention
id=xxxxx //actual field shown in the screen
id=xxxxxHDN // hidden field containing the enable/disabled status of the component from the set from the controller.
Now what I am trying to do is get the satus of xxxxxHDN to be true/false ,
and accordingly set the components status to disabled /enabled .with java script..
var div = document.getElementById("hiddenFields"); // i hava some 30 hidden fields containing the
var j;
for (j=0;j<div.childNodes.length;j++)
if(div.childNodes[j].value){
alert("inside the loop");
var someElementHDN = div.childNodes[j].id; // my aim is to get the ID=xxxxxHDN
var someElementHDNToString = someElementHDN .toString(); // my aim is to get the string value "xxxxxHDN"
var toRemove = 'HDN'; // the part i wanna remove from 'someElementHDNToString' to make it an id for 'xxxxx'
var equivalantComponentIDAsString = someElementToString.replace(toRemove,'');
$('#' + equivalantComponentIDAsString ).attr('disabled', true);
}
}
Invested a lot of time manupulatiing things above , doesent seems to work . I am new to java scrcript , Where am I missing it?
If you have an element with id like 'fooHDN' and want to find another element with id 'foo', then you can do something like:
var otherElement = document.getElementById(someElement.id.replace(/HDN$/,''));
Assuming that you already have someElement and it's a DOM element.
Your posted js code has error: div does not have a "length", do you mean "div.childNodes.length"?
Anyway, since you're using jQuery already, I think it can become easier as below:
Already tested and it works fine.
$("#hiddenFields input[type='hidden'][id$='HDN']").each(
function () {
var elemId = this.id.replace(/HDN$/, '');
$('#' + elemId).attr('disabled', this.value.toLowerCase() == 'false' ? false : true);
}
);

confusion in jquery parents selector with hasClass function

var allChecked = $('.inboxCheckbox:checked');
if(allChecked.length > 0){
var messageIds = new Array();
var parentRow = null;
allChecked.each(
function(){
parentRow = $(this).parents('tr');
if(!(parentRow.hasClass('gradeA'))){
parentRow.addClass('gradeA');
increaseUnreadMessage();
}
parentRow = null;
messageIds.push($(this).val());
}
);
}else{
showInsMessage('<b class="redTxt">Please Select At Least One Message</b>');
}
i have multiple rows with once checkbox in each row... i was trying to add class gradeA to each row if checkbox is checked.... i do not want to call addClass if it already has class gradeA.... when i select multiple rows then it adds class to only one row. does that mean
lets say i have three rows with checkbox in each row and i select each checkbox when i run
$(':checked').each(
$(this).parents('tr')
)does it select all the rows with checked boxes or only the specfic parent row.... my assuption was it only gives the specific parent row..... if it gives specific row then it should work .. but once i add a class to parent row and move to another row then parentRow.hasClass('gradeA') return true... i am confused now if it checks all the row with checkboxes then is there any way to select specific parent row......
Thanks for reading
Would be nice to see the markup, are there more tables nested?
However,
parentRow = $(this).closest('tr');
should be a better choice.
API says that .parents() method search through all ancestors of the elements.
.parent() travels only a single level up the DOM tree.
If your checkbox is a direct child (not a deep descendant) of 'tr' then you can try
parentRow = $(this).parent('tr');
Your code should work. I suspect that the problem is happening because your function increaseUnreadMessage() is throwing an error, which is causing the rest of the each() loop to be skipped.
But, to answer your specific question: yes, you can select all rows (<td>s) that contain checked checkboxes. Using jquery's :has selector, like this:
var allCheckedRows = $('tr:has(.inboxCheckbox:checked)');
from there, of course, you can just use addClass() to apply your classname to all of them:
allCheckedRows.addClass('gradeA');
of course, you've got other things going on in your each() loop, so you probably can't throw out the each() entirely. As I said above, your code works... but something like this might be cleaner, and easier to understand.
var messageIds = new Array();
var allCheckedRows = $('tr:has(.inboxCheckbox:checked)');
allCheckedRows.addClass('gradeA');
allCheckedRows.find('.inboxCheckbox').each( function() {
var cb = $(this);
increaseUnreadMessage();
messageIds.push( cb.val() );
});
if( messageIds.length === 0 ) {
showInsMessage('<b class="redTxt">Please Select At Least One Message</b>');
}
BTW, I think you can do it more jQuerish style :
var messageIds = [];
$('tr.youTrs').toggleClass('gradeA', function () {
var checkbox = $(this).find('.inboxCheckbox');
if (checkbox.is(':checked')){
messageIds.push(checkbox.val());
return true;
}
else{
showInsMessage('<b class="redTxt">Please Select At Least One Message</b>');
return false;
}
});

Categories

Resources