Forum Moderators: open

Message Too Old, No Replies

Append another js function on an existing onchange event

How does one add another js function dynamically

         

aliUK

8:46 am on Jan 1, 2009 (gmt 0)

10+ Year Member



Hi

I have a select list that has an onchange event and I would like to add a js function I created to this onchange event. The code is being generated from an html engine. Unfortunately, I cannot simply change the code until the page is generated.

This is the html of course there is other items above the select list.


<select id="X01_2810528943693135" onchange="$a_report_Split('2810528943693135',$v(this));" size="1" name="X01">
<option value="1_1_1">1 of 4</option>
<option value="2_1_1">2 of 4</option>
<option selected="selected" value="current">3 of 4</option>
<option value="4_1_1">4 of 4</option>
</select>

daveVk

12:02 pm on Jan 1, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You could write your own $a_report_Split that includes the old one.

var old_report_Split = $a_report_Split;
function $a_report_Split( a, b ) {
..
var r = old_report_Split( a, b );
..
return r;
}

aliUK

12:21 pm on Jan 1, 2009 (gmt 0)

10+ Year Member



that function is stored in another external js file. Can I just place the new revised one in the page header and would it overwrite the old one or would it conflict. The $a_report_Split is a function that my html engine produces.

Thanks for your help and Happy New Year!

daveVk

11:20 pm on Jan 1, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Provided it is further down the page, I think it will work Ok. If all else fails do the swap on the body onload event

var old_report_Split = $a_report_Split;
$a_report_Split = new_report_Split; // function name changed to new

Have a great New Year

[edited by: daveVk at 11:57 pm (utc) on Jan. 1, 2009]

aliUK

9:14 am on Jan 2, 2009 (gmt 0)

10+ Year Member



Hi Dave,

I tried your first one but I am getting an alert saying "Stack over flow at line:43". This line is where my new revised js function is. I've gone through the code and it seems that line is the closest to the element.

This is what I have


<script type="text/javascript">

var old_report_Split = $a_report_Split;

function findChangeSelect(){
var optionItem = new Array();
var optionItem = document.getElementsByTagName('option');

for (x in optionItem){
if (x > -1){
//alert(optionItem[x].innerHTML);
var optionText = optionItem[x].innerHTML;
if(optionText.indexOf(' - ') > 0){
//var txtReplace = optionText.substring(0,optionText.indexOf(' - '));
var txtNew = optionText.substring(optionText.indexOf(' - ')+3);
//optionText = optionText.replace(txtReplace,txtNew);
optionItem[x].text = txtNew;
}
}
}
}

function $a_report_Split(a,b){
var r = old_report_Split(a,b);
findChangeSelect();
return r;
}
</script>

Just so you know what $a_report_Split function is. The function is an ajx functin that fetches some data and replaces within the current html page so that the page is not refreshed.

Any ideas where I could be going wrong or How would I implement you other suggestion?

daveVk

11:55 am on Jan 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Three possibilties

1 - The new $a_report_Split is calling itself and causing the stack overflow
2 - findChangeSelect changes the option text and that causes the onchange to fire again
3 - the ajax code is updating or replacing this select control also

Try some debug

function $a_report_Split(a,b){
alert( 'A: ' + ( $a_report_Split === old_report_Split ) );
var r = old_report_Split(a,b);
alert( 'B: ');
findChangeSelect();
alert( 'C: ');
return r;
}

Does the ajax call replace or update the select control ?

Is the order of these 2 lines critical ?
var r = old_report_Split(a,b);
findChangeSelect();

I assume some part of the page changes when selection is made, what is your change trying to do ?

aliUK

9:57 pm on Jan 2, 2009 (gmt 0)

10+ Year Member



Hi Dave,

I replaced my js code with yours and I think it may be because it is calling itself as it does not go past the first alert and just keep alert "A: = true" in an endless loop and I had to kill the browser to escape.

The ajax call replaces a chunk of html table along with the select list. I do have some "Next" and "Previous" buttons that use my findChangeSelect() and that works perfectly as it replaces the select text after it has received it back from the ajax call. The two buttons call a different ajax function that passes the next and previous values so unfortunately I cannot reuse that.

I ruled out number 2 as I commented out the findChangeSelect() and it still went into an endless loop.

Yes the order is critical because its the values html that returned from $a_report_split that I need to replace.

Thanks for your support its most appreciated.

daveVk

1:22 am on Jan 3, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Let try a more direct approach

<script type="text/javascript">

// get control when page loads
if (window.addEventListener) {
window.addEventListener('load', pageMod, false);
} else if (window.attachEvent) {
window.attachEvent('onload', pageMod);
}

function pageMod() {
var selEl = document.getElementsByTagName('select')[0];
// if multiple selects on page change above
//
// add extra onchange stuff
if (selEl.addEventListener) {
selEl.addEventListener('onchange', findChangeSelect, false);
} else if (selEl.attachEvent) {
selEl.attachEvent('onchange', findChangeSelect );
}
}

There may be a second problem in that ajax calls typically return prior to the page update happening, findchangeSelect may be operating on the pre updated page. Also if ajax replaces select, do we need to add findChangeSelect handler each update ?

aliUK

3:38 pm on Jan 4, 2009 (gmt 0)

10+ Year Member



Hi Dave,

I think we almost there. Sorry I forgot to mention that I already had an onload event which called the findChangeSelect(). I removed it now and there are no onload events.

