3

I know, there are several posts with nearly the same question, but all the mentioned "fixes" dont work for me.

but first, here is what I need: Some forms in my application have to be enabled by activating an edit mode. If the edit mode is active every button (except save and abort) and link on the page should not do what it normaly does, but it should give a message that you have to end the edit mode instead.

My script: The button to start the edit mode calls this:

    function startEditMode(selector) {
            var disableAction = "return false;";
            jQuery("mySelectors").each(function(){
                    jQuery(this).bind('click', editModeOnClickHandler);
                    var onClickValue = "";
                    var onClick = jQuery(this).attr("onClick");
                    if ( onClick !== undefined ) onClickValue = "" + onClick;
                    jQuery(this).attr("onClick", disableAction + onClickValue);
            });
    }

To stop edit mode a method exists which reverses all of this. The used handler "editModeOnClickHandler" just shows the message and returns false; and is not important to my question.

So.. everything works fine in FF and IE8 (also in Chrome) but it does not in IE7. The onClick is simply not modified in IE7 via .attr as I read in other postings.

the solution which is posted everywhere: Use event binding instead of manipulating attributes. I wish I can use that!

Here is the reason why I cant: I tried to unbind all handlers and bind my own handler as you see in code above. But this does not prevent the inline onclick from being called. Okay you might think, dont use inline calls.. but my project is written in JSF using Primefaces and most of its code is generated dynamically. All in all I do not have the possibility to prevent inline onclicks.

Now I am stuck. I have to handle with inline onclicks which can only be prevented to be called by inserting a "return false;" in front, but this seems not to be possible with IE7.

Does anyone know a IE7 workaround to be able to manipulate the onclick attributes? And again: I can not use .bind('click'... or .click( because they are not able to stop the original inline onclick.

Thanks for all answers! Alex

edit with your help I figured out, that in IE7 changing the inline onclick is possibile with this.onclick = ... The correct handling of this was alreads answered in this question: How to change onClick handler dynamically?

For my concrete problem here I found no proper solution, because I was not able to manipulate the original inline onclick values without destoying them. For that reason I changed my script, so IE7 disables all buttons and links to make sure they are no longer clickable. To be sure, not to enable too much, ill add a classname too.

disabling all not yet disabled (its called in a loop):

if (!jQuery(this).attr('disabled')) {
    jQuery(this).attr('disabled', 'disabled');
    jQuery(this).addClass('editmodedisabled');
}

enable my previous disabled things:

if (jQuery(this).hasClass('editmodedisabled')) {
    jQuery(this).attr('disabled', '');
    jQuery(this).removeClass('editmodedisabled');
}

maybe this helps anyone else

Community
  • 1
  • 1
Allanon
  • 401
  • 5
  • 13
  • 1
    Why did you capitalize the C in attr('onClick')? Also this could be helpfull in your case `var clickEvents = $(element).data("events").click; $.each(clickEvents, function(key, handlerObj) { .. }` – Robert de W Jul 18 '11 at 18:10
  • thanks for your comment: 1. I capitalitzed C because for some reason IE8 wont remove my added return false; without the C :( 2. I also tried with data("events") but the inline onclick seems not to be part of this. Ill give it another try. – Allanon Jul 19 '11 at 06:53

4 Answers4

5

I've came across the same problem with JSF and PrimeFaces as you. Here is my solution for this problem.

You can disable inline functions and restore them as you wish:

// get the element with jQuery
var element = $('#someId');

// get the current inline onclick function. This works under all browsers. 
var originalInlineClickHandler = element[0].onclick;

// define new click event which will replace the old one.
var click = function () {
    alert('You clicked me!');
}

// replace the old "onclick" event with the new one or in other words disable the click 
element[0].onclick = click;

// Now when clicking #someId element the new function will be executed and only it (the "click" function).
// Original inline function is gone already and those it will not be executed.

// Restore original inline function - a.k.a. enable the click event
element[0].onclick = originalInlineClickHandler.

This approach works under all browsers. The thing is that all modern browsers change element[0].onclick when you change element.attr('onclick', callback); (meaning that element[0].onclick = eval(element.attr('onclick')) or something similar), but not IE <= IE 7. However if you change element[0].onclick property without even changing the onclick attribute will work under all browsers. In this case onclick attribute doesn't correspond to the real event handler. To keep onclick attribute and property in sync under all browsers the following line could be added:

// define new click event which will replace the old one.
var click = function () {
    alert('You clicked me!');
    return false;
}

// update the onclick attribute of the element. Under most browsers this will update and onclick property of the DOM element.
element.attr('onclick', click.toString());

// replace the old "onclick" event with the new one or in other words disable the click 
element[0].onclick = click;
blue112
  • 52,634
  • 3
  • 45
  • 54
1

You can get the inline onclick like this: var inlineHandler = this.onclick;

function startEditMode(selector) {
        var disableAction = "return false;";
        jQuery("mySelectors").each(function(){
                jQuery(this).bind('click', editModeOnClickHandler);
                var onClickValue = "";
                var onClick = this.onclick;
                if ( onClick !== undefined ) onClickValue = "" + onClick;
                jQuery(this).attr("onClick", disableAction + onClickValue);
        });
}
Mrchief
  • 75,126
  • 20
  • 142
  • 189
  • Thanks for your post @Mrchief! That partly did the trick .. Getting the value was not the problem, its the setting, but with `this.onclick = newvalue;` I was able to modify the inline onclick in IE7 as well. But now I'am pointing to another problem. Adding and removing of return false; works, but both versions to get the value, return a wrapped function in IE7 like this: `function anonymoues() { here is the real onclick }`. Adding this as a string to the onclick value may obviously break it. – Allanon Jul 19 '11 at 08:40
  • FYI: with `this.getAttributeNode('onclick')` you get onclick value without a wrapper, but I found no correct way to change this.onclick without destoying the old js.. because I cant find a way to do so, I changed my script and in case of IE7 i'll disable all buttons and links. Too bad I have to live now with the IE7 disabled stylings :( – Allanon Jul 19 '11 at 13:13
  • 1
    Damn interesting, @Allanon. Its good thing the world will soon be away from IE7. – Mrchief Jul 19 '11 at 14:19
0

had the same problem, but pure href="javascript:some_js_function_without_returning_false();" resolved it. I know it's not the solution to onclick, but in some cases may help.

0

This is a known issue with IE7.

Have you tried this workaround?

Alternatively, I have also heard it may be as simple as using IE's proprietary event.returnValue as a workaround, but cannot verify this works.

Here's what part of your code would be changed to:

var disableAction = "event.returnValue = false; return false;";
namuol
  • 9,816
  • 6
  • 41
  • 54
  • Thanks for you comment @namuol! As far as I found out, return false; in a links inline onclick does prevent the defaultbehaviour in IE7, my problem is/was that I cant modify it directly. The method mentioned in the link just adds a new event and I agree that this way, the default action is still called. I also found the event.returnValue thing a couple of times by my searches, but that did not make the clue, because, as I said, I was not able to modify the onclick, my script was just not able to update inline onclick in the DOM in IE7. – Allanon Jul 19 '11 at 08:42