5

My aspx page:-

  <script src="js/jquery-1.4.2.js" type="text/javascript"></script>
  <script src="js/jquery-ui-1.8.2.custom.js" type="text/javascript"></script>

  <script type="text/javascript">
    $(document).ready(function () {
      //lots of other code here....
      function showMessage(){
        $("#msgDiv").dialog({
                        modal: true,
                        buttons: {
                                  Ok: function() {
                                          $(this).dialog('close');
                                      }
                        },
                        resizable: true,
                        show: "explode",
                        position: "center",
                        closeOnEscape: true,
                        draggable: false
                      });
      }
    });
   </script>

Another aspx pop up page which is triggered from the above page

<script type="text/javascript">

    window.opener.document.getElementById("msgDiv").innerHTML = <%=MessageToShow%>; //works very well for me.
    window.opener.document.showMessage(); // I am unable to access it like this?
    window.close();

</script>

Basically I want to call showMessage() from the pop up window. I also have other logics to perform in both pages.

IsmailS
  • 10,797
  • 21
  • 82
  • 134

3 Answers3

15

Declare your function like this inside the document ready:

$(document).ready(function() {

    window.showMessage = function() {
        //...
    };

});

Then you should be able to call it from the other document like this:

window.opener.showMessage();

And because it's in the global scope, you can call it from within the main document just by calling

showMessage();
Bennor McCarthy
  • 11,415
  • 1
  • 49
  • 51
  • I'm sure that, in this case I will have to call it by `window.opener.window.showMessage();` in the pop up window. +1 though. Now its already moved out and working, so don't want to modify it again unless there is any problem. Thanks very much. – IsmailS Aug 04 '10 at 09:51
  • You shouldn't need to double up the window reference. window.opener will return a reference to the window that opened the current one. The only reason window.opener.window works is because the window element contains a reference to itself (as window). If you don't believe me, try window.opener.window.window.window.showMessage() ;) – Bennor McCarthy Aug 04 '10 at 10:25
  • 1
    Just wanted to +1 this, since it would globalize the *`showMessage`* function. I assume it would also be possible to attach it to the jquery namespace `jQuery.fn.showMessage=function(){...}`, which you could probably call like `jQuery.showMessage()` outside the ready. – vol7ron Oct 05 '11 at 18:25
4

As far as I know, what you want to do, can't be done. So, what exactly can we do?

I think the simpliest think would be to move showMessage outside of the ready function, and just call it from within.

Now, if it really must be defined within that function, make it a named function:

  function calledonready()
  {
      /// stuff
      function showMessage(){ 
      /// stuff
      }
   }

$(document).ready(calledonready);

window.opener.document.calledonready.showMessage(); 
James Curran
  • 101,701
  • 37
  • 181
  • 258
  • This is not working for me. Though I can access `calledonready` like this `window.opener.window.calledonready`. But when I access it like this `window.opener.window.calledonready.showMessage()`, it says `TypeError: Object calledonready has no method 'showMessage'` – IsmailS Aug 04 '10 at 05:53
  • Is there going to be any problem with jquery ui dialog if I move showMessage() out of the ready function? If no, I have no other reason to keep it inside. – IsmailS Aug 04 '10 at 05:58
3

You can just declare showMessage() public by putting it directly under your <script> tag. Well that turns out as bad practice actually, but it would work.

The better solution should always be to use your own namespace. Declare an object where all of your application logic can take place.

<script>
var MyApp = {
    showMessage:   function(){
       // do something
    }
};

Later in your code you can access this object from everywhere with

MyApp.showMessage();

You can bring that pattern to an extend by using closures. A lot of smart people developed nice patterns for the ecmascript therefore. A good read like always is `Javascript: the good parts" by Douglas Crockford.

var MyApp = function(){
    var my_private_data = "version 1.0.0",
        foo             = "bar";

     return {
        getfoo          = function(){
             return(foo);
        },
        showMessage     = function(){
             // do something
        }
     };
};

var app = MyApp();

app.showMessage();

This is all about private data and namespacing. That way no other script on your side can possibly change any date you hold within your closured object. The idea can even taken much further by creating inheritance and shared data (semi protected), but I guess this is another story.

jAndy
  • 231,737
  • 57
  • 305
  • 359
  • 1
    +1 Thanks a million ton for teaching this nice concept and best practice. Although I'm just moving out my `showMessage()`, as I'm not doing lots of javascript in my page, but I know that this is the best answer to the question. – IsmailS Aug 04 '10 at 06:06