1. #1
    Ext User
    Join Date
    May 2007
    Posts
    13
    Vote Rating
    0
    DanielD is on a distinguished road

      0  

    Default Adding listeners to all the links inside a grid

    Adding listeners to all the links inside a grid


    When the grid widget is rendered, but I have custom renderer for the column that spits out some normal <a href> links. I'd like to be able to select all these links for the entire grid and add listeners to them, but I've run out of solutions and need some fresh minds to look at it.

    1) ATTEMPT ONE: Before the column renderer returns its string, throw the markup in an Element() and add the event. However, Element() constructor doesn't seem to just take in markup. The markup must already be rendered by the browser, then you use Ext.get() to create the element from it.

    2) ATTEMPT TWO: Use the 'render' event for the grid to scan the contents of grid.container.dom.innerHTML for links, create Elements, and add listens. However, it appears that the 'render' event is actually called just before the markup is rendered to the page. Here is the code I'm using:

    Code:
    var grid = new Ext.grid.Grid('clients-grid', {
            ds: ds,
            cm: cm,
            selModel: new Ext.grid.RowSelectionModel({singleSelect:true}),
            monitorWindowResize: true,
            //autoSizeColumns: true,
            loadMask: true,
            autoWidth: true,
            autoHeight: true,
            listeners: {
            	// seems to be called right before grid markup is actually posted to the page
            	'render' : function(grid) {
            		//alert("grid rendered");
            		Ext.select('a[rel!="external"]',false,grid.container.dom.innerHTML).on('click', grid.handleLinks, grid, {preventDefault: true});
            	}
            },
            handleLinks : function () {
            	alert("blah");
            }
        });
    Other suggests how to do this? I'm probably missing something simple.

  2. #2
    Ext User
    Join Date
    May 2007
    Posts
    13
    Vote Rating
    0
    DanielD is on a distinguished road

      0  

    Default


    The above code does work to attach to every OTHER link on the page, but those in the grid. Haha.

  3. #3
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,502
    Vote Rating
    48
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    Add a handler for the Grid's click event.

    Then get the event's target using

    Code:
        var t = Ext.get(e.getTarget());
    Then use

    Code:
        var t = t.findParent('a[rel="external"]');
        if (t) {
            // the item clicked on was an <a rel="external"> or a descendant of one.
        }
    http://extjs.com/deploy/ext-1.1-beta...tml#findParent

  4. #4
    Ext User
    Join Date
    May 2007
    Posts
    13
    Vote Rating
    0
    DanielD is on a distinguished road

      0  

    Default


    Thanks for the reply. Definitely a more promising direction that where I was heading.

    I've implemented the code and it works algorithmically, but the target that comes back is always a random <div> or <li> in the grid markup and not the <a> tag I clicked on (verified using Firebug). Very odd. Clicking on the same link grabs a different random target each time.

    I can highlight the <a> tag correctly using Firebug's Inspect option.

    Code:
    listeners: {
            	'click' : function(e) {
            		var eventTarget = Ext.get(e.getTarget());
            		var linkTarget = eventTarget.child('a[rel!="external"]');
            		if(linkTarget == null) {
            			linkTarget = eventTarget.findParent('a[rel!="external"]');
            		}
            		if(linkTarget != null) {
            			DAXUI.Application.handleLinks(e,linkTarget);
            			//linkTarget.on('click', grid.handleLinks, grid, {preventDefault: true})
            			e.stopEvent();
            		}
            	}
           }
    Any suggestions?

  5. #5
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,502
    Vote Rating
    48
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    You don't need the child() call.

    The findParent() call asks it to track up the parentNode axis (but starting at this node) until it finds an element where the "rel" attribute != "external". Is that what you want?

  6. #6
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,502
    Vote Rating
    48
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    Obviously, you'd need a custom renderer to render an <a rel="external"> element into any Grid cells you wanted to be clickable.

  7. #7
    Ext User
    Join Date
    May 2007
    Posts
    13
    Vote Rating
    0
    DanielD is on a distinguished road

      0  

    Default


    Quote Originally Posted by Animal View Post
    The findParent() call asks it to track up the parentNode axis (but starting at this node) until it finds an element where the "rel" attribute != "external". Is that what you want?
    Our JSPs are rendered normally and work normally without any Javascript. Then EXT (if the user has JS) finds all the links, forms, and other objects on the page to "enhance" if you will. This includes adding a BorderLayout to the page. Thus all links that are NOT marked as "external" will actually just change the panel and not the page (if JS if active; if not, the link works normally to change the page).

    Thus, I'm trying to grab all the links in a grid and add listeners that override them with a click event to make them change the panel and not go to another page.

    But I just realized that I think that I'm trying to solve this problem the wrong way. I should just go ahead and make the links call JS directly since the user will have JS if they're viewing the Grid.

    Here's to making things more complicated than need be! Thanks for humoring me.

  8. #8
    Ext User
    Join Date
    May 2007
    Posts
    13
    Vote Rating
    0
    DanielD is on a distinguished road

      0  

    Default


    here's the code that worked for me

    Code:
    // Get all the links in the new panel and override 'em.
    var links = Ext.select('#'+gridPanel.getId()+' a[rel!="external"]');
    links.on('click', this.handleLinks, this, {preventDefault: true});
    called after the gird panel is added

  9. #9
    Ext User
    Join Date
    May 2007
    Posts
    13
    Vote Rating
    0
    DanielD is on a distinguished road

      0  

    Default Here's a weird one

    Here's a weird one


    So the follow works as it's suppose to. I know because when I've stepped through it in Firebug, the resulting links in the grid work fine.

    Code:
    this.layout.beginUpdate();
           		
    var gridPanel = new Ext.GridPanel(grid, { fitToFrame: true });
    // Get all the links in the new panel and override 'em.
    var links = Ext.select('#'+gridPanel.getId()+' a[rel!="external"]',gridPanel.getEl().dom);
    links.on('click', this.handleLinks, this, {preventDefault: true});
    	        
    !cache ? gridPanel.on('deactivate', destroyPanel, this) : '';
    this.layout.add(MAIN_REGION, gridPanel);  
    this.layout.endUpdate();
    However, when I don't step through it in Firebug (no breakpoint), it's like the listeners are not attached because each link loads a new page instead of a new panel. They are not overridden or handled by the handleLinks function. It's as if the two bolded lines are just skipped over.

    Any ideas? It works everytime if I put a breakpoint there.

  10. #10
    Sencha User
    Join Date
    Mar 2007
    Posts
    7,854
    Vote Rating
    4
    tryanDLS is on a distinguished road

      0  

    Default


    Where is your ds.load in relation to that code? load is async, so if you set a BP, it may have a chance to complete and actually allow the grid to build its rows. If you don't set a BP, the grid may not have built anything yet, so there's nothing to attach. You should probably do that in a handler for the gridview's refresh event so that you know the rows have been rendered.