Is Jquery $(this) broken by jqgrid gridunload method?

Go To StackoverFlow.com

4

I expect the following code to unload a javascipt jqgrid, then load another grid with different options, including different columns

//onload
(function($)
$.fn.myGridFn = function(options){
   $(this).jqGrid('GridUnload');
   $(this).jqGrid(options.gridoptions);


//....

$('#select').change(function(){ 
    switch($(this).val())
    {
      case 'grid1':
            $('#grid').myGridFn({gridoptions:{/*grid1 options*/}});
            break;
      case 'grid2':
            $('#grid').myGridFn({gridoptions:{/*grid2 options*/}});
            break;
    }
   });


})(jQuery);

//...
<table id="grid"></table>

What I get is the grid unloading, then I have to change the selection in the select element and back again to load the new grid.

Updated: If I replace the $(this) in the plugin with the actual element selector $('#grid') - it works just fine, I cant do this in my real app because the plugin is used by several other table elements and grids

2012-04-04 03:14
by Pete_ch
I don't know if this is contributing, but I'm pretty sure val needs parentheses like switch($(this).val() - Isaac Fife 2012-04-04 03:17
was just a typo - I corrected the question -problem persists -th - Pete_ch 2012-04-04 03:19


4

Cleaned up for future readers:

So here's a sort of working fiddle: http://jsfiddle.net/s3MsW/10/

I say "sort of" because the underlying code is suspect (jqGrid itself). But we'll get there in a moment... first thing: if you log "this" for the plugin, it's actually the jQuery object, not the node. Theoretically we can replace $(this) in your original code with this and all should work.

Except not.

You can in fact use this to unload the Grid, but then the function leaves this as a reference that does not point to the table on the rendered page. There are ways to show that the old node is still around ( http://jsfiddle.net/s3MsW/8 was a test ) but suffice it to say it can no longer be used to render a new table to the page proper.

There's no real choice except to cache the selector string and re-select the clean table (ie. create a new jQuery object) from scratch:

$.fn.myGridFn = function(options){
   var theId = this.selector;
   this.jqGrid('GridUnload'); // reference works for now
   $(theId).jqGrid(options); // reference is broken, so re-select with cached ID
}

If you're conscientious about memory usage, you probably want to destroy this (the ghost node), but there's probably no real harm just keeping it around.

2012-04-04 05:04
by Greg Pettit
The gridunload method modifies the table element by deleting all attributes that the jqgrid method had added leaving (and returning)the original table element...this doesn't sound like it would cause problem - Pete_ch 2012-04-04 05:23
The proof is in the pudding, what can I say? Neither caching $(this) nor using this works because right after the unload method, the reference is unusable - Greg Pettit 2012-04-04 05:25
@GregPettit: Sorry to my typing error before. You should use this.id or $this.selector - Oleg 2012-04-04 05:53
No apologies, it's working fine! I don't actually know which typos you mean. ;-) since this is the jQuery object (not the node), this.selector works fine for grabbing the string "#grid" from the original object - Greg Pettit 2012-04-04 05:54
@GregPettit: I did just another things parallel during writing my comments. :-) I need take a cup of coffee - Oleg 2012-04-04 06:00


1

It seems to me that you should just save $(this) in a variable like $this and use it later. The problem is just that inside of

$('#select').change(function(){/*here*/}); // another value of this

so you should do

(function($)
$.fn.myGridFn = function(options) {
    var $this = $(this), selector = $this.selector;

    $this.jqGrid('GridUnload');
    $this = $(selector);    // reset $this value
    ...    

    $('#select').change(function() { 
        switch($(this).val()) { // here is $('#select')
          case 'grid1':
                $this.myGridFn({gridoptions:{/*grid1 options*/}});
                ...

Additionally one use typically start the body of plugin with

return this.each( function() { ...

to be sure that your plugin works also in the case of usage like $(".myGridClass").myGridFn(...) where one can have more as one element in wrapped set $(".myGridClass").

2012-04-04 05:21
by Oleg
You would think it would work (I totally agree), but the reference being cached as $this doesn't work anymore after the unload method: http://jsfiddle.net/s3MsW/7/ - Greg Pettit 2012-04-04 05:28
@GregPettit: You are right! One should save this.selector and use it again - Oleg 2012-04-04 05:33
@GregPettit I agree. In my real app I store 'this' in a variable 'that'. Doesn't work eithe - Pete_ch 2012-04-04 05:33
@GregPettit: Sorry to typing error. The code can be var $this = $(this), selector = $this.selector; $this.jqGrid('GridUnload'); $this = $(selector); I updated the code of my answer - Oleg 2012-04-04 05:39
Oleg, this.selector in and of itself was a revelation. Optimizing code is good fun; sometimes even more than originally writing it. ;- - Greg Pettit 2012-04-04 05:49
Hate to be 'that guy', chohi, but I don't think you noticed that I'm the one who identified the lost reference and provided the working sample. ;-) The above code won't actually work since this is the jQuery object and $(this) will break it - Greg Pettit 2012-04-04 06:00
..or actually, it'll work, but it's unecessarily wrapped a second time. ;- - Greg Pettit 2012-04-04 06:08
Alright I tested the solution on the real app..works just as expected..I wd have been stuck on this forever..this.selector- good one Oleg thanks @Greg Petti - Pete_ch 2012-04-04 13:53
@chohi: You are welcome! I find the most important that the problem is solved. Who helped more and who received more reputation points is absolutely not important for me. So I find good that you marked Greg's answer as the solution. For me it's enough just to know that the problem is solved - Oleg 2012-04-04 14:03
I don't care about points, but I'm the kind of person who thrives on recognition for hard work. Some people don't, but I have to admit to myself that I appreciate a good pat on the back. And I put a lot into solving that problem! That's all. :- - Greg Pettit 2012-04-04 17:56


0

This issue stumped and the answer above was right on.

I kept trying to execute the following:

this.jqGrid('GridUnload')
this.('getGridParam'); /* Still returning all the parameters for the grid. */

Instead I did:

var $t = $(this.selector);
$t.jqGrid('GridUnload');
$t = $(this.selector);
$t.jqGrid('getGridParam'); /* Now empty */
2013-02-18 17:12
by user1949561


-1

I think you should try

$('#select option:selected).val()// gives the value of the selected option.
$('#select option:selected).text()// gives the text of the selected option.

instead of

$(this).val() 

in the parenthesis of switch

2012-04-04 04:01
by mesimplybj
The switch is fine: http://jsfiddle.net/vJ6n2 - Greg Pettit 2012-04-04 04:26
Ads