1. #1
    Sencha User
    Join Date
    Sep 2010
    Location
    Munich, Germany
    Posts
    5
    Answers
    1
    Vote Rating
    0
    Zyrix is on a distinguished road

      0  

    Default Answered: Call custom function in Group Header Template

    Answered: Call custom function in Group Header Template


    I use custom renderers in my grid to display data I get from another store.

    One of them is:

    Code:
    function genre_name(val) {
        return genres.queryBy(function(rec) {
            return rec.data.id == val;
        }).get(0).get('genre');
    }
    Now I'm grouping my store of the grid and trying to customize the group titles:

    Code:
    var groupingFeature = Ext.create('Ext.grid.feature.Grouping', {
        groupHeaderTpl: 'Genre: {[genre_name({name})]}'
    });
    However I get an error: Uncaught SyntaxError: Unexpected identifier

    Even if I enter the parameter directly in the template like this

    Code:
    var groupingFeature = Ext.create('Ext.grid.feature.Grouping', {
        groupHeaderTpl: 'Genre: {[genre_name(1)]}'
    });
    I get another error: Uncaught ReferenceError: genre_name is not defined

    Why is it not possible to call the function genre_name() although it's being called by the grid for the renderer function for each column. Or is there any way I can access the values generated by the renderer function of the grid?

  2. Taking these one at a time.

    First, this:

    Code:
    function genre_name(val) {
        return genres.queryBy(function(rec) {
            return rec.data.id == val;
        }).get(0).get('genre');
    }
    I assume genres is a store?

    For the line rec.data.id, generally it is bad practice to access a field through the data property, use rec.get('id') instead.

    Using queryBy seems excessively complicated for finding a single record. Would it not be easier just to use findRecord?

    Code:
    function genre_name(val) {
        return genres.findRecord('id', val).get('genre');
    }
    Assuming id is the idProperty for your model, it would probably be even easier to use getById.

    Code:
    function genre_name(val) {
        return genres.getById(val).get('genre');
    }
    Next, this:

    Code:
    {[genre_name({name})]}
    The code inside {[...]} will just be run as JavaScript, no substitutions can be made. This is why you get that error as {name} isn't valid JavaScript.

    Inside a {[...]} block you have access to a number of useful variables such as values and parent. Take a look at the docs for XTemplate for more information:

    http://docs.sencha.com/ext-js/4-0/#!/api/Ext.XTemplate

    Next up, this one:

    Code:
    {[genre_name(1)]}
    If genre_name is a global function then this will work fine. Given the error you're seeing I can only conclude that genre_name isn't global and that your grid is in the right scope to see it. This is actually a good thing, you shouldn't have globals without a suitable namespace.

    To call a formatting function you have a few options. One option is to save it in the formats namespace:

    Code:
    Ext.util.Format.genre_name = function() {
        ...
    };
    The reason for doing this is that formats have a special syntax within templates:

    Code:
    {name:genre_name}
    An alternative is to save the function on the template itself:

    Code:
    groupHeaderTpl: Ext.create('Ext.XTemplate', 'Genre: {name:this.genre_name}', {
        genre_name: function(val) {
            ...
        }
    });
    Personally I'd usually go for this last option but if your formatting function is used throughout your application then saving it to Ext.util.Format would make it much easier to share it.

  3. #2
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,580
    Answers
    540
    Vote Rating
    314
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    Taking these one at a time.

    First, this:

    Code:
    function genre_name(val) {
        return genres.queryBy(function(rec) {
            return rec.data.id == val;
        }).get(0).get('genre');
    }
    I assume genres is a store?

    For the line rec.data.id, generally it is bad practice to access a field through the data property, use rec.get('id') instead.

    Using queryBy seems excessively complicated for finding a single record. Would it not be easier just to use findRecord?

    Code:
    function genre_name(val) {
        return genres.findRecord('id', val).get('genre');
    }
    Assuming id is the idProperty for your model, it would probably be even easier to use getById.

    Code:
    function genre_name(val) {
        return genres.getById(val).get('genre');
    }
    Next, this:

    Code:
    {[genre_name({name})]}
    The code inside {[...]} will just be run as JavaScript, no substitutions can be made. This is why you get that error as {name} isn't valid JavaScript.

    Inside a {[...]} block you have access to a number of useful variables such as values and parent. Take a look at the docs for XTemplate for more information:

    http://docs.sencha.com/ext-js/4-0/#!/api/Ext.XTemplate

    Next up, this one:

    Code:
    {[genre_name(1)]}
    If genre_name is a global function then this will work fine. Given the error you're seeing I can only conclude that genre_name isn't global and that your grid is in the right scope to see it. This is actually a good thing, you shouldn't have globals without a suitable namespace.

    To call a formatting function you have a few options. One option is to save it in the formats namespace:

    Code:
    Ext.util.Format.genre_name = function() {
        ...
    };
    The reason for doing this is that formats have a special syntax within templates:

    Code:
    {name:genre_name}
    An alternative is to save the function on the template itself:

    Code:
    groupHeaderTpl: Ext.create('Ext.XTemplate', 'Genre: {name:this.genre_name}', {
        genre_name: function(val) {
            ...
        }
    });
    Personally I'd usually go for this last option but if your formatting function is used throughout your application then saving it to Ext.util.Format would make it much easier to share it.

  4. #3
    Sencha User
    Join Date
    Sep 2010
    Location
    Munich, Germany
    Posts
    5
    Answers
    1
    Vote Rating
    0
    Zyrix is on a distinguished road

      0  

    Default


    Thank you very much for your detailed instructions on improving my code and solving the formatting problem. I adapted your changes and the display of the genre name works as intended now by saving my function in the Ext.util.Format namespace.

    I also tried your second solution and created a XTemplate with my function inline:

    Code:
    var groupingFeature = Ext.create('Ext.grid.feature.Grouping', {
            groupHeaderTpl: Ext.create('Ext.XTemplate', 'Genre: {name:this.genre_name}', {
                genre_name : function(val) {
                    var rec = genres.getById(val);
                    return rec ? rec.get('genre') : val;
                }
            })
    });
    However this does not work and [object Object] gets displayed as the group header. As the other solution works, it's not important to know why this doesn't work, I'm just curious why ExtJS won't call the inline formatting function.

  5. #4
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,580
    Answers
    540
    Vote Rating
    314
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    OK, having done a quick bit of digging I think I can explain it. From the docs for groupHeaderTpl:

    Template snippet, this cannot be an actual template.
    It does string concatenation internally with the provided string, so the XTemplate I created was treated as a string, giving what you described. In general the approach I suggested works fine with an XTemplate, it's just the way its used with that config option requires it to be a string rather than the template itself.

  6. #5
    Sencha User
    Join Date
    Sep 2010
    Location
    Munich, Germany
    Posts
    5
    Answers
    1
    Vote Rating
    0
    Zyrix is on a distinguished road

      0  

    Default


    Thank you for the clarification, it worked after I modified the Template to:

    Code:
    groupHeaderTpl: 'Genre: {name:genre_name}',
        genre_name : function(val) {
            var rec = genres.getById(val);
            return rec ? rec.get('genre') : val;
        }
    I also found an interesting solution here: http://www.sencha.com/forum/showthre...d-column-title

    This solution overrides the Ext.grid.feature.Grouping to also return the title of the group and its rendered value.

  7. #6
    Ext GWT Premium Member
    Join Date
    Oct 2009
    Posts
    131
    Vote Rating
    5
    zlevardy is on a distinguished road

      0  

    Default


    i was not able to use inline methods with INPUT element:

    Code:
    		    items: { 		        xtype: 'grid',		        selModel: Ext.create('Ext.selection.RowModel', { listeners: { select: {fn: me.rowSelect, scope: me } } }),		        features: [ Ext.create('Ext.grid.feature.Grouping',{		        	groupHeaderTpl: 		        		Ext.create('Ext.XTemplate',' {[this.groupSelect()]}: <input type="button" onclick="this.groupSelect" value="select"> {name} ',		            		    {		            		        groupSelect: function(value) { console.log('tpl grp sel: '+value); }		            		    }		        		),		        	startCollapsed: false, 		        	enableGroupingMenu: false,		        	collapsible: false		        			        })],		        columns: [ ... ]   ...
    Button this.groupSelect not fired. The section before colon simply executed fine.

    any hints?

    Thx

Thread Participants: 2

Turkiyenin en sevilen filmlerinin yer aldigi xnxx internet sitemiz olan ve porn sex tarzi bir site olan mobil porno izle sitemiz gercekten dillere destan bir durumda herkesin sevdigi bir site olarak tarihe gececege benziyor. Sitenin en belirgin ozelliklerinden birisi de Turkiyede gercekten kaliteli ve muntazam, duzenli porno izle siteleri olmamasidir. Bu yuzden iste. Ayrica en net goruntu kalitesine sahip adresinde yayinlanmaktadir. Mesela diğer sitelerimizden bahsedecek olursak, en iyi hd porno video arşivine sahip bir siteyiz. "The Best anal porn videos and slut anus, big asses movies set..." hd porno faketaxi