PDA

View Full Version : Change Script To Recognize Id Not Name



atclt37
11-02-2010, 11:13 PM
I have a script that is written based on the name and I would like to change it based on the id. I've tried simply switching getElementsByName to getElementById plus changing name to id where appropriate without luck. IE tells me "object doesn't support this property or method" and FF tells me "getElementByID is not a function" when I do that.

How is the best way to approach rewriting this script for Id?



function initFillDown() {
var aObj = document.getElementsByTagName('input');
var i = aObj.length;
while(i--) {
if(aObj[i].type=='text') {
aObj[i].onchange = function() {lastChoice(this.name);};
}
else {
aObj[i].onclick = function() {fillDown(this);};
}
}
};

function lastChoice(ref) {
var needle = /grade(\d+)_(\d+)$/i;
ref.match(needle);
down[(RegExp.$2)] = RegExp.$1;
}

var down = [];
function fillDown(obj) {
// button column
var aObj = document.getElementsByName('copy');
var len = aObj.length;
for(var i=0; i<len; i++) {
if(aObj[i]==obj) {
var col = i;
break;
}
}
// fill
var aObj = document.getElementsByTagName('input');
var len = aObj.length;
var idx = down[col];
var lastName = 'grade'+idx+'_'+col;
var val = document.getElementsByName(lastName)[0].value;
for(var i=0, count=0; i<len; i++) {
if(aObj[i].name==lastName) {
aObj[i].value = val;
lastName = 'grade'+(++idx)+'_'+col;
}
}
}

Nile
11-02-2010, 11:16 PM
Can you tell me what exactly this script does? Thanks

atclt37
11-03-2010, 12:26 AM
Sure, it takes the value of a textbox and places that value in all the textboxes below it. The textboxes are arranged in columns by divs (not a table).

Here's a link to the code working using the name attribute:
http://bftrs2.mainvista.com/test/test3.html

I'd like to rewrite it to use the id attribute instead. I'd use the same naming system for id's as I used for names. The reason I'm wanting to switch to id is the name will now be populated with data brought in with php and not using the same sequential naming system.

I tried switching name for id here but it didn't work:
http://bftrs2.mainvista.com/test/reworkFillDown.html

Any ideas on how to approach this? I'm thinking that because getElementsByName produces an array like collection and getElementById is a single element that may be the cause of the problem, but am not sure how to fix it.

Thanks!

Nile
11-03-2010, 12:30 AM
The reason it doesnt work is because getElementById is ment to get one element, and not an array of elements. Is it possible that you could just add another class to it - and use getElementsByClassName? Give it a try.

atclt37
11-03-2010, 01:00 AM
Thanks for the suggestion. I gave it a try and am getting 2 errors and the script isn't functioning. The errors are:
"ref is undefined" and "document.getElementsByClassName(lastName)[0] is undefined'

The rewritten script is here:
[BROKEN LINK REMOVED]


So with the name attribute it was taking the regular expression to locate which input textbox had the last inputted value and which ones below it that needed to have that value added to them. Now with the class attribute that part seems to be broken.

Any more ideas? I'm at a loss right now, I think I've been staring at it too much =)

Nile
11-03-2010, 02:05 AM
The link you provided is to your local drive

