how to check if a checkbox exists - javascript

The check box's exist for each row. the table is created by PHP and I need a way to check if the check box exists. when they are created they are given the ID of checkbox_(an incrementing number).
This is what I have so far, but it does not work on checking if the element exists.
var check = true;
var todelete = "";
var counter = 0;
//check if box exisits and record id and post
while(check)
{
if ($("#Checkbox_"+counter).length > 0)
{
todelete = todelete + $("#Checkbox_"+counter).value;
counter = counter + 1;
}
else
{
check = false;
}
}
I have also tried
if ($("Checkbox_"+counter))
if (document.getElementById("tbody").value == null)
Update:
Even with the # symbol or if i do it by javascripts element ID - when I debug the DOM, it hits the while, then the if, adds the value to todelete, adds 1 to the counter, then it goes back to the while, then hits the if
Then bounces back up to the while without even going into the if or the else???
this I do not understand, then it just bounces up and down between the two lines and crash's the browser?
Update2:
I needed to .tostring() the counter when adding it to the string for an element id. problem solved

You can use
if ($("#Checkbox_"+counter).length > 0)
I'm assuming that 'Checkbox_0' is an ID, so I've added the # symbol. If it's the name of the checkbox, you can use
if ($("input[name='Checkbox_"+counter+"']").length > 0);
[edit]Also, you should check to make sure you do / don't need the capital 'C'.

You can use for "checkbox exists in this case"
if ($("#Checkbox_"+counter).length > 0) {
//checkbox exists
}

