Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I pass a parameter with the OnSuccess event in a Ajax.ActionLink

Tags:

asp.net-mvc

When I use:

new AjaxOptions
{
  UpdateTargetId = "VoteCount" + indx,
  OnSuccess = "AnimateVoteMessage"
}

everything works fine...but I am trying to animate items in a list, with automatically assigned ID's. Since I want each of these to be addressable from my javascript, I believe I need to pass a parameter to my javascript. But when I use:

new AjaxOptions
{ 
  UpdateTargetId = "VoteCount" + indx,
  OnSuccess = "AnimateVoteMessage(2)"
}

I get an " Sys.ArgumentUndefinedException: Value cannot be undefined." exception. Well I get that when using the debug versions of MicrosoftMvcAjax.js. When using the compressed version I get a "Microsoft JScript runtime error: 'b' is null or not an object"

So my question is, can I pass a parameter to my javascript function using the OnSuccess event for a ActionLink?

Is this the right approach? How else am I going to have one javascript function have the ability to be run on 10 items (in my case the IDs of multiple DIVs) on my page?

like image 288
Whozumommy Avatar asked Apr 27 '09 06:04

Whozumommy


3 Answers

There is a better way to do this - use the built in parameters that the OnSuccess call can be expected to pass

the built in parameters (the ones I found so far anyway) are data, status and xhr

data = whatever you return from the action method

status = if successful this status is just a string that says "success"

xhr = object that points to a bunch of javascript stuff that I will not be discussing...

so you would define your javascript like this (you can leave out the arguments you don't need - since all we want is our data back from the action we will just take the data argument)

function myOnSuccessFunction (data)
{
   ..do stuff here with the passed in data...
}

like I said before, data is whatever JSON that may be returned by the ActionResult so if your controller action method looks like this...

public ActionResult MyServerAction(Guid modelId)
{
   MyModel mod = new MyModel(modelId);

   mod.DoStuff();

   return Json(mod, JsonRequestBehavior.AllowGet);
}

you would set up your action link like this...

@Ajax.ActionLink("Do Stuff", "MyServerAction", new { modelId = Model.Id }, new     AjaxOptions { OnSuccess = "mySuccessScript(data);", OnFailure = "myFailureScript();", Confirm = "Are you sure you want to do stuff on the server?" })

this will create a confirmation message box asking if you want to actually invoke the action - clicking yes on the prompt will invoke the call to the controller - when the call comes back - the data argument will contain a JSON object of whatever you returned in your action method. Easy Peasy!

But wait! What if I want to pass another custom argument?! Simple! Just add your arguments to the front of the list...

instead of this...

function myOnSuccessFunction (data)
{
   ..do stuff here with the passed in data...
}

do this (you can have more than one custom argument if you like, just keep adding them as needed)...

function myOnSuccessFunction (myCustomArg, data)
{
   ..do stuff here with the passed in data and custom args...
}

then in your setup - just get the argument through some client side script within your ActionLink definition... i.e.

@Ajax.ActionLink("DoStuff", "MyServerAction", new { modelId = Model.Id }, new AjaxOptions { OnSuccess = "mySuccessScript(myClientSideArg, data);", OnFailure = "myFailureScript();", Confirm = "Are you sure you want to do stuff on the server?" })

Note that "myClientSideArg" in the OnSuccess parameter can come from wherever you need it to - just replace this text with what you need.

Hope That Helps!

like image 137
Chase Avatar answered Oct 17 '22 09:10

Chase


or...a bit different syntax that worked for me:

OnSuccess = "( function() { MyFunction(arg1,arg2); } )"
like image 37
Mike Avatar answered Oct 17 '22 09:10

Mike


There is a better way, which I believe is how Microsoft intended it: Set the AjaxOptions.OnSuccess to a function pointer, i.e. just the name of the function, no parameters. MVC will send it parameters automagically. Below is an example.

JScript parameter:

public class ObjectForJScript
{
    List<int> Ids { get; set; }
}

Jscript function:

function onFormSuccess(foobar){
    alert(foobar);
    alert(foobar.Ids);
    alert(foobar.Ids[0]);   
}

View code:

@using (Ajax.BeginForm("ControllerAction", "ControllerName", 
    new AjaxOptions
        {
            OnSuccess = "onFormSuccess" //see, just the name of our function
        }))
{
    @Html.Hidden("test", 2)
}

Controller code:

public JsonResult ControllerAction(int test)
{
    var returnObject = new ObjectForJScript
        {
            Ids = new List<int>{test}
        };

    return Json(returnObject);
}

Note that the parameter name in the JScript function doesn't matter, you don't have to call it "returnObject" even though the controller names it so.

Also note that Json() conveniently turns our List into a JScript array. As long as the methods of the C# object are translatable to Json, you can call them in the JScript like I've done.

Finally, the controller doesn't have to return a JsonResult, it can be ActionResult (but it's usually better to have a controller action do just one thing).

The above example will alert two objects (the Json and the array object which it contains), and then 2.

like image 9
Magnus Avatar answered Oct 17 '22 08:10

Magnus