Also - make sure that the class actually exists (in case you didnt know: classes are seperated by spaces, e.g class="el_34 name blah"


Cant you play around with something as simple as:


<script type="text/javascript">
var copyall = function(cl){
cl = document.getElementsByClassName(cl);
for(var i = 1; i < cl.length; i++){
cl[i].value = cl[0].value;
}

};
</script>
Class aa: <input type="text" class="aa" /><input type="button" value="Copy all" onclick="copyall('aa');" /><br />
Class ab: <input type="text" class="ab" /><input type="button" value="Copy all" onclick="copyall('ab');" /><br />
Class ac: <input type="text" class="ac" /><input type="button" value="Copy all" onclick="copyall('ac');" /><br />
Class aa: <input type="text" class="aa" /><br />
Class ab: <input type="text" class="ab" /><br />
Class ac: <input type="text" class="ac" />

atclt37
11-03-2010, 03:26 PM
That's very similar to what I had using name:

Worked using Id:


function initFillDown() {
var aObj = document.getElementsByTagName('input');
var i = aObj.length;
while(i--) {
if(aObj[i].type=='text') {
aObj[i].onchange = function() {lastChoice(this.name);};
}
else {
aObj[i].onclick = function() {fillDown(this);};
}
}
};

function lastChoice(ref) {
var needle = /points(\d+)_(\d+)$/i;
ref.match(needle);
down[(RegExp.$2)] = RegExp.$1;
}

var down = [];
function fillDown(obj) {
// button column
var aObj = document.getElementsByName('copy');
var len = aObj.length;
for(var i=0; i<len; i++) {
if(aObj[i]==obj) {
var col = i;
break;
}
} // fill
var aObj = document.getElementsByTagName('input');
var len = aObj.length;
var idx = down[col];
var lastName = 'points'+idx+'_'+col;
var val = document.getElementsByName(lastName)[0].value;
for(var i=0, count=0; i<len; i++) {
if(aObj[i].name==lastName) {
aObj[i].value = val;
lastName = 'points'+(++idx)+'_'+col;
}
}
}


I switched it around using ClassName but haven't had any luck getting it to run. I do have the class separated by a space as you suggested:
class='text_field points5_0'

Using ClassName:


function initFillDown() {
var aObj = document.getElementsByTagName('input');
var i = aObj.length;
while(i--) {
if(aObj[i].type=='text') {
aObj[i].onblur = function() {lastChoice(this.class);}; // changed this.name to this.class
} else {
aObj[i].onclick = function() {fillDown(this);};
}
}
};

function lastChoice(ref) {
var needle = /points(\d+)_(\d+)$/i;
ref.match(needle);
down[(RegExp.$2)] = RegExp.$1;
}

var down = [];
function fillDown(obj) {
// button column
var aObj = document.getElementsByName('copy');
var len = aObj.length;
for(var i=0; i<len; i++) {
if(aObj[i]==obj) {
var col = i;
break;
}
}
// fill
var aObj = document.getElementsByTagName('input');
var len = aObj.length;
var idx = down[col];
var lastName = 'points'+idx+'_'+col;
var val = document.getElementsByClassName(lastName)[0].value; // changed document.getElementsByName to document.getElementsByClassName for(var i=0, count=0; i<len; i++) {
if(aObj[i].class==lastName) { // changed aObj[i].name to aObj[i].class
aObj[i].value = val;
lastName = 'points'+(++idx)+'_'+col;
}
}


When I use ClassName I'm still getting the errors "ref is undefined" and "document.getElementByClassName(lastName)[0] is undefined"

This is the part I hate the most, debugging when I'm out of ideas =(

atclt37
11-03-2010, 06:41 PM
Success! Finally able to get the script running using the id attribute! It was a simple matter of removing the [0] array thingy at the end of one line of code since we were dealing with single elements vs. a collection.

So now I have a functioning script and I understand how it works. Ahh, life is good again.

Here's the working code using id if you're interested:



/* Fill Down */
function initFillDown() {
var aObj = document.getElementsByTagName('input');
var i = aObj.length;
while(i--) {
if(aObj[i].type=='text') { // onchange to onblur (some instances onchange wasn't allowing a 0 as a value)
aObj[i].onblur = function() {lastChoice(this.id);}; // changed this.name to this.id
} else {
aObj[i].onclick = function() {fillDown(this);};
}
}
};

function lastChoice(ref) {
var needle = /points(\d+)_(\d+)$/i;
ref.match(needle);
down[(RegExp.$2)] = RegExp.$1;
}

var down = [];
function fillDown(obj) {
// button column
var aObj = document.getElementsByName('copy');
var len = aObj.length;
for(var i=0; i<len; i++) {
if(aObj[i]==obj) {
var col = i;
break;
}
}
// fill
var aObj = document.getElementsByTagName('input');
var len = aObj.length;
var idx = down[col];
var lastName = 'points'+idx+'_'+col;
var val = document.getElementById(lastName).value; // changed document.getElementsByName[0] to document.getElementsById
for(var i=0, count=0; i<len; i++) {
if(aObj[i].id==lastName) { // changed aObj[i].name to aObj[i].id
aObj[i].value = val;
lastName = 'points'+(++idx)+'_'+col;
}
}
}
/* End Fill Down */

Nile
11-03-2010, 11:33 PM
No problem, I'm glad to help.

Here on DD, we like to keep things organized. In an effort to do so, you have the option to set a thread to resolved when an issue is fixed. To make the status of the thread resolved:
1. Go to your first post
2. Edit your first post
3. Click "Go Advanced"
4. In the dropdown next to the title, select "RESOLVED"