sending infinity number of checkbox values to text - javascript

I have a table with n number of rows with checkboxes and a what i want to do is if i select a checkbox the value should go to the text area, so i stored all elements in an array first, but it isnt happening, as you can see i added alerts as well to check it out. please help.
window.onload = function () {
var oRows = document.getElementById('rnatable').getElementsByTagName('tr');
var iRowCount = oRows.length;
alert('Your table has ' + iRowCount + ' rows.');
var i = 0;
cb = new Array(iRowCount);
while (i <= iRowCount) {
var id = 'check'+ i;
cb[i] = document.getElementById(id);
i++;
}
//alert('Your table has ' + cb[i].value + ' rows.');
for(var a=0; a < iRowCount; a++) {
var fasta = document.getElementById('fasta');
if(cb[a].checked) {
fasta.value = cb.value + ",";
};
};
}

Are you seeing an error in the console? I suspect that when while (i <= iRowCount) runs when i === iRowCount that document.getElementById(id) isn't yielding a result, and that then when you use that value, bad things happen.
Also, each lap through the fasta loop overwrites the previous value. You probably want something like fasta.value += cb.value + ","; instead.

Related

Dynamically load images, break loop on error

I asked this previously but didn't get an answer that applied to my project. I am trying to load images to a table dynamically without having to use server side code. It works, but I want to be able to have an infinite loop that breaks when a picture fails to load, rather than hard code the number of rows I need. That way I won't ever have to update the code, I'll just be able to add pictures to a folder if I want to expand the table.
Right now the "onerror" attribute hides the failed image, but I also want to break out of the outer loop (loop1).
function headCatalogLoader() {
var table = document.getElementById("catalog");
var meshNum = 0;
var uniqueID = 0;
loop1:
for (var i = 0; i <= 50; i++) { // i made it 50 instead of infinite for now
var row = table.insertRow(i);
loop2:
for (var k = 0; k <= 2; k++) { // 2 is because 3 columns
var skinTone = "none";
var cell = row.insertCell(k);
if (k == 0) {
skinTone = "lgt";
}
else if (k == 1) {
skinTone = "med";
}
else if (k == 2) {
skinTone = "drk";
}
cell.innerHTML = "<img src=\"headimgs/head" + skinTone + meshNum + ".png\" id=\"head" + uniqueID + skinTone + "\" onclick=\"previewIt(this)\" onerror=\"$(this).hide();\" />";
uniqueID++;
}
meshNum++;
}
var tbody = $("table tbody");
tbody.html($("tr",tbody).get().reverse());
}
Breaking from within the attribute is out of the loop's scope and doesn't work. Also using
$('img').on("error", function () {
break loop1;
});
inside loop2 doesn't do anything. Someone suggested I use a recursive method and rewrite my function, but that won't work for me since I'm dynamically creating a table and using image names that correspond to the loop. Any help or suggestions would be wonderful!
I'm thinking you could use an XMLHttpRequest to check the response for that URL before trying to put it onto the page. If status is not 404 then insert image else break loop1. Something like this might work:
function headCatalogLoader() {
var table = document.getElementById("catalog");
var meshNum = 0;
var uniqueID = 0;
loop1:
for (var i = 0; i <= 50; i++) { // i made it 50 instead of infinite for now
var row = table.insertRow(i);
loop2:
for (var k = 0; k <= 2; k++) { // 2 is because 3 columns
var skinTone = "none";
var cell = row.insertCell(k);
if (k == 0) {
skinTone = "lgt";
} else if (k == 1) {
skinTone = "med";
} else if (k == 2) {
skinTone = "drk";
}
// note: you'll need to use an absolute path for imageUrl
var imageUrl = "http://example.co.uk/example/headimgs/head" + skinTone + meshNum + ".png";
var xhttp = new XMLHttpRequest();
xhttp.open('HEAD', imageUrl, false);
xhttp.send();
if (xhttp.status !== 404) {
cell.innerHTML = "<img src=" + imageUrl + " id=\"head" + uniqueID + skinTone + "\" onclick=\"previewIt(this)\" onerror=\"$(this).hide();\" />";
uniqueID++;
} else {
break loop1;
}
}
meshNum++;
}
var tbody = $("table tbody");
tbody.html($("tr", tbody).get().reverse());
}
Note: you'll need to use an absolute path for the XMLHttpRequest. I've just used example.co.uk/example because I don't know your URL.
I'm guessing you're only expecting it to error if the image is not found, because that would indicate that you've reached the last image in your folder, which is why I checked !== 404, if you want to break in the case of any error (such as 500 internal server error), it might be best to change if (xhttp.status !== 404) to if (xhttp.status === 200).

Using JS loops to send unique vars from HTML buttons to function

Beginner here. I have a loop that creates 26 buttons with unique ID's and values. What I'm struggling with is figuring out the proper way to send the button's ID to a function so that I can store unique vars for each button independently without creating more than one function. I currently have an array with the 26 items I need for my buttons and the following loop:
function makeButtons() {
for (var i = 0; i < 26; i++) {
document.getElementById("whereButtonsGo").innerHTML += "<input type = 'button' value = '" + items[i] + "' id = 'button" + items[i] + "' onclick = doThing(button" + items[i] + ")'>";
}
}
I want the argument in the onclick function to be sent to a function such as:
function doThing(id) {
document.getElementById("'" + id.value + "'").style.color = "pink";
}
But so far I haven't been able to get this to work. Any help would be greatly appreciated!
Maybe this is what you are looking for:
makeButtons();
function makeButtons() {
for (var i = 0; i < 26; i++) {
document.getElementById("whereButtonsGo").innerHTML += "<input type = 'button' value = '" + i + "' onclick = doThing(this)>";
}
}
function doThing(currentButton) {
currentButton.style.color = "pink";
}
<div id="whereButtonsGo"/>
Try to keep the IDs as simple as possible
I recommend against using innerHTML for creating elements that you actually want to do something. Even if it works, your code will be amazingly unclear. Instead, write code that demonstrates that you're actually creating and adding elements:
var items = [1,2,3,4,5,6];
function makeButtons() {
var container = document.getElementById("whereButtonsGo");
for (var i = 0; i < items.length; i++) {
var button = document.createElement("button");
button.type = 'button';
button.value = items[i];
button.innerText = items[i];
button.id = 'button'+items[i];
button.onclick = doThing;
container.append(button)
}
}
function doThing() {
console.log('click of ' + this.id);
}
makeButtons();
Note that you don't need to pass the id in the function call for the event - the button that was clicked will be available as this.
Here is a fiddle.

JS for loop not working

