Reputation: 109
The way I have structured the form is that there are multiple "Test Connection" submit buttons plus a "Save" submit button to save all the credentials and urls for each test connection. I have seen some suggested solutions but I don't feel like doing an ajax or javascript. So I'm wondering if this is possible. And by the way, I would like to pass values to the controller via the submit buttons as enum values and receive that enum in my controller.
I could easily make multiple ActionResults but it just feels so convoluted for me and if I have to change something in the test connection, I would have to change all. So I would like to have only one ActionResult method for TestConnection plus one Save ActionResult all within the same form.
When I click the Save button, all the credentials are sent to the controller as the ApplicationSettings model.
When I click the Test Connection button, I still receive the ApplicationSettings model plus the DatabaseSystems enum and depending on the enum received form the button, I would do the necessary connection.
Below are the code snippets but I just can't make them work.
Approaches tried:
1. Blank form action, submit buttons has name as "Save" and "TestConnection" accordingly. - Save works. TestConnection does not work saying The resource cannot be found.
2. Form action pointed to "TestConnection", TestConnection button names set as
"database" while value set as @DatabaseSystems.xxx, Save button set as "action:Save", ActionResult method for Save added [MultipleButton(Name = "action", Argument = "Save")]
- TestConnection works, Save does not work saying ambiguous request.
I can't seem to figure out the config to make them both work. :(
View
@using Models.Enums
@model MyApp.Data.ApplicationSettings
@Html.AntiForgeryToken()
@using (Html.BeginForm())
{
<div class="row">
<div class="col-md-2">
@Html.EditorFor(model => model.con1_un, new { htmlAttributes = new { @class = "form-control", @placeholder = Html.DisplayNameFor(model => model.con1_un) } })
</div>
<div class="col-md-2">
@Html.EditorFor(model => model.con1_pw, new { htmlAttributes = new { @class = "form-control", @placeholder = Html.DisplayNameFor(model => model.con1_pw) } })
</div>
<div class="col-md-7">
@Html.EditorFor(model => model.con1_url, new { htmlAttributes = new { @class = "form-control", @placeholder = Html.DisplayNameFor(model => model.con1_url), @rows = "1", @style = "max-width:520px !important" } })
</div>
<div class="col-md-1 pull-right">
<button type="submit" class="btn btn-warning pull-right" name="database" value="@DatabaseSystems.System1" data-toggle="collapse" data-target="#loading"><span class="glyphicon glyphicon-link"></span> Test Connection</button>
</div>
</div>
<div class="row">
<div class="col-md-2">
@Html.EditorFor(model => model.con2_un, new { htmlAttributes = new { @class = "form-control", @placeholder = Html.DisplayNameFor(model => model.con2_un) } })
</div>
<div class="col-md-2">
@Html.EditorFor(model => model.con2_pw, new { htmlAttributes = new { @class = "form-control", @placeholder = Html.DisplayNameFor(model => model.con2_pw) } })
</div>
<div class="col-md-7">
@Html.EditorFor(model => model.con2_url, new { htmlAttributes = new { @class = "form-control", @placeholder = Html.DisplayNameFor(model => model.con2_url), @rows = "1", @style = "max-width:520px !important" } })
</div>
<div class="col-md-1 pull-right">
<button type="submit" class="btn btn-warning pull-right" name="database" value="@DatabaseSystems.System2" data-toggle="collapse" data-target="#loading"><span class="glyphicon glyphicon-link"></span> Test Connection</button>
</div>
</div>
<div class="row">
<div class="col-md-2">
@Html.EditorFor(model => model.con3_un, new { htmlAttributes = new { @class = "form-control", @placeholder = Html.DisplayNameFor(model => model.con3_un) } })
</div>
<div class="col-md-2">
@Html.EditorFor(model => model.con3_pw, new { htmlAttributes = new { @class = "form-control", @placeholder = Html.DisplayNameFor(model => model.con3_pw) } })
</div>
<div class="col-md-7">
@Html.EditorFor(model => model.con3_url, new { htmlAttributes = new { @class = "form-control", @placeholder = Html.DisplayNameFor(model => model.con3_url), @rows = "1", @style = "max-width:520px !important" } })
</div>
<div class="col-md-1 pull-right">
<button type="submit" class="btn btn-warning pull-right" name="database" value="@DatabaseSystems.System3" data-toggle="collapse" data-target="#loading"><span class="glyphicon glyphicon-link"></span> Test Connection</button>
</div>
</div>
... and many more test connections for different systems
<button type="submit" class="btn btn-success pull-right" name="Save" data-toggle="collapse" data-target="#loading"><span class="glyphicon glyphicon-floppy-disk"></span> Save</button>
}
Controller
[HttpPost]
ActionResult TestConnection(ApplicationSettings model, DatabaseSystems database)
{
// depending on the DatabaseSystems enum passed, then I'll do the necessary connection check.
{
[HttpPost]
ActionResult Save(ApplicationSettings model)
{
// Save credentials entered in all the input fields above for con1, con2 & con3.
}
Model
[Serializable]
public class ApplicationSettings
{
public string con1_un { get; set; }
public string con1_pw { get; set; }
public string con1_url { get; set; }
public string con2_un { get; set; }
public string con2_pw { get; set; }
public string con2_url { get; set; }
public string con3_un { get; set; }
public string con3_pw { get; set; }
public string con3_url { get; set; }
... and many more systems
}
Enum
public enum DatabaseSystems
{
System1,
System2,
System3,
... and many more systems
}
Upvotes: 0
Views: 3909
Reputation: 109
Finally got it. Though @Stephen Muecke did not really provide a direct solution, I should say he made me reconsider using formaction again so I still have to thank him. Thanks mate! Below is how I solved it:
View
@using Models.Enums
@model MyApp.Data.ApplicationSettings
@Html.AntiForgeryToken()
@using (Html.BeginForm())
{
...
<button type="submit" class="btn btn-warning pull-right" name="database" value="@DatabaseSystems.System1" formaction="Admin/TestConnection" data-toggle="collapse" data-target="#loading"><span class="glyphicon glyphicon-link"></span> Test Connection</button>
...
<button type="submit" class="btn btn-warning pull-right" name="database" value="@DatabaseSystems.System2" formaction="Admin/TestConnection" data-toggle="collapse" data-target="#loading"><span class="glyphicon glyphicon-link"></span> Test Connection</button>
}
Controller
public ActionResult TestConnection(ApplicationSettings model, DatabaseSystems database)
{
// at the end, instead of putting return View() or return("Index", model), I used below code
return Redirect("/[ControllerName]");
{
... this way, formaction will do the calling of the ActionResult method for me while keeping the name attribute of the button free for other purposes such as passing it as a parameter to my TestConnection method.
Upvotes: 2
Reputation: 420
Use single action name with different parameters for multiple submit button.and give name is same in both button but value is different
for check connectin
<button type="submit" class="btn btn-warning pull-right" name="save" value="@DatabaseSystems.System3" data-toggle="collapse" data-target="#loading"><span class="glyphicon glyphicon-link"></span> Test Connection</button>
for save
<button type="submit" class="btn btn-warning pull-right" name="Save" value="save" data-toggle="collapse" data-target="#loading"><span class="glyphicon glyphicon-link"></span> Save</button>
[HttpPost]
ActionResult Save(ApplicationSettings model,string Save)
{
if(Save=="Testconnection")
{
//do your code on save
}
if(save="Save")
{
//do your code on save
}
}
Upvotes: 1