0

The jquery-ui dialog widget is wrapped (just like all other widgets) within an anonymous function.

Inside this function there is a variable declared named sizeRelatedOptions. I need to add a key to that object from outside that wrapping closure. What is the best way to achieve this?

(function( $, undefined ) {

    var sizeRelatedOptions = {
        buttons: true,
        height: true,
        //etc
    }

    $.widget( "ui.dialog", {
        //widget code
    });

}( jQuery ) );

Edit #1: above code is source code of jQuery ui

Edit #2: I now understand that I can't simply access that variable. So I have to work around this. Therefore, here some more information about why I need this:

I am extending jQuery ui's dialog widget to add another buttonPane. To make the widget resize itself once the pane is added to the widget, I wanted to add an option to sizeRelatedOption. (That's what this question first was about.) Because the _options function of the dialog widget checks whether the option exists in sizeRelatedOption as a key. When that is the case it calls the _size function which resizes the widget.

Hopefully I made myself a bit clear.

netiul
  • 2,737
  • 2
  • 24
  • 29
  • Can't you declare the variable in a global scope? – reggaemahn Aug 14 '13 at 13:44
  • @JeevanJose Not a good idea to modify jquery's source I guess! – netiul Aug 14 '13 at 13:49
  • sizeRelatedOptions is from jQuery's source?? – reggaemahn Aug 14 '13 at 13:51
  • @JeevanJose Yes. I've added a link to the sourcecode. – netiul Aug 14 '13 at 13:55
  • 1
    Everyone seems to forget that the OP do not own the widget's code, which is part of the jQuery UI library. Modifying the source code of a library is an extremely bad practice that leads to maintenance nightmares, so the only viable answer here is that you cannot achieve this. – plalx Aug 14 '13 at 13:55
  • @plaix It's only a "maintenance nightmare" if you upgrade your plugins constantly, [which is a bad idea anyway](http://stackoverflow.com/questions/12608242/latest-jquery-version-on-googles-cdn/12608285#12608285). Just because it's jQuery doesn't mean you're not allowed to get your hands dirty tinkering with it; it just means you should really know what you're doing first. – Blazemonger Aug 14 '13 at 13:57
  • I would just override the setOptions method of the widget with my own version that uses a modified sizeRelatedOption object. Similar example: http://stackoverflow.com/questions/11053168/override-method-inside-jquery-widget/11053676#11053676 – Kevin B Aug 14 '13 at 15:29

5 Answers5

2

You simply can't without directly modifying the source code, but that's not an option that you should consider since it's a very bad practice for many reasons.

The variable is private to that scope and unless the object makes it accessible publicly, your code has to run in the same scope or a children scope of the one where the variable was declared to access it.

However, if you attempt to change some configuration options, the widget provides an API for this already.

For instance,

$('#dialog').dialog({
    height: 500,
    width: 500
});

EDIT: If you could give us some more details about why you are trying to achieve this, we could probably give you other alternatives.

plalx
  • 42,889
  • 6
  • 74
  • 90
  • Could you explain the downvote? It's actually the only valid answer since the OP don't own the code and should never modify the widget's code. – plalx Aug 14 '13 at 13:52
  • Not my downvote, but you're incorrect: The OP didn't create the original code, but that doesn't mean he can't modify it after he downloads it. – Blazemonger Aug 14 '13 at 13:54
  • The variable that the OP is declaring is user-defined. It's not from the api. Besides you said and i quote "You simply can't". This is wrong because in javascript you can make a variable declaration global by using window.variableName. I hope this explains the downvotes. – reggaemahn Aug 14 '13 at 13:56
  • What the OP asks for CAN be done. He just asks what the best way to do it is. Instead of saying that it is not possible it all, you should explain in your answer why it is bad practice and provide an alternative. Otherwise your answer is wrong because there are several ways to do it. – Ethan Aug 14 '13 at 13:56
  • Yeah, "can't" is a bit strong. Better would have been "can't without modifying the code, and shouldn't modify the code if you want to keep sane". – nmaier Aug 14 '13 at 13:56
  • Update. Ok the op just added that the variable is in fact from the api (He didn't mention this before.) But the second statement still stands true. – reggaemahn Aug 14 '13 at 13:57
  • 3
    @Blazemonger, Well in that case why not modifying the object literal and add the new key? It's an very bad practice to modify code that you dont own for many reasons and it should not be considered a sane option. Why would the OP even ask the question if he could simply modify the code directly? – plalx Aug 14 '13 at 13:58
  • @plalx Probably because he didn't know how to? :) – reggaemahn Aug 14 '13 at 14:00
  • @plalx Because he didn't know how to? He could *always* modify the code directly. You're making a false statement that he *can't,* not a reasoned argument that he *shouldn't.* – Blazemonger Aug 14 '13 at 14:00
  • 1
    @Blazemonger, Well I assumed that he would know how to use a text editor. Anyway I have modified my answer and added precisions. – plalx Aug 14 '13 at 14:05
  • As requested, I've made myself more clear (hopefully) why I needed this :). See the question. – netiul Aug 14 '13 at 14:31
0

You can set it as a global variable:

var window.sizeRelatedOptions = { // now it's a global

It would be better to have your anonymous function return the variable, however:

var myvar = (function( $, undefined ) {

  var sizeRelatedOptions = {
    buttons: true,
    height: true,
    //etc
  };
  var returnvar = sizeRelatedOptions; // in case sizeRelatedOptions is modified

  $.widget( "ui.dialog", {
      //widget code
  });

  return returnvar;

}( jQuery ) ); // now myvar contains the same data
Blazemonger
  • 90,923
  • 26
  • 142
  • 180
  • This is slightly unsafe if the widget replaces `sizeRelatedOptions` outright, instead of changing its properties, e.g. `sizeRelatedOptions = { buttons: false, height: true }` instead of `sizeRelatedOptions.buttons = false;` – Sacho Aug 14 '13 at 13:47
  • @Sacho True, but without more code from OP, I have no reason to expect that. Added some code to account for this possibility. – Blazemonger Aug 14 '13 at 13:49
  • @plalx Of course it's an option; it's JavaScript code, it's not compiled. OP can download and modify it any time he likes. – Blazemonger Aug 14 '13 at 13:53
0

Pass the window object to the function, then you can attach methods and properties to it.

(function( $, window, undefined ) {

    window.sizeRelatedOptions = {
        buttons: true,
        height: true,
        //etc
    }

    $.widget( "ui.dialog", {
        //widget code
    });

}( jQuery, window ) );
Ethan
  • 2,754
  • 1
  • 21
  • 34
0

You should declare this variable in the global scope. You can use $.extend to add properties to the existing object.

window.sizeRelatedOptions  = {};

(function( $, undefined ) {
    $.extend(sizeRelatedOptions ,  {
        buttons: true,
        height: true,
        //etc
    });

    $.widget( "ui.dialog", {
        //widget code
    });
}( jQuery ) );
Damien
  • 8,889
  • 3
  • 32
  • 40
0
var accessor = (function( $, undefined ) {

    var sizeRelatedOptions = {
        buttons: true,
        height: true,
        //etc
    }

    $.widget( "ui.dialog", {
        //widget code
    });
    return {
       getSizeRelatedOptions: function () { return sizeRelatedOptions; }
    }
}( jQuery ) );
accessor.getSizeRelatedOptions();

I don't think it's possible without modifying the widget's source.

Sacho
  • 2,169
  • 1
  • 14
  • 13
  • Why not simply making it part of the global interface? I don't see any advantages to add an accessor in this case. – plalx Aug 14 '13 at 14:28