I have an html page dynamically generated by javascript with the onLoad event.
This is the javascript:
function populateTable(q,a1,a2,a3,a4) {
var i;
for (i=0;i<10;i++) {
table = document.createElement("table");
table.appendChild(createQuestion(q,i));
for (var j=0;j<4;j++) {
var answer= eval("a" + (j+1));
table.appendChild(createAnswers(j,answer,i));
}
var tabform= document.getElementById("tablesform");
tabform.appendChild(table);
}
}
function createQuestion(quest,i) {
var row = document.createElement("tr");
var tabd = document.createElement("td");
tabd.setAttribute("class","question");
var qinput=document.createElement("input");
qinput.setAttribute("type","text");
qinput.setAttribute("name","q" + (i+1));
qinput.setAttribute("value",quest[i]);
qinput.setAttribute("readonly","readonly");
qinput.setAttribute("size","50");
row.appendChild(qinput);
var tabd1 = document.createElement("td");
var rdiv = document.createElement("div");
rdiv.setAttribute("id","result" + (i+1));
tabd1.appendChild(rdiv);
row.appendChild(tabd1);
return row;
}
in FF it works fine, it makes 10 neat tables, each with the question inside the text input on the first row, with all of the text input fields of the same size (50), etc etc..
on IE8 the text field remains empty, and moreover its size is not fixed! The strange thing is that if I go look at the html that was generated i see:
<FORM id=tablesform method=post action=processquiz.php>
<INPUT value=" - Correct The Test - " type=submit>
<INPUT onclick="window.location='logout.php'" value=" - Log Out - " type=button>
<TABLE>
<TR>
<INPUT value="What browser has the most DHTML extentions?" readOnly size=50 type=text name=q1>
<TD><DIV id=result1></DIV></TD>
</TR>
which is perfectly fine! What could be the problem?
EDIT: document is html 4.01 strict
Related
Good day all and happy b-lated new year
So I got a problem and I would rather not tie everything directly into an array and call it from there. Im building an old school chat based RPG and I have hit an issue with passing on the skills which are determined by the characters stats. Essentially what I am trying to do is this:
I have a bunch of buttons which represent a total of 72 skills:
<td><button type="button" onclick="" class="button" id="math">MATH</button></td>
which I would like to use their onclick event to pass both the skill name and skill rating to this targeted area of the page:
<td><input type="text" id="skill1" value="" readonly /></td>
<td><input type="text" id="skillRate1" value="" readonly /></td>
the skillRate(s) are reflected in their appropriate variables like so:
var math = (mem * 3) + (log * 2);
and ideally what will happen is I set each targeted recipient in an array as skill and skillRate respectively so that once all the skills are selected it is stored in the array and uploaded into the DB as such.
Originally I was thinking something along the lines of this:
function addSkill(){
var n = 0;
for (n = 0; n < 17; n++){
getElementById("skill" + n) = getElementById(this.id);
getElementById("skillRate" + n) = //figure out some way to turn this into the var for skillRate (getElementById(this.id));
}
}
I've been bumbling around with this for days now but cant seem to get anywhere and I would really rather not just put all the skills and their respective skillRates in an array unless I have to.
Any thoughts or suggestions as to how to accomplish this or maybe another approach altogether?
Thanks in advance!
If i understood you problem properly, maybe you can do it this way:
For html
<td>
<button type="button" data-skill="math" data-point="20" onclick="addSkill(this)" class="button" id="math">MATH</button>
</td>
For javascript
//Start your variables
var tagsSkills = []
var totalPoint = 0;
function addSkill(skill) {
var dataset = skill.dataset;
totalPoint += dataset.point; // Here you will sum the skill's point
tagsSkills.push(dataset.skill); // Add skill into array
}
Or maybe, instead you could use a map structure that store map[skill] to points. And, just with skill in the function, you will have the points just getting it from the map.
Not sure why you don't want array, they are your friends.
This code will build a table from array but only uses it for build, all the calculations are later taken from html.
This is vanilla js, could be easier/prettier with jQuery.
JS:
//This is just for building the table, you don't have to use it if you don't want array for some reason :S
var skillsArr = [{
firstSkillName: "Memory",
firstSkillValue: 15,
secondSkillName: "Logic",
secondSkillValue: 17
}, {
firstSkillName: "Dexterity",
firstSkillValue: 12,
secondSkillName: "Speedness",
secondSkillValue: 11
}];
var table = document.getElementById("tblSKills");
var tableBody = table.createTBody();
for (i = 0; i < skillsArr.length; i++) {
var row = tableBody.insertRow(i);
var cell = row.insertCell(0);
cell.innerHTML = skillsArr[i].firstSkillName + ": " + "<span>" + skillsArr[i].firstSkillValue + "</span>";
cell = row.insertCell(1);
cell.innerHTML = skillsArr[i].secondSkillName + ": " + " <span>" + skillsArr[i].secondSkillValue + "</span>";
cell = row.insertCell(2);
cell.innerHTML = "<button onclick='doMath(this)'>DO THE MATH</button>";
}
function doMath(currnetBtn) {
var currentRow = currnetBtn.parentElement.parentElement; //TD -> TR
var currentCells = currentRow.children;
var skill1 = document.getElementById("skill1");
var skill2 = document.getElementById("skill2");
var mathResult = document.getElementById("mathResult");
skill1.value = currentCells[0].innerText;
skill2.value = currentCells[1].innerText;
mathResult.value = (currentCells[0].children[0].innerText/1) * 3 + (currentCells[1].children[0].innerText/1) *2 ;//This is your *3 + *2 function or whatever you want.
//You can also make that each skill set will have its' own math function.
}
HTML:
<h1>
Welcome to my skill page!
</h1>
<h2>
Your results:
</h2>
<label id="lbl1"></label>
<input id="skill1" readonly />
<label id="lbl2"></label>
<input id="skill2" readonly />
<label>Result:</label>
<input id="mathResult" readonly />
<table id="tblSKills">
</table>
-- Fiddle --
I have a table which looks essentially like this
<!DOCTYPE html>
<html lang="en">
<body>
<table class="ui table" id="items">
<tbody>
<tr data-toggle="fieldset-entry">
<td><input id="items-0-quantity" name="items-0-quantity" type="text" value=""></td>
<td><input id="items-0-description" name="items-0-description" type="text" value=""></td>
</tr>
</body>
</html>
Using javascript, I'd like to have a button which adds a new row to the table, and I'd like the inputs in that new row to have id="items-1-xxx", and name="items-1-xxx, i.e. where there's a 0 in the original row I'd like a 1 in the new row.
I can make a new table row by cloning the old one, but I have not figured out how to modify the name and id attributes of the input.
Here's a sketch of what I've tried:
function cloneRow() {
var table = document.getElementById("items");
var original_row = table.rows[table.rows.length - 1];
var new_row = original_row.cloneNode(true);
// We have a new row and now we need to modify it as
// described in the question. The only way I've found
// is to grab the inner HTML:
var cell_contents = original_row.cells[0].innerHTML;
// Now we could do a bunch of string parsing and manipulations
// to increment the 0 to a 1 and stuff the modified HTML into
// new_row, but it seems there must be a better way.
// Finally insert the new row into the table.
original_row.parentNode.insertBefore(new_row, original_row.nextSibling);
}
What is the right way to update the input elements' id and name?
You could just build a new <td> and assign document.querySelectorAll('#items tr').length as the x in items-x-...:
function addItem() {
var items = document.querySelector('#items')
, itemcount = items.querySelectorAll('tr').length
, newitemQuantityText = 'items-' + itemcount + '-quantity'
, newitemDescriptionText = 'items-' + itemcount + '-description'
, newitem = document.createElement('tr')
, newitemQuantity = document.createElement('td')
, newitemDescription = document.createElement('td')
, newitemQuantityInput = document.createElement('input')
, newitemDescriptionInput = document.createElement('input');
newitemQuantityInput.id = newitemQuantityText;
newitemQuantityInput.name = newitemQuantityText;
newitemQuantity.appendChild(newitemQuantityInput);
newitemDescriptionInput.id = newitemDescriptionText;
newitemDescriptionInput.name = newitemDescriptionText;
newitemDescription.appendChild(newitemDescriptionInput);
newitem.appendChild(newitemQuantity);
newitem.appendChild(newitemDescription);
document.querySelector('#items').appendChild(newitem);
}
document.querySelector('#add').addEventListener('click', addItem);
<button id="add">add item</button>
<table id="items"></table>
However using good old innerHTML reads way better:
function addItem() {
var items = document.querySelector('#items')
, itemcount = items.querySelectorAll('tr').length;
items.innerHTML += '<tr><td>' +
'<input id="item-' + itemcount + '-quantity" name="item-' + itemcount + '-quantity">' +
'</td><td>' +
'<input id="item-' + itemcount + '-description" name="item-' + itemcount + '-description">' +
'</td></tr>';
}
document.querySelector('#add').addEventListener('click', addItem);
<button id="add">add item</button>
<table id="items">
</table>
You can separately reconstruct the node itself by using
createAttribute()
createElement()
Fiddle: http://jsfiddle.net/ztb9gq3d/1/
This is not the data oriented approach the question asks for, but a reasonably simple solution is
numRows = table.rows.length;
// Use a regexp so we can replace all instances of the number
// corresponding to what is currently the last table row.
var re = new RegExp((numRows - 1).toString(), "g")
for (var i = 0; i <= originalRow.cells.length - 1; i++) {
var originalHTML = originalRow.cells[i].innerHTML;
var newHTML = originalHTML.replace(re, numRows.toString());
newRow.cells[i].innerHTML = newHTML;
}
Obviously this only works if the number we replace doesn't exist elsewhere in the HTML string, so this is not a particularly good solution.
However, we could use a more complex regexp.
This solution does have the advantage that we don't need to hard-code anything except the parts we want to replace into the regexp.
Therefore, if the HTML in the table were to acquire additional parts in future development this solution will still work, up to the quality of the regexp as already mentioned.
I have a form where you can generate automatically additional form boxes and send them to be handeled at PHP-script. How ever as I am quite lousy with Javascript and I am running in the following problem.
When the form is filled out I can see everything is filled out on the URL, except the the boxes created with JS (every box has unique name!). My guess is that the JS generated field drop out of the form tags, but can not figure out how to fix this. I would appreciate if someone could give me pointers or tell me how to fix this. I shortened the code for clarity (if something got left out please tell me). If someone is wondering why I am not using the form action. It´s because drupal tries to forward the site to wrong place if I do (surprise, not too good with drupal either :D)
<?php
require_once('customer.php');
?>
<script type="text/javascript">
var intTextBox=0;
//FUNCTION TO ADD TEXT BOX ELEMENT
function addElement()
{
intTextBox = intTextBox + 1;
var contentID = document.getElementById('content');
var newTBDiv = document.createElement('div');
newTBDiv.setAttribute('id','strText'+intTextBox);
newTBDiv.innerHTML = "<div class='product'><tr><td>Sku/ID: "+intTextBox+": <input type='text' name='sku_" + intTextBox + "'/></div>";
contentID.appendChild(newTBDiv);
}
function removeElement()
{
if(intTextBox != 0)
{
var contentID = document.getElementById('content');
contentID.removeChild(document.getElementById('strText'+intTextBox));
intTextBox = intTextBox-1;
}
}
</script>
<table>
<form name="activate">
<div class='cu'>
<tr><td>Sku/ID (oma): <input type="text" name="sku"></td>
<td><p><a href="javascript:addElement();" >Add product</a>
<a href="javascript:removeElement();" >Remove product</a></p></td></tr>
<div id="content"></div>
</div>
<tr> <td><input type="submit" value="Submit"></td> </tr>
</form>
Customer.php
<?php
if(isset($_GET["sku_1"]))
{
echo "found it";
}
else
echo "did not find it";
?>
Any help would be much appreciated!
You could dynamically change the url of the form tag to include textbox values:
var textboxes = document.getElementsByTagName("input");
for (var i = 0; i < textboxes.length; i++){
var data = "?";
if (textboxes[i].type == "text") {
data += (data == "?" ? "" : "&") + textboxes[i].name + "=" + textboxes[i].value;
}
}
form.action += data;
I haven't tested this, you might have to dynamically add all elements
[UPDATE]
If you have trouble with the form you can try using an absolute path, if you aren't already.
<tbody id="contacttable">
</tbody>
<script>
var hrtypeCode = document.getElementById('hrtypeCode').value;
var hrCode = document.getElementById('hrCode').value;
var hrName = document.getElementById('hrName').value;
var hrDesc = document.getElementById('hrDesc').value;
for(i=0;i<hrCode.length; i++){
if(hrCode[i]!="") {
var table = document.getElementById("contacttable");
var slNo = table.rows.length;
var tr = table.insertRow(slNo-1);
tr.id = 'list_tr_' + slNo;
tr.innerHTML ='<td><input type="text" name="hrtypeCode" value="'+hrtypeCode[i]+'" ></td><td><input type="text" name="hrCode" value="'+hrCode[i]+ '"></td><td><input type="text" name="hrName" value="'+hrName[i]+'" ></td>';
count++;
}
}
</script>
<i>
how to find out the cell values.i have tried the following code but it showing entire TD row
tbl.rows[i].cells[j].innerHTML);
alert(tbl.rows[i].cells[j].innerHTML);
Kindly help in finding the value.. thanks.
Table cells don't have values, only input elements do. You need to access the <input> element within the table cell.
Use:
tbl.rows[i].cells[j].getElementsByTagName("input")[0].value
DEMO
This is my HTML code:
<table id="display_table"><tr>
<td>No. of Questions: </td>
<td><input type="text" id="questions_num"></td>
</tr><tr>
<td>No. of Options: </td>
<td><input type="text" id="options_num"></td>
</tr></table>
I want to make it such that when the user enters x in the text input (whose id is options_num), x rows will be created. For each new row that is created, there should be a left column and a right column. The left column will contain the "Option" + somenumber, where somenumber refers to the row that has been created, and the right column will create a text input.
This is what I have tried in my JS:
document.getElementById("options_num").onkeyup = function() {
var options_num = parseInt(document.getElementById("options_num").value);
var display_text = '<tr><td>No. of Questions: </td><td><input type="text" id="questions_num"></td></tr><tr><td>No. of Options: </td><td><input type="text" id="options_num"></td></tr>'
for(var i = 1; i <= options_num; i++) {
display_text += "<tr><td>Option " + i + ": </td><td>" + "<input type='text' id='option_" + i + "'</td></tr>";
}
document.getElementById("display_table").innerHTML = display_text;
document.getElementById("options_num").value = options_num.toString();
document.getElementById("options_num").focus();
}
And it works when I first enter a value into the text input (whose id is question_num), but when I change the value, it does not work (it does not do anything). Demo.
So how do I get my JS code to work?
The reason it doesn't work after the first time, is that innerHTML actually destroys event binding. So after you modify table.innerHTML browser completely rebuilds new DOM elements without original onkeyup event listener attached.
I would recommend to change HTML a little, it will make everything simpler:
<table id="display_table">
<tbody>
<tr>
<td>No. of Questions:</td>
<td><input type="text" id="questions_num"/></td>
</tr>
<tr>
<td>No. of Options:</td>
<td><input type="text" id="options_num"/></td>
</tr>
</tbody>
<tbody id="rows"></tbody> <!-- append generated HTML here -->
</table>
and modified JS:
document.getElementById("options_num").onkeyup = function () {
var options = document.getElementById("options_num"),
optionsNum = parseInt(options.value),
tbody = document.getElementById("rows"),
rows = '';
for (var i = 1; i <= optionsNum; i++) {
rows += "<tr><td>Option " + i + "</td><td>" + "<input type='text' id='option_" + i + "'</td></tr>";
}
tbody.innerHTML = rows;
options.focus();
}
So the idea is to put table rows into tbody and it makes easy adding new and replacing replacing old rows.
Demo: http://jsfiddle.net/8yYyW/2/