I have a for loop which looks like this:
for (var i = 0; i < list.length; i++) {
It is looping through Firebase data in the database and returning all the data in the database.
However, I want it to only go up to the first 10 database items. So I changed the loop to:
for (var i = 0; i < 9; i++) {
But this fails to display any results when the there are less than 10 pieces of data in the database. However, if I set the number to however many objects I have in the database, for example 10 because I have 10 objects, it displays them all. But any less than this number and I just get a blank webpage.
Here is the webpage when I have 10 objects in my Firebase database:
And here it is when I remove one of those objects:
I have no idea why this is happening - The logic is correct - if i is less than 9 then display the data - But instead it only displays it when it equals 9.
Here is the full JS:
function refreshUI(list) {
var lis = '';
var lis2 = '';
var lis3 = '';
var lis4 = '';
for (var i = 0; i <= 9; i++) {
lis += '<li data-key="' + list[i].key + '" onclick="addText(event)">' + list[i].book + '</li>';
lis2 += genLinks(list[i].key, list[i].book)
};
for (var i = 10; i < list.length; i++) {
lis3 += '<li data-key="' + list[i].key + '" onclick="addText(event)">' + list[i].book + '</li>';
lis4 += genLinks(list[i].key, list[i].book)
};
document.getElementById('bookList').innerHTML = lis;
document.getElementById('bookList2').innerHTML = lis2;
document.getElementById('bookList3').innerHTML = lis3;
document.getElementById('bookList4').innerHTML = lis4;
};
function genLinks(key, bkName) {
var links = '';
links += '<img src="images/bin.png" style="width: 24px; height: 24px; transform: translateY(-7px); opacity: .4;"></img> ';
return links;
};
function del(key, bkName) {
var response = confirm("Are certain about removing \"" + bkName + "\" from the list?");
if (response == true) {
// build the FB endpoint to the item in movies collection
var deleteBookRef = buildEndPoint(key);
deleteBookRef.remove();
}
}
function buildEndPoint (key) {
return new Firebase('https://project04-167712.firebaseio.com/books/' + key);
}
// this will get fired on inital load as well as when ever there is a change in the data
bookList.on("value", function(snapshot) {
var data = snapshot.val();
var list = [];
for (var key in data) {
if (data.hasOwnProperty(key)) {
book = data[key].book ? data[key].book : '';
if (book.trim().length > 0) {
list.push({
book: book,
key: key
})
}
}
}
// refresh the UI
refreshUI(list);
});
If anybody has any help I'd greatly appreciate it!
When the list size is shorter than 10, you will get an error in the loop because you will eventually address a property (like key) that does not exist on list[i] (since it is undefined). If you would check the console, you would notice that this error is reported.
To fix this, change the condition of the first for loop like this:
for (var i = 0; i < Math.min(10, list.length); i++) {
This way, the loop will never iterate to an entry that does not exist. It will stop after 9 or after list.length-1 whichever comes first.
Alternatively, you can just put the two conditions with an && operator:
for (var i = 0; i < 10 && i < list.length; i++) {

format text fields created

I'm really new so I'll appreciate some help here. please refer to this fiddle.
$(function () {
var input = $('<input type="text" />');
$('#qty').bind('blur', function () {
var n = this.value || 0;
if (n + 1) {
setFields(n);
}
});
function setFields(n) {
$('#newFields').html("");
$('#newFields').append("<table>");
//to create rows and columns
for (i = 0; i < n; i++) {
for (j = 0; j < 1; j++) {
var somestr = "Sample ";
var num = i + 1;
$('#newFields').append("<td>" + somestr + num + ":" + "</td>");
$('#newFields').append("<td>");
var newInput = input.clone();
var newFields1 = $('');
newFields1 = newFields1.add(newInput);
newInput.appendTo('#newFields');
$('#newFields').after("</td>");
}
$('#newFields').after("</tr>");
}
}
});
I'll like to have the input text field appear on the right column (so it should be [column 1]"Sample #" [column 2] input text field, with "Sample 2" and another text field appearing on the next row and so forth). Been trying but couldn't get it. Thanks!
Try appending new rows to the existing table by targeting the table itself on the appendTo() method. You don't need to add a new table and, as you haven't been closing the table off with </table> this isn't working at present anyway.

Get the value from only selected checkbox

I am trying to get the value from a checkbox using javascript.
I want only one checkbox value to be passed to the javascript function, and if multiple are selected, an alert box informing that only one box can be checked for the function.
I've tried this:
var publish_trigger = document.querySelector("#publish_trigger");
publish_trigger.onclick = function() {
var _posts = document.getElementsByName('post_id[]');
var check = _posts.checked;
var boxes = _posts.length;
var txt = "";
if(check.length > 1) {
alert("Only one at a time");
} else {
for (i = 0; i < boxes; i++) {
if (_posts[i].checked) {
txt = txt + _posts[i].value + " "
}
}
}
alert(txt);
return false;
}
This code is wrong:
var _posts = document.getElementsByName('post_id[]');
var check = _posts.checked;
getElementsByName() returns a NodeList (effectively an array) of elements, so your variable _posts doesn't have a checked property. You need to loop through _posts to count the checked property on the individual elements within _posts.
You already have a for loop so add the validation in there:
var count = 0;
for (var i = 0; i < boxes; i++) {
if (_posts[i].checked) {
if (++count > 1) {
alert("Only one checkbox may be checked at a time.");
return false;
}
// I don't know what you're trying to do with the following line
// but I've left it in.
txt = txt + _posts[i].value + " "
}
}
(Note: unrelated to your question, you should declare the loop counter i within your function otherwise it will be global and might lead to hard to debug problems if you are using it in other places too.)

Categories