Getting undefined string constraint error in Javascript - javascript

I want to pass a Javascript variable as a argument of a function called on onclick event of a checkbox, and the checkbox is created in innerHTML.
The code snippet is:
function populateValue(Result) {
var valueSet = new Array();
valueSet = Result.split("##");
for (i = 1; i < valueSet.length - 3; i++) {
var tr = document.createElement("tr");
var td = document.createElement("td");
tr.setAttribute("align", "left");
tr.className = "table_ce11";
td.setAttribute("align", "center");
var code = String(valueSet[i - 1]);
td.innerHTML = "<input type='checkbox' name='pCheckBox' value='111' id ='" + code + "' onClick=\"javascript:decide('" + code + "')\">";
tr.appendChild(td);
}
}
function decide(code) {
alert("here");
alert(document.getElementById(code).value);
if (document.getElementById(code).checked) alert("chked");
else alert("unchked");
}
while running this, neither am able to set the id nor to pass the argument of the function decide(). I get the error:
"undetermined string constraint".
But if I hardcode the values the function runs fine.
Any suggestions on this?

Just for starters
Split creates an array.
var valueSet = Result.split("##");
You need to test if there ARE at least 4 items in the array
if (valueSet.length <= 3) return
for (var i = 1; i < valueSet.length - 3; i++) {
no need to create a string when you string concatenate a string anyway
var code = valueSet[i - 1];
No need to use javascript: prefix and no need to pass the code when it is the same as the ID:
td.innerHTML = '<input type="checkbox" name="pCheckBox" value="111" id ="' + code + '" onClick="decide(this.id)">';
Also default align is left and you align center on the cell so get rid of
// tr.setAttribute("align", "left");
can you post more of the code and tell where things are going wrong exactly?

Related

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.

Calling a function via created HTML code

EDIT:
After some re-working to use another method (createElement) I've gotten my code to the point where it can properly call on elements, however it only uses the parameters of the last banner made at the end of the function. Here's the snippet of what I have to date.
function load() {
var staffB = ["Admin", "GM", "Dev", "FM", "Lore", "App", "Magic", "Event"];
var table = document.createElement("table");
for (var staffI = 0; staffI < staffB.length; staffI = staffI + 2) {
var row = document.createElement("tr");
var td = document.createElement("td");
var td2 = document.createElement("td");
var temp1 = staffB[staffI];
var temp2 = staffB[staffI + 1];
for (var i = 0; i < 10; i++) {
td.innerHTML = '<img src=banners/' + staffB[staffI] + '.png height="auto" width="100%">';
td.onclick = function() { select (temp1) }
td2.innerHTML = '<img src=banners/' + staffB[staffI + 1] + '.png height="auto" width="100%">';
td2.onclick = function() { select (temp2) }
}
row.appendChild(td);
row.appendChild(td2);
table.appendChild(row);
}
document.getElementById("staff").appendChild(table);
}
First time posting here, my apologies in advance for being a total nub.
So, to start off, I'm working on a page to assemble medieval-looking banners for a community that I'm part of, so in order to make it easy on myself to add/remove different banners in the future I made a modular HTML system using 'for'. When it's created it changes the names of the files it access to the names in an Array so that I only have to change the list and add a file. The HTML it creates is a table so that I can insert the images with two columns.
That table is then used for the selection menu as to which banner/curtain rod you'd be selecting. I have an ID attached to each <tr> based on the banner within (done during the creation of the HTML). Now I need to have it so that when they're clicked for selection, the sample image shown changes. Within the created HTML I created an onclick="select( Insert Banner Name Here )" in an effort to have the banner info transfer over to the next function, which is a switch.
I found out later that, from what I've seen, the function transfers a variable and not the word/data itself. I'm trying to think of a way I can code this so that, when called, the function knows what banner was clicked. When I tested the code it would always return [object HTMLTableCellElement].
In case I'm not making sense, this image may help. (Apologies for the bright colors, they're there so I can see the different divs easier).
The banners being selected are on the right, and the preview is on the left. The images on the right are within a table within a div (where the scroll bar is). That's where I'm trying to call my switch function from.
If anyone knows a way this is possible, or a better way of going about it I'd love for some help with it.
You might want to look into the document.createElement function.
http://www.w3schools.com/jsref/met_document_createelement.asp
With this you could do something like:
var staffB = ["http://i.stack.imgur.com/ziZF1.png", "http://i.stack.imgur.com/ziZF1.png", "http://i.stack.imgur.com/ziZF1.png"];
var table = document.createElement("table");
for (var staffI = 0; staffI < staffB.length; staffI = staffI + 2) {
var row = document.createElement("tr");
var td = document.createElement("td");
for (var i = 0; i < 10; i++) {
td.innerHTML = '<img src=' + staffB[staffI] + '.png height="auto" width="100%">';
}
td.onclick = function () {
//Whatever function you like
alert(1);
}
row.appendChild(td);
table.appendChild(row);
}
document.body.appendChild(table);
This way you have an object approach to your elements and thereby better control over your event listeners.
EDIT 1:
Example using anonymous functions to maintain the current loop state:
var staffB = ["http://www.faster-minis.com/site/speed-mini.jpg", "http://i.stack.imgur.com/ziZF1.png"];
var table = document.createElement("table");
for (var staffI = 0; staffI < staffB.length; staffI++) {
var row = document.createElement("tr");
for (var i = 0; i < 10; i++) {
var td = document.createElement("td");
td.innerHTML = '<img src=' + staffB[staffI] + ' height="auto" width="100%">';
//Anonymous scope to retain loop state
(function(a){
td.onclick = function () {
//Whatever function you like
//In here, "a" is the current "i"
alert(a);
alert(i);
}
})(i);
row.appendChild(td);
}
table.appendChild(row);
}
document.body.appendChild(table);
So, what I ended up doing was re-working it with divs instead. Doing that I was able to set the ID for each block, and from there send an onclick to a 'filter' function. The filter function then used the elements .id to extract which was which, and then send that info off to my switch function. Here's the code for those interested;
var staffB = ["Admin", "GM", "Dev", "FM", "Lore", "App", "Magic", "Event"];
for (var staffI = 0; staffI < staffB.length; staffI = staffI + 2) {
var co1 = document.createElement("div");
var co2 = document.createElement("div");
var wide = (282 / 2 - 10);
co1.setAttribute("id", staffB[staffI]);
co1.setAttribute("onclick", "filter(this)");
co1.style.float = "left";
co1.style.width = wide;
co1.innerHTML = '<img src=banners/' + staffB[staffI] + '.png height="auto" width="' + wide + '">';
co2.setAttribute("id", staffB[staffI + 1]);
co2.setAttribute("onclick", "filter(this)");
co2.style.float = "right";
co2.style.width = wide;
co2.innerHTML = '<img src=banners/' + staffB[staffI + 1] + '.png height="auto" width="' + wide + '">';
document.getElementById("staff").appendChild(co1);
document.getElementById("staff").appendChild(co2);
}
And the filter function;
function filter(ele) {
var id = ele.id;
select (id);
}
Hope this helps someone else if they find this post.

