I have 3 forms each has access to its own Delete/Create/Edit action on server side.
When I change the DropDownListFor selected item and do a Delete then the string title is passed to the server
When I change the DropDownListFor selected item and do a Create/Edit then the string title is not passed to the server.
How can I let my Create/Edit form know of my change in the DropDownListFor ?
Passing the initial title value works with the Create/Edit action. So the problem is the change event.
index.cshtml
#using (Html.BeginForm(MVC.Configuration.Addresses.ActionNames.Delete, MVC.Configuration.Addresses.Name, new { #area = MVC.Configuration.Name }, FormMethod.Post, HtmlAttributes.Form))
{
<div class="form-group required">
#Html.LabelFor(m => m.Title, HtmlAttributes.Label)
<div class="col-md-6">
#(Html.Kendo().DropDownListFor(m => m.Title)
.BindTo(Model.Addresses.OrderBy(order => order.Text))
.HtmlAttributes(HtmlAttributes.KendoControl))
</div>
</div>
<input type="submit" value="Delete" class="btn btn-default" />
}
#using (Html.BeginForm(MVC.Configuration.Addresses.ActionNames.Edit, MVC.Configuration.Addresses.Name, new { #area = MVC.Configuration.Name }, FormMethod.Get, HtmlAttributes.Form))
{
#Html.HiddenFor(p => p.Title)
<input type="submit" value="Edit" class="btn btn-default" />
}
#using (Html.BeginForm(MVC.Configuration.Addresses.ActionNames.Add, MVC.Configuration.Addresses.Name, new { #area = MVC.Configuration.Name }, FormMethod.Get, HtmlAttributes.Form))
{
#Html.HiddenFor(p => p.Title)
<input type="submit" value="Add" class="btn btn-default" />
}
you can use 1 form with multiple buttons, you will achieve the desired result and your view will be cleaner.
As far as I know there are two main methods:
1 MVC Action: You can check the value of clicked submit button in MVC action and then perform the desired things. Example given that your buttons have as name "submitButtonName".
[HttpPost]
public ActionResult YourAction(string submitButtonName, YourFormModel model)
{
switch (submitButtonName) {
case "create":
CreateMethod(model);
break;
case "edit":
EditMethod(model);
break;
case "delete":
DeleteMethod(model);
break;
}
}
3 MVC Actions: You can change the form target action on button click using javascript. Example given that your buttons have as class "submitButtonClass".
$(".submitButtonClass").on("click", function(e){
e.preventDefault();
$('#yourFormId').attr('action', $(this).val()).submit();
});
I wrote the code quickly without testing it but it should work :)
Have a nice day,
Alberto
Related
If I have a single form - with two submits:
From a save button - calls a form POST "Save" controller action.
From a change of a dropdown list value - calls a form POST "NoSave" controller action that returns a modified view without saving.
What's the best way of achieving this?
At the moment, I have the following - but they both call the same POST controller action. I want to call a named action for the dropdownlist update.
<form form method="POST">
<!-- dropdown list -->
<div class="row">
#Html.LabelFor(x => x.FieldName, "Field Name:")
#Html.DropDownListFor(x => x.FieldName, Model.FieldName, new { #class = "browser-default", #onchange = #"form.submit();" })
#Html.ValidationMessageFor(x => x.FieldName)
</div>
</div>
<!-- save button-->
<div class="save-button">
<input type="submit" class="btn" value="Save" />
</div>
</form>
what about using ajax request for different type of requests every type of request call different action or even different controller
[HttpPost]
public ActionResult SomeFunction(string a)
{
return Json("some data here", JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ActionResult AnotherSomeFunction(string a)
{
return Json("some data here", JsonRequestBehavior.AllowGet);
}
//by click button
$("some button name ").click(function(){
$.ajax({
url: 'home/FirstAjax',
success: function(responce){ alert(responce.data)},
error: function(responce){ alert(responce.data)}
});
});
//by click another button
$("some button name ").click(function(){
$.ajax({
url: 'home/SecoundFirstAjax',
success: function(responce){ alert(responce.data)},
error: function(responce){ alert(responce.data)}
});
});
For this you can use ajax.beginform in first parameter you have to give the name of action and then controller and then some option which are like method type and success and failure actions.
#using (Ajax.BeginForm("_LoadPartial", "Abss", new AjaxOptions { HttpMethod = "POST", OnSuccess = "OnSuccess", OnFailure = "OnFailure" }))
{
<div class="row">
#Html.LabelFor(x => x.FieldName, "Field Name:")
#Html.DropDownListFor(x => x.FieldName, Model.FieldName, new { #class = "browser-default", #onchange = #"form.submit();" })
#Html.ValidationMessageFor(x => x.FieldName)
</div>
</div>
<!-- save button-->
<div class="save-button">
<input type="submit" class="btn" value="Save" />
</div>
}
Also provide OnSuccess and Failure Javascript fucntion on the same page.
<script>
function OnSuccess(){
// some action
}
function OnFailure(){
// some action
}
</script>
Here is what I have in my view in ASP.NET MVC 5
#model Entities.Coupon
#using (Html.BeginForm("coupon", "marketing", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="scsm-18 scmd-16 sclg-14">
<div class="form-group">
<label>Codes</label>
#Html.TextBoxFor(p => p.Code, new { #class = "form-control", #data_bind = "value: Code", #autofocus = true, #maxlength = "50" })
</div>
<input type="radio" name="IsPerCentOrDollar" value="1" data-bind="checked: IsPerCentOrDollar" />
<span>PercentageAmount</span>
<input type="radio" name="IsPerCentOrDollar" value="2" data-bind="checked: IsPerCentOrDollar" />
<span>DollarAmount</span>
<input type="radio" name="IsPerCentOrDollar" value="3" data-bind="checked: IsPerCentOrDollar" />
<span>FreeShipping</span>
</div>
<div class="panel-footer text-right">
<input type="submit" name="commandType" id="btnSave" class="btn btn-primary" data-bind="click:submit" value="Save" />
</div>
}
In the script:
$(document).ready(function () {
var viewModel = new CouponViewModel(couponModel);
ko.applyBindings(viewModel);
function CouponViewModel(data) {
self.Code = ko.observable(data.Code);
self.IsPerCentOrDollar = ko.observable("1");
self.DiscountLevel = ko.computed(function () {
return self.IsPerCentOrDollar();
});
};
}
Code in MVC:
[HttpPost, ActionName("coupon")]
public ActionResult coupon(Coupon coupon)
{
try
{
// some logic not yet in
}
catch (Exception ex)
{
}
return View();
}
That's all I have in there now.
In Developer tools inside the browser I can see values for self.DiscountLevel change on the selection of radio buttons.
On Submit, at MVC front the value of Code comes in but the values for DiscountLevel are not.
Any help is greatly appreciated.
Regards.
Let me expand on #StephenMuecke's comment (which has the gist of it I think).
ASP.NET MVC's default model binding will fill the argument (Coupon) with values found in the request. Only form elements are sent along with the request. You seem to expect that DiscountLevel is sent along, but it's just a JavaScript function that exists in the user's browser.
Adding something like this may solve your immediate problem:
<input type="hidden" name="DiscountLevel" data-bind="value: DiscountLevel" />
To note a related issue though: the property you have trouble with is a computed observable. However, you probably do not want to send it along as it depends entirely on IsPerCentOrDollar. Just have your server side Coupon class derive the discount level from that property too. That would also prevent users from hacking the hidden input and sending in a malicious value.
I want to create a page that has a next button and previous button that switches the image displayed.
For that purpose I created an Ajax.BeginForm and inserted into it, an image and two submit buttons.
Can I (should I) have multiple submit buttons inside an Ajax.BeginForm?
How would the controller handle each submit separately?
Try this,
View
#model TwoModelInSinglePageModel.RegisterModel
#using (Ajax.BeginForm("DYmanicControllerPage", "Test", FormMethod.Post,null, new { id = "frmSignUp" }))
{
<div>
<input type="hidden" id="" name="hidden2" id="hdasd" />
#Html.HiddenFor(m => m.hidden1)
#Html.LabelFor(m => m.Name)
#Html.TextBoxFor(m => m.Name)
#Html.ValidationMessageFor(m => m.Name)
</div>
<br />
<div>
#Html.LabelFor(m => m.Address)
#Html.TextBoxFor(m => m.Address)
#Html.ValidationMessageFor(m => m.Address)
</div>
<br />
<div>
#Html.LabelFor(m => m.PhoneNo)
#Html.TextBoxFor(m => m.PhoneNo)
#Html.ValidationMessageFor(m => m.PhoneNo)
</div>
<input type="submit" value="Save" id="btnSave" name="ButtonType"/>
<input type="submit" value="Next" id="btnNext" name="ButtonType" />
}
Controller
[HttpPost]
public ActionResult DYmanicControllerPage(RegisterModel model, string ButtonType)
{
if(ButtonType == "Next")
{
// Do Next Here
}
if (ButtonType == "Save")
{
//Do save here
}
return JavaScript("REturn anything()");
}
I would recommend that you have two buttons and then depending on what button was clicked you could set the action on the form:
Razor
$(function (){
$("#btn-prev").click(function() {
$("#form").attr
(
"action",
"#Url.Action("Action", "Controller", new {area="Area" })",
).submit();
});
$("#btn-next").click(function() {
$("#form").attr
(
"action",
"#Url.Action("Action", "Controller", new {area="Area" })",
).submit();
});
});
I am using jQuery here to do this, but I think you can get the idea.
I had the same requirement/issue and tried both solutions here and they both work for me. I LIKE the idea of setting the action via jquery when clicking so I can keep my actions separate so they can be used by other views.
HOWEVER, I've found that when I do this while I debug, it posts TWICE and BOTH the OnSuccess and OnFailure are triggered. It only happens when debugging though. Keep this in mind when picking.
There are a few questions on SO about multiple submit buttons, such as How do you handle multiple submit buttons in ASP.NET MVC Framework? but what I am having trouble with is having multiple search buttons, each with it's own associated textbox for the value being searched for, and which searches it's own set of data. For example..
<div class="leftContentColumnRow">
#Html.TextBox("SearchString", null, new { placeholder = "Search Roles..." })
<input type="submit" value="" class="searchbtn" name="SearchRoles" />
</div>
<div class="rightContentColumnRow">
#Html.TextBox("SearchString", null, new { placeholder = "Search Permissions..." })
<input type="submit" value="" class="searchbtn" name="SearchPermissions" />
</div>
I can determine which button has been clicked, but I am struggling to get hold of the data in both textboxes.
Use a separate form for each input button pair with a different action for the form.
Like Oded said, 2 forms, each has it'w own action paramter value.
#using(Html.Beginform("SearchRole","User")
{
<div class="leftContentColumnRow">
#Html.TextBox("SearchString", null, new { placeholder = "Search Roles..." })
<input type="submit" value="" class="searchbtn" name="SearchRoles" />
</div>
}
#using(Html.Beginform("SearchPermissions","User")
{
<div class="rightContentColumnRow">
#Html.TextBox("SearchString", null, new { placeholder = "Search Permissions..." })
<input type="submit" value="" class="searchbtn" name="SearchPermissions" />
</div>
}
and the Action methods
public ActionResult SearchRole(string SearchString)
{
//get data and return something
}
public ActionResult SearchPermissions(string SearchString)
{
//get data and return something
}
I'm fairly new to ASP.NET MVC and still getting used to some of the concepts.
I understand that to pass the value of a text box in the View back to the Controller, I can use Html.BeginForm and give the text box the same name as the corresponding parameter in the Controller Action.
Here's my situation: I have 2 buttons. I want them to call the same Action in the Controller. I want them to both pass the value for the text box (i.e. the "searchText").
However, I want one of the buttons to pass "false" for the parameter isQuickJump and I want the other button to pass "true" for the parameter isQuickJump.
Here is my View:
#using (Html.BeginForm("SearchResults", "Search", FormMethod.Get)) {
<div id="logo" class="centered">
<a href="SearchResults">
<img alt="Search" src="../../Content/themes/base/images/Search.jpg" />
</a>
</div>
<div id="searchBox" class="centered">
#Html.TextBox("searchText", null, new { #class = "searchTextBox" })
</div>
<div id="buttons" class="centered">
<input type="submit" id="searchButton" value="Search" class="inputBtn" />
#Html.ActionLink("Quick Jump", "SearchResults", "Search", new { isQuickJump = true }, new { #class = "btn" })
</div>
}
Controller:
public ActionResult SearchResults(string searchText, int? page, int? size, bool? isQuickJump, GridSortOptions sort)
{
var items = GetSearchGrid(searchText, page, size, sort);
if (Request.IsAjaxRequest())
return PartialView("_SearchResultsGrid", items);
return View(items);
}
Any suggestions on how to do this?
I appreciate your help!
Just use 2 submit buttons with the same name and different value:
<div id="buttons" class="centered">
<button type="submit" name="isQuickJump" value="false">Search</button>
<button type="submit" name="isQuickJump" value="true">Quick Jump</button>
</div>
Depending on which button is clicked the corresponding value will be sent to the server for the isQuickJump parameter. And since both are submit buttons, they will also submit all other input fields data to the server (which was not the case with the anchor that you used as the second button).