if (($("#Checkbox_"+counter).length) > 0) {
...
//Or something more generalized
jQuery.fn.exists = function(){
return jQuery(this).length>0;
}
//then, if you have valid selector
if ($("#Checkbox_"+counter).exists()){
//do something here if our selected element exists
}

// if document.getElementById(name) do not exist
// document.getElementById(name).value generate already an error
if (document.getElementById(name) != null) {
// you code if checkbox exist
}

Related

How does the matching JS code using indexOf work?

I've managed to copy some JS over into my doc, and I've got it working. But I don't entirely understand how its doing it.
It's a search function to match with data in a table and hide any rows that don't match.
But I don't understand the active line of code that actually searches and matches. Would someone explain it?
$('#searchBar').keyup(function() {
searchFunction($(this).val());
});
function searchFunction(value) {
$('#results tr').each(function() {
var found = 'false';
$(this).each(function() {
if ($(this).text().toLowerCase().indexOf(value.toLowerCase()) >= 0) {
found = 'true';
}
});
if (found === 'true') {
$(this).show();
} else {
$(this).hide();
}
})
};
It's this line I can't get my head around:
if ($(this).text().toLowerCase().indexOf(value.toLowerCase()) >= 0) {
found = 'true';
}
I understand how it changes the variable to true, but I don't understand how it matches the data in the Table row with the Value fed in.
It converts the value you sent to the function to lowercase, and then looks at the data in the row. It converts that to lowercase too, and sees if there is a match using indexof, which is covered here: How to use IndexOf in JQuery
Basically, the indexOf() method returns the position of the first occurrence of a specified value in a string. It returns -1 if the value to search does not occur.
Consider searching for "test"
var str = "Hello this is a test";
var n = str.indexOf("test");
The result of n will be: 16, ergo, as in your script, larger than 0... and "found"
What it does is
For each rows in my table "result"
If one of all these values, that I look in lowercase, is equal to what I typed in the "searchBar" in lower case, more than one time, then I found it, and so found = "true"
From search bar key press event will be triggered and value of search bar will passed to search function
$("#searchBar").keyup(function() {
searchFunction($(this).val());
});
function searchFunction(value) {
//value will contain the value of search bar
$("#results tr").each(function() {
//assuming value is not there in tr
var found = "false";
//now searching for each tr for value
$(this).each(function() {
//converting to lower case and comparing each value with searchbar value
if (
$(this)
.text()
.toLowerCase()
.indexOf(value.toLowerCase()) >= 0
) {
found = "true";
}
});
//actual showing/hiding row
if (found === "true") {
$(this).show();
} else {
$(this).hide();
}
});
}
if need more info about index of
https://www.w3schools.com/jsref/jsref_indexof.asp
#MattCouthon let me know if you need anything else

console.log of undefined doesn't log

I am trying to fetch data from www.matchbook.com using this script
function scrape(){
var row = document.querySelectorAll(".mb-runner")[0]; //get rows
console.log(row.textContent); //log row content
}setInterval(scrape, 1000);
This code produces inline data ArsenalArsenal1.347$2591.349$20,8171.352$4811.363$11,2331.368$11,4571.379$9,948 without delimiter. Do you know how should I separate this data?
Here I am posting screen how data looks on a web
When the contents of that cell changes to MAKE OFFER, it no longer has the mb-price__odds class, so the selector matches the next cell.
Instead of selecting by this cell's class, use the class of the container, which I don't think goes away.
Then check whether this matched anything before trying to access .textContents.
function scrape() {
var cell = document.querySelector(".mb-price:first-of-type .mb-price__odds");
if (!cell) {
console.log("Log me null please, do not skip to another cell !");
} else {
console.log(cell.textContents);
}
}
Finally I solved my problem via this javascript code:
function scrape(){
var radek = document.querySelectorAll(".mb-runner")[2];//row
var bunka = radek.querySelectorAll(".mb-price")[0]; //cell
console.log(bunka.textContent); //cell value
}setInterval(scrape, 1000); //run every second
Try this.
No need to querySelectorAll if you only need the first element
Find the parent first and look for the price only if the element exists
Put null check on the element && the text content
function scrape(){
var x = document.querySelector(".mb-price");
var y = x && x.querySelector('.mb-price__odds');
if (y && y.textContent){
console.log(y.textContent);
}
else {
console.log('No Content');
}
}

Filter options by reading character length inside for loop

I have a widget (the widget code in the pen linked below is not the actual code, please just pay attention to the filtering function jQuery.fn.doFilterOptions(){..}).
Use case:
I have a non-native selectbox. I need to extend its functionality to accept an onclick event which allows the user to type data into the selectbox (not targeting a traditional <select>), it should filter the .options available by simply showing or hiding them based on its inner HTML value, if no match is found at any point during the loop through the string being entered by the user, I need the options to continue not being displayed.
Issue:
Right now it works 95% of the way, the only issue is that if an invalid char is found, the loop keeps checking the rest of the users entries char by char, and if the next char is a match to any of the options in the same index, it re-display's this as a valid .option.
$('.selectbox .selected').on('keyup', function(){
var theseOptions = $(this).parent('.selectbox').find('.option');
var defaultPlaceholder = $(this).data('placeholder');
var filterOptions = (function(curSelectedVal){
if (curSelectedVal === ' ' || curSelectedVal.length === 0 || curSelectedVal === defaultPlaceholder){
theseOptions.show();
}
var optionsVal;
var doInputOptionsComparison = (function(){
var invalidOption = false;
for (var letterPos = 0; letterPos < curSelectedVal.length; letterPos++){
theseOptions.each(function(optionIteration){
var thisOption = $(this);
thisOptionsVal = thisOption.html();
if (curSelectedVal.length > thisOptionsVal.length ){ // If a longer string has been input by the user than exists in the option being iterated over, hide this option
thisOption.hide();
invalidOption = true;
}
else if ((thisOptionsVal[letterPos].toLowerCase().trim() === curSelectedVal[letterPos].toLowerCase().trim()) && invalidOption === false){ // If the input string matches this option and no invalid options have been found in the letterPos prior to it, show this option
thisOption.show();
}
else { // If the string does not match any option
invalidOptionFound = true;
thisOption.hide();
}
});
}
})();
})($(this).html());
});
Here is the demo, try selecting then typing abz you will see the filter working properly.
Now erase that input data, and now type azc. You will see the abc option comes available again because the c matches in that same index (user input[i] = optionsHtml[i] = show();), resulting the the above described undesirable effect.
http://codepen.io/nicholasabrams/pen/KwwMPG?editors=001
BONUS:
Would this be easier by using regEx to do the filtering?
I managed to use a dynamic regEx filter function it it cut the code down big time! Wow what a better solution.
$.fn.filterOptionsByUserInput = function(optionSelector){
var curInput = $(this).html().trim().replace(/ /g, '').toLowerCase();
$(optionSelector).each(function(optionIndex){
var userInputRegEx = new RegExp('^'+curInput+'.*');
if ($(this).html().toLowerCase().trim().match(userInputRegEx)){
$(this).fadeIn('slow');
}
else {
$(this).fadeOut('slow');
}
});
};
http://codepen.io/nicholasabrams/pen/LEEwrm?editors=001

jquery each loop only looping once and if using else code stops

I've got two problems with the following javascript and jquery code.
The jquery each loop only iterates once, it gets the first element with the right ID does what it needs to do and stops.
The second problems is that when I use the else in the code the one inside the each function, it doesn't even tries the next if, it just exits there.
I'm probably doing something fundamental wrong, but from the jquery each function and what I'd expect from an else, I don't see it.
Javascript code:
var $checkVal;
var $checkFailed;
$("#compliance").live("keypress", function (e) {
if (e.which == 10 || e.which == 13) {
var checkID = $(this).parents('td').next().attr('id');
var checkVal = $(this).val();
$('#' + checkID).each(function () {
var cellVal = $(this).text();
if (checkVal == cellVal) {
$(this).removeClass("compFail").addClass("compOk");
} else {
$(this).removeClass("compOk").addClass("compFail");
var checkFailed = True;
}
});
if (checkFailed == 'True') {
(this).addClass("compFail");
} else {
(this).addClass("compOk");
}
}
});
How could I get the each loop to iterate through all instances of each element with the id assigned to the variable checkID, and get the code to continue after the else, so it can do the last if?
An id should appear on a page only once. If you want to have multiple elements with same id, then use a class, not an id.
Your each loop iter only once because you are selecting by id thus you are selecting only one element in the page. If you change you elements to a class it should work like you expect.
This is to illustrate what I'm talking about in my comment, so that you do not remove the wrong var:
var checkVal;
var checkFailed;
$("#compliance").live("keypress", function (e) {
if (e.which == 10 || e.which == 13) {
var checkID = $(this).parents('td').next().attr('id');
//HERE is the first edit
checkVal = $(this).val();
$('#' + checkID).each(function () {
var cellVal = $(this).text();
if (checkVal == cellVal) {
$(this).removeClass("compFail").addClass("compOk");
} else {
$(this).removeClass("compOk").addClass("compFail");
//HERE is the second
checkFailed = True;
}
});
if (checkFailed == 'True') {
(this).addClass("compFail");
} else {
(this).addClass("compOk");
}
}
});
Normally, the way you have it would cause a compile-time error (in a typed language like C#) for redeclaring a variable. Here, it's not clear to me if it will be used as a local variable (ignoring your global variable) or if javascript will combine them and consider them the same. Either way, you should use it as I have shown so that your intent is more clear.
EDIT: I have removed the $ from your variables (var $checkVal) as on jsFiddle it was causing issues. SO if you do not need those $'s, then remove them. Also, note that testing on jsFiddle indicates that you do not need to change your code (other than possibly removing the $ from your declaration) as javascript appears to consider them the same variable, despite the redeclaration, which I find a bit suprising tbh.
The jquery each loop only iterates once, it gets the first element
with the right ID does what it needs to do and stops.
Yes, this is absolutely right for the code you're using:
$('#' + checkID).each(function(){};)
ID attributes are unique. There must be only one element with a given ID in the DOM. Your selector can match only one element. You are iterating over a collection containing just 1 item.

nextSibling issue, should be simple

Ok, I'm trying to come to grips with this nextSibling function in JS. Here's my issue within the following code...
var fromRow = document.getElementById("row_1");
while(fromRow.nodeType == 1 && fromRow.nextSibling != null)
{
var fRowId = fromRow.id;
if (!fRowId) continue;
// THIS ONLY gets done once and alerts "row_1" ONLY :(
alert(fRowId);
fromRow = fromRow.nextSibling;
}
Ok can someone please tell me what is wrong with this code? There are siblings next to this document.getElementById("row_1"); element for sure as I can see them, and they all have id attributes, so why is it not getting the id attributes of the siblings?? I don't get it.
row_1 is a TR element, and I need to get the TR elements next to it within this table, but for some reason, it only gets the 1 element that I can already get using document.getElementById, arggg.
Thanks guys :)
Try:
var fromRow = document.getElementById("row_1");
while(fromRow !== null)
{
var fRowId = fromRow.id;
if (!fRowId || fromRow.nodeType != 1) {
fromRow = fromRow.nextSibling;
continue;
}
// THIS ONLY gets done once and alerts "row_1" ONLY :(
alert(fRowId);
fromRow = fromRow.nextSibling;
}
While fromRow.nextSibling != null would halt on the second to last iteration because you already set fromRow to its nextSibling at the end. Also, you don't necessarily want to halt if the next node isn't an element, you just want to move onto the next one if possible. Finally, if you hit the continue in your original example, you'll run into an endless loop because fromRow would never change value.
Your while loop stops as soon as it encounters a node not of type 1. So if there is any whitespace between your elements the while loop will break after the first element.
What you probably want is:
while(fromRow.nextSibling != null)
{
if(fromRow.nodeType == 1) {
...
}
}

Categories