Cannot manage to use innerHTML

I'm new to Stack Overflow and also in JavaScript. So, first of all, hello to everyone and thanks in advance for your help.
I'm using Incomedia Website X5 Evolution to create a website. On one of the page, I want to populate a table with data from a server. So, I've created a table and insert in each cell this HTML code:
<!--#0000,0000-->
Values are representing the row and the column. I managed to write a javascript to change the value of each cell. But when I want to replace the content of the HTML pahe using innerHTML, it does not work. Nevertheless, everything seems correct as the old and the new html content is the same. Even if I just use again the original variable, it still doesn't work.
Could you tell me where is the problem please ?
Here the javascript code:
<script>
var i;
var div = document.getElementById('imTableObject_1');
div = document.getElementsByTagName('table');
var htmlContent = div[0].innerHTML;
var newHtmlContent = div[0].innerHTML;
var test = div[0].innerHTML;
var row,col;
//I can't understand why the scrip stop running at this line. I didn't change anything...
div[0].innerHTML = newHtmlContent ;
for (i=htmlContent.length - 5; i > -1; i--) {
if(htmlContent.charAt(i)=='#') {
//alert(i);
//alert(htmlContent.substring(i+6,i+10));
row = parseInt(htmlContent.substring(i+1,i+5));
col = parseInt(htmlContent.substring(i+6,i+10));
newHtmlContent = insertText(row,col,newHtmlContent,i);
};
};
alert(div[0].innerHTML);
alert(newHtmlContent );
//This does not work
div[0].innerHTML = newHtmlContent ;
alert("Done !");
function insertText (row, col, text, index) {
var length;
var newText;
length = getTextLength (text,index + 13);
//alert(htmlContent.substring(index+13,index+13+length));
newText = text.substring(0,index+13);
newText += "Titi too !";
newText += text.substring(index+13+length,text.length);
//alert(newText);
return newText ;
}
function getTextLength (text,startIndex) {
var i = 0;
for(i = startIndex ; i < text.length ; i++) {
//alert(text.substring(i,i+7));
if(text.substring(i,i+7) == "</span>") {
return i - startIndex ;
};
};
return -1;
}
</script>
You set:
var newHtmlContent = div[0].innerHTML;
And then:
div[0].innerHTML = newHtmlContent ;
You're setting its content to what its content already was. Hence, no change occurs.
Change the 3rd row to
div = document.getElementsByTagName('td');
to look for <td> tags instead of <table> tags. <table>s can't directly store text data so I guess their innerHTML doesn't work as expected either.
I managed to get it working here: http://jsfiddle.net/mgabor/ZMaW6/1/

sending infinity number of checkbox values to text

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.

Trying to call two functions on the same input field but only calls one

