SitePoint Sponsor

User Tag List

Results 1 to 11 of 11
  1. #1
    SitePoint Guru
    Join Date
    Nov 2005
    Location
    Midwest
    Posts
    777
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Prevent Events from OnClick Event

    Hello all

    I am trying to get some JavaScript to work where I am passing an object as the function parameter. This part of the code works well. Now what I am trying to do is prevent other events from firing once this href is clicked. My situation is I have a table row that has an onlick event. Part of the data in the table row contains an href. If the user clicks this href, I do not want to table rows onclick event to fire.
    In the past, if I included the few lines of code below, it would prevent other events from firing. I tried adding this code to a condition where I am dynamically building the onclick event for the href but it is not working. Both events fire but I only want the events from the Test1 and Test2 links to fire. I do not want the TR event that displays “Display Message” to alert the user.

    Any feedback on what I am doing wrong here? Attached is an example.

    Thank you in advance for your time.

    Code:
    <html>
    <head>
        <title>Test</title>
        <script type="text/javascript">
    	
    	function objectX() {
    		var foo = "";
    		
    		this.setFoo = function( newFoo ) {
    			foo = newFoo; 
    		};
       	
    		this.getFoo = function() {
    			return foo;
    		};
    	}
    
    	function testObj() {
    		var content = document.getElementById('content');
    		content.innerHTML = '<table><tr onClick="javascript:displayMessage();"><td><a href="#" id="Test1">Test 1</a></td><td><a href="#" id="Test2">Test 2</a></td></tr></table>';
    		
    		for( var i = 1; i < 3; i++ ) {
    			var obj = new objectX();
    			obj.setFoo( "Test " + i );
    
    			// pass obj as an argument and receive it as a parameter
    			// in order to keep a private reference to its current value
    			document.getElementById("Test" + i).onclick = createTestClickHandler( "href", obj );
    		}
    	}
    	
    	function createTestClickHandler( event, obj ) {
    		return function () {
    			//-- Cross browser way to get event
    			var evt = event || window.event;
    			//-- Causes events to buggle up, a href goes first
    			evt.stopPropagation ? evt.stopPropagation() : evt.cancelBubble = true;
    			//-- Prevents other events from firing
    			evt.preventDefault ? evt.preventDefault() : evt.returnValue = false;
    			
    			alert( "event: " + evt );
    			
    			testPassObj(obj);
    		};
    	}
    	
    	function testPassObj( obj ) {
    		alert( "object: " + obj.getFoo() ); 
    	}
    	
    	function displayMessage() {
    		alert( "Display Message" );
    	}
        
        </script>
    </head>
    <body onLoad="testObj();">
    	<div id="content"></div>
    </body>
    </html>

  2. #2
    Grüße aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,938
    Mentioned
    214 Post(s)
    Tagged
    12 Thread(s)
    Hi there,

    You are very nearly there, just a simple matter of four brackets.

    Change this:

    Code JavaScript:
    function createTestClickHandler( event, obj ) {
      return function () {
        //-- Cross browser way to get event
        var evt = event || window.event;
        //-- Causes events to buggle up, a href goes first
        evt.stopPropagation ? evt.stopPropagation() : evt.cancelBubble = true;
        //-- Prevents other events from firing
        evt.preventDefault ? evt.preventDefault() : evt.returnValue = false;
        alert( "event: " + evt );
        testPassObj(obj);
      };
    }

    into this:

    Code JavaScript:
    function createTestClickHandler( event, obj ) {
      return function () {
        //-- Cross browser way to get event
        var evt = event || window.event;
        //-- Causes events to buggle up, a href goes first
        evt.stopPropagation() ? evt.stopPropagation() : evt.cancelBubble = true;
        //-- Prevents other events from firing
        evt.preventDefault() ? evt.preventDefault() : evt.returnValue = false;
        alert( "event: " + evt );
        testPassObj(obj);
      };
    }

    Notice the brackets after evt.stopPropagation and evt.preventDefault in the ternary conditionals.

    HTH

  3. #3
    SitePoint Guru
    Join Date
    Nov 2005
    Location
    Midwest
    Posts
    777
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you for the response... when I add brackets to evt.stopPropagation() and evt.preventDefault(), I get a JavaScript error stating evt.stopPropagation is not a function. I am using FireFox to test. I will continue researching but appreciate feedback if someone sees a silly mistake that I am making.

  4. #4
    Grüße aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,938
    Mentioned
    214 Post(s)
    Tagged
    12 Thread(s)
    Oh, I didn't test on FF, but would be surprised if it didn't work. I'll check it out in a bit.

  5. #5
    Grüße aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,938
    Mentioned
    214 Post(s)
    Tagged
    12 Thread(s)
    Hi,

    Just tested on Firefox (latest version).
    When I click on either "Test 1" or "Test 2", I see a "Display Message" alert which is fired by this <tr onClick="javascript:displayMessage();">.
    Which is what I was thinking was meant to happen due to this line here: evt.preventDefault() ? evt.preventDefault() : evt.returnValue = false;

  6. #6
    SitePoint Guru
    Join Date
    Nov 2005
    Location
    Midwest
    Posts
    777
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    No, I do not want to TR onclick event to fire. With this example, I know it looks weird. I have a multi row TR and some of the data in the TR are HREFs so if the user clicks on the HREF, I do not want the TR onclick event to fire. So I only want the Test1 or Test2 messages to display, not Display Message. Sorry I made this confusing.

  7. #7
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,813
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    <tr onClick="javascript:displayMessage();">.
    Is there some particular reason why onclick has been spelt incorrectly with an uppercase C and why there is a JavaScript label that never gets referenced from anywhere in front of the actual JavaScript command.

    If you are going to jumble the JavaScript in with the HTML instead of placing it all together in a separate JavaScript file then at least write it properly:

    Code:
    <tr onclick="displayMessage();">

    Also the code to prevent other events firing is more likely to work if you attach the events from within the JavaScript as event listeners rather than hard coding them in the HTML as event handlers.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  8. #8
    Grüße aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,938
    Mentioned
    214 Post(s)
    Tagged
    12 Thread(s)
    Hi,

    I know I'm probably missing some use case in your application, but the following code would do what you want.

    Code JavaScript:
    function objectX() {
      var foo = "";
     
      this.setFoo = function( newFoo ) {
        foo = newFoo; 
      };
     
      this.getFoo = function() {
        return foo;
      };
    }
     
    function testObj() {
      var content = document.getElementById('content');
      content.innerHTML = '<table><tr onclick="javascript:displayMessage();"><td><a href="#" id="Test1">Test 1</a></td><td><a href="#" id="Test2">Test 2</a></td></tr></table>';
     
      for( var i = 1; i < 3; i++ ) {
        var obj = new objectX();
        obj.setFoo( "Test " + i );
     
        document.getElementById("Test" + i).onclick = function(e){
          testPassObj(obj);
          if(e && e.stopPropagation) {
            e.stopPropagation();
          } else {
            e = window.event;
            e.cancelBubble = true;
          }
        }
      }
    }
     
    function testPassObj( obj ) {
      alert( "object: " + obj.getFoo() ); 
    }
     
    function displayMessage() {
      alert( "Display Message" );
    }

    As far as I could see, the trouble was coming from passing in "href" as a parameter to the 'createTestClickHandler' method.
    This is a string and does not respond to stopPropagation

  9. #9
    SitePoint Guru
    Join Date
    Nov 2005
    Location
    Midwest
    Posts
    777
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It works!!! Your post triggered a thought in my mind and I was misplacing where to include the event parameter. The code I posted is calling a function to return the code for another function. Event needed to be added in the function that was being called by the onclick event.

    Thank you for the feedback!!!

    Here is what I mean (notice event was added as a parameter for the function):
    Code:
    return function (event) {
    //-- Cross browser way to get event
    	var evt = event || window.event;
    	alert( "event: " + evt );
    			
    	//-- Causes events to buggle up, a href goes first
            evt.stopPropagation() ? evt.stopPropagation() : evt.cancelBubble = true;
    	//-- Prevents other events from firing
    	evt.preventDefault() ? evt.preventDefault() : evt.returnValue = false;
    			
    	testPassObj(obj);
    };
    Here is the complete code.
    Code:
    <html>
    <head>
        <title>Test</title>
        <script type="text/javascript">
    	
    	function objectX() {
    		var foo = "";
    		
    		this.setFoo = function( newFoo ) {
    			foo = newFoo; 
    		};
       	
    		this.getFoo = function() {
    			return foo;
    		};
    	}
    
    	function testObj() {
    		var content = document.getElementById('content');
    		content.innerHTML = '<table><tr onClick="javascript:displayMessage();"><td><a href="#" id="Test1">Test 1</a></td><td><a href="#" id="Test2">Test 2</a></td></tr></table>';
    		
    		for( var i = 1; i < 3; i++ ) {
    			var obj = new objectX();
    			obj.setFoo( "Test " + i );
    
    			// pass obj as an argument and receive it as a parameter
    			// in order to keep a private reference to its current value
    			document.getElementById("Test" + i).onclick = createTestClickHandler( obj );
    		}
    	}
    	
    	function createTestClickHandler( obj ) {
    		return function (event) {
    			//-- Cross browser way to get event
    			var evt = event || window.event;
    			alert( "event: " + evt );
    			
    			//-- Causes events to buggle up, a href goes first
    			evt.stopPropagation() ? evt.stopPropagation() : evt.cancelBubble = true;
    			//-- Prevents other events from firing
    			evt.preventDefault() ? evt.preventDefault() : evt.returnValue = false;
    			
    			testPassObj(obj);
    		};
    	}
    	
    	function testPassObj( obj ) {
    		alert( "object: " + obj.getFoo() ); 
    	}
    	
    	function displayMessage() {
    		alert( "Do not display this message" );
    	}
        
        </script>
    </head>
    <body onLoad="testObj();">
    	<div id="content"></div>
    </body>
    </html>

  10. #10
    Grüße aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,938
    Mentioned
    214 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by TryingToLearn View Post
    It works!!! Your post triggered a thought in my mind and I was misplacing where to include the event parameter. The code I posted is calling a function to return the code for another function. Event needed to be added in the function that was being called by the onclick event.
    Hey, cool!
    I'm glad you got things working.
    Thanks, too, for taking the time to follow up.

  11. #11
    SitePoint Guru
    Join Date
    Nov 2005
    Location
    Midwest
    Posts
    777
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by felgall View Post
    Also the code to prevent other events firing is more likely to work if you attach the events from within the JavaScript as event listeners rather than hard coding them in the HTML as event handlers.
    Felgall, I am sorry I missed your comment earlier. I was hoping you could expand on your comments in regards to attaching the events within the JavaScript as event listeners rather than hard coding them in the HTML as event handlers. How would I do that?


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •