开发者

Two or more action buttons on an MVC form - Best practice

I have an ASP.NET MVC app with a form. Say this form has an arbitrary number of buttons, each with their own action.

<input type="button" id="action开发者_如何学JAVA1" value="One" />
<input type="button" id="action2" value="Two" />
... and so forth

We want the user to click on one and have a jQuery action fire to submit the form and then repost the form with new information.

There are several ways to implement this. What is the best practice on how to design this elegantly? Please provide code snippets if you can.


Rarely mentioned way is to use ActionMethodSelectorAttribute:

http://weblogs.asp.net/dfindley/archive/2009/05/31/asp-net-mvc-multiple-buttons-in-the-same-form.aspx

In short, it works much like AcceptVerbs attribute - only it selects method by submit value, not by HTTP method. It can also be used for many other things, for example, to select different actions for AJAX/HTTP requests, etc, requested formats (JSON/XML/etc), and so on.

Which method to use - switch, attributes, etc - depends on the situation. I wouldn't say that there's best practice here.

Just to name methods I know:

  1. switch (/action parameter/ submit) {} - too prodecure, though one can use reflection like this.GetType().GetMethod(submit).Invoke(this, new object[]{actiondata}).
  2. javascript: input onclick="$(this).parents("form").attr("action", "specific url").submit() - won't work without javascript
  3. ActionMethodSelectorAttribute - too declarative.

I would be glad to see a better method, for example, [SubmitName("submit1")] attribute on action, and OnActionExecuting() checking it and overriding the called action... but I don't know how it's possible.


Set up an object literal of potential actions:

var actions = {
  action1: function(elem) {
    // If you just want to submit the form normally
    $(elem).closest('form').submit();
    ...
  },
  action2: function(elem) {
    // If you wanted to ajax load a url-field into a div
    var url = $('#url_field').val();
    $('.display').load(url);
    ...
  }
}

Then write a selector that grabs all the buttons (be as specific as you need to be) and attach each function based on the element's id to the click handler. Using event delegation ('$.live()') you can increase performance for the case when there are several buttons, or when buttons are added dynamically.

$('input[type=button]').live('click', function(e){
  actions[$(this).attr('id')](this);
});

This would call the related action in the 'actions' variable on each click (you should probably validate that the function exists, as well).

Then inside each of the action functions, you can submit to different urls, or ajax submit, or load new information, or do anything you want. As far as 'repost[ing] the form' goes, that would be a server-side function that prefilled each input element with its previous value, much like you would do on an invalid submit.

This gives you a single line of code to handle the events, and then a clean structure to build each of your actions in.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