I have two working functions which I want to assign to two inputs:
<input type="text" id="start0" value="0" name="start[]" onkeyup="displayTotal();"/>
<input type="text" id="end0" value="0" name="end[]" onkeyup="displayTotal();"/>
I would like to be able to use a displayHoras(); onkeyup for those two too. (2 many 2s on this thread already). when I use displayHoras(); instead of displayTotal(); it works, but when I call both of them like this it doesnt:
<input type="text" id="start0" value="0" name="start[]" onkeyup="displayTotal();displayHoras();"/>
<input type="text" id="end0" value="0" name="end[]" onkeyup="displayTotal();displayHoras();"/>
Any help will be welcomed.
I'll share the code of both functions because...who knows? The problem might be there, right?
function displayTotal()
{
var tableRows = document.getElementById('budgetTable').getElementsByTagName('tr');
var totalDays = tableRows.length - 3; //Don't count the header rows and the Total rows
var totalPrice = 0;
var price = filterNum(document.getElementById( 'txtPrice' ).value);
var totalField = document.getElementById( 'txtTotal' );
var tempHours = 0;
var tempTotal = 0;
for(var i = 0; i < totalDays; i++)
{
tempHours = document.getElementById("end" + i).value - document.getElementById("start" + i).value;
tempTotal = tempHours * price;
document.getElementById("total" + i).innerHTML = formatCurrency(tempTotal);
totalPrice += tempTotal;
}
totalField.value = formatCurrency(totalPrice*1.21);
}
function displayHoras()
{
var tableRows = document.getElementById('budgetTable').getElementsByTagName('tr');
var totalDays = tableRows.length - 3;
var tempHours = 0;
var tempTotal = 0;
for(var i = 0; i < totalDays; i++)
{
tempHours = document.getElementById("end" + i).value - document.getElementById("start" + i).value;
document.getElementById("totalHoras" + i).innerHTML = tempHours;
}
}
EDIT: I added the functions that create the table below.
function keyUpCall() {displayHoras(); displayTotal();}
function addRowToTable()
{
var tbl = document.getElementById('budgetTable');
var lastRow = tbl.rows.length - 4;
var iteration = lastRow;
var entry = iteration - 1; //because we started with day0, etc
var row = tbl.insertRow(lastRow);
// day cell
var cellDay = row.insertCell(0);
cellDay.appendChild(createInput('text','dia' + entry, '', keyUpCall, 'dia' + entry));
// start cell
var cellStart = row.insertCell(1);
cellStart.appendChild(createInput('text','start' + entry, 0, keyUpCall, 'start' + entry));
// end cell
var cellEnd = row.insertCell(2);
cellEnd.appendChild(createInput('text','end' + entry, 0, keyUpCall, 'end' + entry));
// precio unitario
var cellPrecioUnitario = row.insertCell(3);
cellPrecioUnitario.appendChild(createInput('text', null, '$36', null, null));
// total HOras
var cellTotalHoras = row.insertCell(4);
cellTotalHoras.id = 'totalHoras' + entry;
// total cell
var cellTotal = row.insertCell(5);
cellTotal.id = 'total' + entry;
}
function createInput(type, id, value, action, name)
{
var el = document.createElement('input');
el.type = type;
el.id = id;
el.value = value;
el.onkeyup = action;
el.name = name;
return el;
}
At this point, the action is not even attached for some reason.
Edit2: I SOLVED THE PROBLEM!!! IUPI!! it was this line:
var totalDays = tableRows.length - 3;
In the previous version of this form I was using 3 extra rows, my client got me to add a couple extra ones for Tax and without Tax result. I changed it to:
var totalDays = tableRows.length - 5;
And that fixed it!
You can create a single function that calls both functions
function function1(){
displayTotal();
displayHoras();}
I'd recommend creating a function that then calls your two functions, e.g.:
function handleKeyUp() { // Or `updateDisplay` or some such
displayTotal();
displayHoras();
}
Putting too much text within the onXYZ attributes is problematic (though I'm not immediately seeing why yours isn't working).
Off-topic 1: I'd also suggest hooking up event handlers using DOM2 methods (addEventListener on standards-compliant browsers, attachEvent on IE8 and below) rather than using DOM0 mechanisms like onXYZ attributes.
Off-topic 2: A JavaScript library like jQuery, Prototype, YUI, Closure, or any of several others can help smooth over browser differences (and even bugs) like the event attachment stuff above, as well as providing lots of handy utility functionality. Totally optional, but using one helps you concentrate on what you're actually trying to do, without worrying about slightly different plumbing in various different browsers.
old school javascript ^^
try this instead of the attribute variant, and use bugzilla, or a javascript debugger
var checks_keyup = function() {
displayTotal();
displayHoras();
}
var inputs = document.getElementsByTagName('input');
for(var i=0;i<inputs.length;i++) {
if(/^(start|end)/.test(inputs[i].id))
inputs[i].onkeyup = checks_keyup;
}
Try calling second function withing the first function itself,
function displayTotal()
{
\\.....your code
displayHoras();
}

Categories