I placed your code into my html page. Now when the page is first loaded it does not seem to execute the findChang
eSelect(). So the select list is in the wrong format, but when I select an option from the list it retrives the data and also changes the select list which is what I want in. However it does not do it again, when I select another option it just retrieves the data and just formats the select list incorrectly. This maybe cause but the fact that it replaces the select list and so the code is lost the second time. So I guess the answer to your question is Yeah we need to add findChangeSelect to each update.

1. We need to change the code to run onload so that the user does not see the incorrect format.
2. We just need to get it to add the code to it like it does on the first page load.

This is what I have at the moment and have no other onload events:


<script type="text/javascript">

var old_report_Split = $a_report_Split;

function findChangeSelect(){
var optionItem = new Array();
var optionItem = document.getElementsByTagName('option');

for (x in optionItem){
if (x > -1){
//alert(optionItem[x].innerHTML);
var optionText = optionItem[x].innerHTML;
if(optionText.indexOf(' - ') > 0){
//var txtReplace = optionText.substring(0,optionText.indexOf(' - '));
var txtNew = optionText.substring(optionText.indexOf(' - ')+3);
//optionText = optionText.replace(txtReplace,txtNew);
optionItem[x].text = txtNew;
}
}
}
}

// get control when page loads
if (window.addEventListener) {
window.addEventListener('load', pageMod, false);
} else if (window.attachEvent) {
window.attachEvent('onload', pageMod);
}

function pageMod() {
var selEl = document.getElementsByTagName('select')[0];
// if multiple selects on page change above
//
// add extra onchange stuff
if (selEl.addEventListener) {
selEl.addEventListener('onchange', findChangeSelect, false);
} else if (selEl.attachEvent) {
selEl.attachEvent('onchange', findChangeSelect );
}
}

</script>

Thanks for your help.

daveVk

9:22 pm on Jan 4, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Good, try changes shown in red. We got off easy.

<script type="text/javascript">

// var old_report_Split = $a_report_Split;

function findChangeSelect(){
var optionItem = new Array();
var optionItem = document.getElementsByTagName('option');

for (x in optionItem){
if (x > -1){
//alert(optionItem[x].innerHTML);
var optionText = optionItem[x].innerHTML;
if(optionText.indexOf(' - ') > 0){
//var txtReplace = optionText.substring(0,optionText.indexOf(' - '));
var txtNew = optionText.substring(optionText.indexOf(' - ')+3);
//optionText = optionText.replace(txtReplace,txtNew);
optionItem[x].text = txtNew;
}
}
}
}

// get control when page loads
if (window.addEventListener) {
window.addEventListener('load', pageMod, false);
} else if (window.attachEvent) {
window.attachEvent('onload', pageMod);
}

function pageMod() {
findChangeSelect(); // fix each cycle
var selEl = document.getElementsByTagName('select')[0];
// if multiple selects on page change above
//
// add extra onchange stuff
if (selEl.addEventListener) {
selEl.addEventListener('onchange', pageMod, false);
} else if (selEl.attachEvent) {
selEl.attachEvent('onchange', pageMod );
}
}

</script>

aliUK

4:49 pm on Jan 5, 2009 (gmt 0)

10+ Year Member



THANK YOU THANK YOU THANK YOU !

It works perfectly. I can't thank you enough I've been banging my head against a wall trying to get this done. Thank you for your time and patience with this problem, I really appreciate it. I have given you reconginition in my coding script.

The data thats being returned are images how easy would it to add a fade out/fade in effect between the ajax calls. I thinking perhaps wrap a div around the image and fade it out and then fade it in when the ajax has returned.

The piece of software I'm using to code my website is called ORACLE Application Express (also called APEX or HTML DB ) if you interested to know and has the power of being built within an ORACLE database. APEX is also open Source and comes with ORACLE 10g. If you want to try and need any help just ask me thats my specialty.

Once again thanks for your help and support it is most appreciated.

daveVk

12:06 am on Jan 6, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I have managed to avoid oracle so far, working with php mysql at moment, thanks for the offer, the day may come. No experience with fading, search this site and start a new thread if questions remain.

Regards Dave

aliUK

7:29 am on Jan 6, 2009 (gmt 0)

10+ Year Member



I would not mind learning php and mysql. I'm not sure where to start on those though.

Thanks for your support.

aliUK

12:57 pm on Jan 6, 2009 (gmt 0)

10+ Year Member



Hi Dave,

Sorry to bug you but the select list dont seem to be changing in firefox 3. It works in IE but not firefox. I have a button that calls pageMod() and that works its just when you select an option from the select list that it does not update the select list.

It does change the select onload though and like I said its only when you select an option from the select list.

daveVk

9:23 pm on Jan 6, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Timing issues maybe, please try debug below and note when it fires, if html displayed is pre/post update, and if delay introduced by alert results in correct functioning.

function pageMod() {

var selEl = document.getElementsByTagName('select')[0];
alert( 'A: ' + selEl.innerHTML )
alert( 'B: ' + selEl.innerHTML )
findChangeSelect(); // fix each cycle

// if multiple selects on page change above
//
// add extra onchange stuff
if (selEl.addEventListener) {
selEl.addEventListener('onchange', pageMod, false);
} else if (selEl.attachEvent) {
selEl.attachEvent('onchange', pageMod );
}
}