13

I would like to pass a parameter to the jQuery document.ready() function from my View:

$(document).ready(function (parameter){
        $('select[name=Product]').val(parameter);
});

How can I fire the event from my View and pass the parameter? I use Razor as View engine.

Thanks

CiccioMiami
  • 8,028
  • 32
  • 90
  • 151

4 Answers4

23

You can't. The document.ready function doesn't take parameters. You could for example define this parameter as a global variable in your view:

<script type="text/javascript">
    var model = @Html.Raw(Json.Encode(Model));
</script>

and then in your separate javascript file use this global variable:

$(function() {
    $('select[name=Product]').val(model.SomeProperty);
});
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • thanks for your answer. I use a master page (_Layout) where I place the and all the Javascript but I would like to restrict this behavior to a specific View. – CiccioMiami May 12 '11 at 11:59
  • @Francesco, in this case in your _Layout you could define a `Scripts` section which you could override in the specific view and which will contain the definition of the global javascript variable. – Darin Dimitrov May 12 '11 at 13:03
  • I used this implementation, but without the `@Html.Raw(Json.Encode())` part. – Brent Connor Oct 07 '15 at 17:41
21

To avoid using global variables, you can define a closure and then returning this function to ready():

function start(parameter)
{
    return function()
    {
        /*...use parameter */
        alert('parameter: ' + parameter);
    }
}

and then call ready():

$(document).ready(start('someValue'));

You can also define the start function in a external .js file and calling ready (for example) in your main html file. Example: external script.js:

function start(parameter)
{
   return function()
   {
        /*...use parameter */
        alert('parameter: ' + parameter);
   }
}

html file:

<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type="text/javascript" src="script.js"></script>
<script>
$(document).ready(start('someValue'));
</script>
</head>
<body>
</body>
</html>

Calling ready() in the latter file allows you to pass server parameters to your functions. Example (using PHP. In this case you must change the extension from html to php to this file):

$(document).ready(start('<?php echo $serverParameter; ?>'));
slava
  • 1,901
  • 6
  • 28
  • 32
Pablo
  • 223
  • 2
  • 7
5

You can effectively accomplish this with a closure. That is, if you are calling something like $(document).ready(startup) then you can easily rewrite startup so that you can call it with a parameter, e.g. $(document).ready(startup(7)). Pablo gave an excellent underrated answer, and it is worth giving a more detailed example.

Example

Here is a page which displays an alert, invoked by $(document).ready(), that calculates 6*9:

<html>
  <head>
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <script>
      function startup() {
        alert('6 * 9 = ' + 6 * 9);
      }
    </script>
  </head>

  <body>
    Hello!
    <script>
      $(document).ready(startup);
    </script>
  </body>
</html>

Say you want to replace "9" with a variable parameter. The 4-step recipe to do this is:

  1. Parameterize the function.
  2. Wrap the function body in a closure. That is, return function() {...}.
  3. Parameterize the body.
  4. Call the function with the parameter.

Applying this to the above code:

<html>
  <head>
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <script>
      function startup(x) { // Step 1 - Parameterize the function
        return function() { // Step 2 - Put body in "return function() {...}"
        alert('6 * '+x+' = ' + 6 * x); // Step 3 - Parameterize the body.
        } // (closing brace for step 2)
      }
    </script>
  </head>

  <body>
    Hello!
    <script>
      $(document).ready(startup(7)); // Step 4 - Call function with parameter.
    </script>
  </body>
</html>

This displays the alert "6 * 7 = 42".

What's Happening?

$(document).ready() takes as its parameter a function. This is why it is called in the first version above with just startup as the parameter. In contrast if you called it with startup() you wouldn't be passing in the startup function anymore, you would be passing in the return value of startup.

Since $(document).ready() takes a function as its parameter, that's what we give it: startup is transformed in the second version above into a function that returns a function, which has the parameter x set to the value we pass it initially. That is, startup(7) returns a function to $(document).ready() that has the value of x set to 7.

OP's Question

To specifically apply this to the OP's question, rewrite that call as

$(document).ready((function(x) { return function() {
    $('select[name=Product]').val(x);
}})('name'));

where 'name' can be any other value that gets substituted for x. No need for global variables.

More information: JavaScript closures.

Community
  • 1
  • 1
Matt
  • 20,108
  • 1
  • 57
  • 70
  • What I don't get is why you need steps 2 and 3. Steps 1 and 4 (parameterize and call with that parameter) would suffice, wouldn't they? You have the 'startup' function scope to hide your vars and everything inside. Why is the extra function needed? – R. Navega Oct 10 '18 at 18:03
  • According to that "JavaScript closures" question you pointed to, "In JavaScript, if you declare a function within another function, then the local variables of the outer function can remain accessible after returning from it." So it's a way to have private access to them. – R. Navega Oct 10 '18 at 18:12
  • If you only did steps 1 and 4, what would `startup(7)` return? Answer: nothing. This is why you need steps 2 and 3 to return a function. `$(document).ready(f)` doesn't immediately execute `f`. It calls `f()` once the document is ready. You need to pass it a function. – Matt Oct 10 '18 at 18:49
1

You can simply echo your parameter value into the Javascript code if its inline in your view.

$(document).ready(function (){
        $('select[name=Product]').val('@ViewBag.Parameter');
});
DanielB
  • 19,910
  • 2
  • 44
  • 50