ASP.NET MVC 2: Better way to handle multiple buttons in each HTML table row?

余生长醉 提交于 2019-12-24 07:01:26

问题


I have an HTML table where each row has buttons which toggle status bits in the database for each row. Assuming Javascript is not an option, what would be the "best practice" way of handling this?

I'm currently handling it by wrapping each row in a form like this:

<table>
    <tr>
        <td>
            <form action="/FooArea/BarController/BazAction" id="frm0" name="frm0" method="post">
                 <span>Item 1</span>
                 <input type="submit" value="Toggle1" name="submitButton"  />
                 <input type="submit" value="Toggle2" name="submitButton"  />
                 <input type="hidden" name="itemID" value="1" />
            </form>
        </td>
    </tr>
    <tr>
        <td>
            <form action="/FooArea/BarController/BazAction" id="frm1" name="frm1" method="post">
                 <span>Item 2</span>
                 <input type="submit" value="Toggle1" name="submitButton"  />
                 <input type="submit" value="Toggle2" name="submitButton"  />
                 <input type="hidden" name="itemID" value="2" />
            </form>
        </td>
    </tr>
</table>

And the post method looks something like this:

string buttonName = Request.Form["submitButton"];    
if (!String.IsNullOrEmpty(buttonName )) 
{
     int itemID = Convert.ToInt32(Request.Form["itemID"]);
     switch (buttonName )
     {
         case "Toggle1":
         DoSomething(itemID);
         break;

         case "Toggle2":
         DoSomethingElse(itemID);
         break;
     }
}

Any better suggestions? Is having 50 forms on a page cool? I dunno.. let me know what you are doing in this case.


回答1:


The best way to handle POST scenarios without JavaScript is, as several others have stated, a tiny form with only the necessary values, and only one submit button. Basically, what you should do is to create a helper method that creates a form with the necessary POST values in hidden fields and a submit button. For example, you could have a method you use like this:

<%= Html.PostLink("FooArea/BarController/BazAction", "Toggle1", new List<KeyValuePair<string, string>>{ new KeyValuePair<string, string>("itemId", 1), new KeyValuePair("action", "option1") }); %>

It looks pretty verbose, but I've tried to make it as generic as possible. You can probably create the List<KeyValuePair<string, string>> in the controller when you render the view, so you only have to call something

 <%= Html.PostLink("FooArea/BarController/BazAction", "Toggle1", Model.Values) %>

In the action method that handles the post, you bind to the posted FormCollection, and retrieve the values of itemId and action to determine what to do, instead of checking for Request.Form values.

An implementation of the helper method might look like this:

public static string PostLink(this HtmlHelper helper, string postAction, string submitText, IEnumerable<KeyValuePair<string, string>> postValues)
{
    var form = new TagBuilder("form");

    // Setup basic properties like method, action
    form.Attributes.Add("method", "post");
    form.Attributes.Add("action", postAction);

    // Instantiate a stringbuilder for the inner html of the form
    var innerHtml = new StringBuilder();

    // Create and append hidden fields for the post values
    foreach(var value in postValues)
    {
        var hidden = new TagBuilder("input");
        hidden.Attributes.Add("type", "hidden");
        hidden.Attributes.Add("name", value.Key);
        hidden.Attributes.Add("value", value.Value);
        innerHtml.Append(hidden.ToString(TagRenderMode.SelfClosing));
    }

    // Create the submit button
    var submit = new TagBuilder("input");
    submit.Attributes.Add("type", "submit");
    submit.Attributes.Add("value", submitText);
    // Append it to the stringbuilder
    innerHtml.Append(submit.ToString(TagRenderMode.SelfClosing));

    // Set the InnerHtml property of the form, and return it
    form.InnerHtml = innerHtml.ToString();
    return form.ToString(TagRenderMode.Normal);
}



回答2:


This seems like a prime case for some JQuery and Ajax functionality. But if javascript isn't an option then i think wrapping each one in a form is probably the most simple solution.




回答3:


When I need to do something like this I do it pretty much the same way as you do here. It is no problem to have multiple forms in one view. Its like having multiple links in one view (but they use POST instead of GET). I guess many .net developers think its wrong because of webforms only having one form tag. In your case I would even create more forms for each submit button as they seem to do different things. I consider having to check the name of the button in the controller to be a code smell. If they do something like activate/deactivate you should probably post that as a bool or something and have both forms post to the same action.




回答4:


I think technically this is the best way to go. From a usability point of view you can question if this is the best way to do it. More than 20 items in a list can get quite confusing. But ofcourse, I don't really know what you are programming :)

I agree with Mattias about creating different actions for the activate and deactivate-button. This way you avoid having to use a switch-statement.



来源:https://stackoverflow.com/questions/2185301/asp-net-mvc-2-better-way-to-handle-multiple-buttons-in-each-html-table-row

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!