I want to call the same class from different buttons. Here is what I am doing:
<div class="buttondiv">
#using (Html.BeginForm("TankList","Forms", FormMethod.Post))
{
<input class="allformsbutton" type="submit" value="ASME Basic Form" id="buttonAsmeBasic" />
}
</div>
<div class="buttondiv">
#using (Html.BeginForm("TankList", "Forms", FormMethod.Post))
{
<input class="allformsbutton" type="submit" value="ASME Detailed Form" id="buttonAsmeDetailed" />
}
</div>
I want to pass to the class that I'm calling "TankList" which button was clicked.
How would I capture that in the class?
EDIT
I wanted to clarify. The point of the buttons is to uniquely identify which button was pressed. So, I want to pass to the TankList the value "ASME Basic Form" if the ASME Basic button was pressed or pass "ASME Detailed Form" if the ASME Detailed button was pressed.
your .cshtml-file:
<div class="buttondiv">
#using (Html.BeginForm("TankList","Home", FormMethod.Post))
{
<input name="theClass" class="allformsbutton" type="submit" value="ASME Basic Form" id="buttonAsmeBasic" />
}
</div>
<div class="buttondiv">
#using (Html.BeginForm("TankList", "Home", FormMethod.Post))
{
<input name="theClass" class="allformsbutton" type="submit" value="ASME Detailed Form" id="buttonAsmeDetailed" />
}
</div>
your FormsController.cs
public class FormsController : Controller
{
[HttpPost]
public void TankList(string theClass)
{
}
}
When you post the form the result in the controller is as follows depending on the button you clicked:
Related
I am currently working on a basic To Do List on ASP.NET CORE. I have a button on top of the To-Do list to says "Add Task" upon clicking on the button you'll be re-directed to a Create Task Form. At the moment when click on the Add Task button to be re-directed to the form I am getting a localhost not found error. The URL is correct as it says http://localhost:51797/Todo/Create but my .cshtml page does not appear. I'm new to ASP.Net so apologies if the reason is obvious but I have gone through my code and I cant seem to find why this is happening.
[HttpPost]
[ActionName("Create")]
public ActionResult Create(int? id, string newText)
{
int i = id ?? 0;
TodoListItem toDo = _todoListService.GetList(i);
toDo.Text = newText; //Set new text
_todoListService.WriteToFile(toDo);
return RedirectToAction("Index");
}
}
This is my Create.cshtml page
#model TodoListItem
#{
ViewData["Title"] = "Create";
}
<h2>Add Task</h2>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Text" class="control-label"></label>
<input asp-for="Text" class="form-control" name="newText" />
<span asp-validation-for="Text" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Submit" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
app.UseMvc(routes =>
routes.MapRoute(
name: "create",
template: "{controller=Todo}/{action=Create}");
});
You need an HTTPGET attribute for the GET action, which should return the create view with an empty model.
public IActionResult Create()
{
return View(new TodoListItem());
}
So when you click on Add Task, it will execute this action method and returns the create view.
jQuery
<script>
$(document).ready(function () {
$('#nlSubscribeInitial').click(function () {
$('#nlSubscribeEmail').val($('#nlTextboxInitial').val());
$('#nlTextboxInitial').val('');
});
});
</script>
Form Currently in the Layout View
<div class="input-group">
<input class="form-control" type="text" id="nlTextboxInitial">
** Some other input / info here
<button id="nlSubscribeInitial" type="button" data-toggle="modal" data-target="#nlModal">Open Modal</button>
</div>
Modal currently in Layout View
<div class="modal-body">
<div class="form-group">
<label for="emailInputLogin">Email address</label>
<input type="email" class="form-control" id="nlSubscribeEmail" />
</div>
</div>
Currently this is my codes. After clicking the button on my page, it will open the modal popup.
The value of the textbox will be pass to the textbox located on the modal popup. Currently the form and the modal popup are on my Layout view.
I want to accomplish the same but this time I want call a View (.cshtml) and display it as a modal popup and passing my textbox value to another textbox that is in the View that is being called.
Thanks
Sumbit your email id value to your action, Fill your submited email id to model or viewbag or tempdata
Load That data to your redirected page
<div class="modal-body">
<form action="/somecontroller/someaction" method="post">
<div class="form-group">
<label for="emailInputLogin">Email address</label>
<input type="email" class="form-control" name="email" id="nlSubscribeEmail" />
</div>
</form>
</div>
Controller Action method,
public ActionResult SomeAction(string email){
// You can also construct model
ViewBag.Email = email;
// Return view
return View("SomeViewName");
}
Redirected page(i.e. SomeViewName.cshtml)
<h1>#ViewBag.Email</h1>
I have a view named Index and a PartialView named '_Addbook' that shown as a bootstrap modal. In the partialView insert data into database using ajax form.
Index view :
<div class="panel panel-primary">
<div class="panel-body">
<div class="btn-group">
<a class="btn btn-primary marginbutoon" id="showBookgroup" data-toggle="modal" asp-action="AddBook"
data-target="#modal-book">
<i class="glyphicon glyphicon-plus"></i>
Add Book
</a>
</div>
</div>
Partialview :
#model WebApplication1.Models.Book
<form asp-controller="Home" asp-action="AddBook" id="myform"
data-ajax="true" data-ajax-method="POST"
data-ajax-mode="replace" data-ajax-update="#myform">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">Add Book</h4>
</div>
<div class="modal-body form-horizontal">
<div class="row">
<div class="form-group">
<label asp-for="BookName" class="col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="BookName" class="form-control" />
<span asp-validation-for="BookName" class="text-danger"></span>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-primary" value="Submit" />
</div>
Controller :
[HttpGet]
public IActionResult AddBook()
{
var book = new Book();
return PartialView("_AddBooks", book);
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult AddBook(Book model)
{
if (ModelState.IsValid)
{
using (var db = _Context.GetRequiredService<ApplicationDbContext>())
{
db.bookgroups.Add(model);
db.SaveChanges();
}
return RedirectToAction("Index");
}
else
{
return PartialView("_Addbooks", model);
}
}
The data is stored correctly in the database and modal hide after submit but index view shows Mixed up.
How can i Redirect after ajax submit?
Your current form is setup to do ajax form post. So when the response is received from the server, it will replace the inner html of the form tag. So with your current code, it will basically makes a GET call to the Index action and the response of that will be loaded to the form tag.
If you want to do a redirect, but still want to have the model validation works, You may return a view result back, which has some javascript code which does the redirection.
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult AddBook(Book model)
{
if (ModelState.IsValid)
{
//Your code to store data
return PartialView("_AddedSuccessfully");
}
return PartialView("_AddBooks", model);
}
And in the _AddedSuccessfully.cshtml partial view will have only the below content, which is the javascript for redirect to /Home/Index
<script>
window.location.href = '#Url.Action("Index","Home")';
</script>
EDIT : As per the comment
how can i make it dynamically. because i have several partial view in
my project and i want pass ControllerName and ActionName as a
parameters to _AddedSuccessfully.cshtml?
You can pass it from your view to the action method and from there to the partial view
Just add a hidden input element to the Add form, just above your submit button and use Url.Action helper method to generate the url you want to redirect to, after saving successfully.
<input type="hidden" name="redirectUrl" value="#Url.Action("Index","Home")" />
<input type="submit" class="btn btn-primary" value="Submit"/>
Now, add a new parameter to your action method with the same name as the hidden input. Pass that string value as the model of the view when you call the PartialView method for _AddedSuccessfully view.
[HttpPost]
public IActionResult AddBook(Book model,string redirectUrl)
{
if (ModelState.IsValid)
{
// to do : Save
return PartialView("_AddedSuccessfully", redirectUrl);
}
return PartialView("_AddBook", model);
}
Now you need to udpate the partial view to be strongly typed to string and use the model of the view for redirect.
#model string
<script>
window.location.href = '#Model';
</script>
You can use FormHelper to create ajax forms, ajax redirects, showing notifications and to do many things on ASP.NET Core. Also, FormHelper helps you to transform server-side validations to client-side.
It's so easy to use. You just need to add asp-formhelper="true" to your form tag.
<form asp-formhelper="true" asp-controller="Home" asp-action="Save">
// <input...
// ...
</form>
You can check it's documentation on FormHelper GitHub Page. And you can download that package from Nuget.
I am using ASP.NET MVC with C# and pure bootstrap. One of my views contains a label, text input box, and a submit button:
#{
ViewBag.Title = "BinSearch";
Layout = "~/Views/Shared/_LayoutSearch.cshtml";
}
<h2>BinConfig Search</h2>
#using (Html.BeginForm("FiEdit", "EditConfigController"))
{
<div class="form-group">
<label for="issuerKey">Issuer Key</label>
<input type="text" name="key" />
<input type="submit" class="btn btn-default" value="Search" />
</div>
}
When I click the "submit" button, I would like to transfer the data to a controller, EditConfigController to this method:
[HttpPost]
public ActionResult FiEdit(int key)
{
return View(new IssuerKey().Key = key);
}
Which then is supposed to create a new view where I can edit data based off the key provided. This is the FiEdit view:
#model BinFiClient.Models.IssuerKey
#{
ViewBag.Title = "FiEdit";
Layout = "~/Views/Shared/_LayoutEdit.cshtml";
}
<h2>FiEdit</h2>
However, when I click the "submit" button, I receive a 404 error, and the URL path looks like this:
http://localhost:58725/EditConfigController/FiEdit
Which is actually the path to the method in the controller that I posted above.
What I need is basically a way to POST data to another controller. How can I accomplish this?
Edit:
Now I am receiving the error:
The model item passed into the dictionary is of type 'System.Int32', but this dictionary requires a model item of type 'BinFiClient.Models.IssuerKey'.
Try replacing your code with the following:
#using (Html.BeginForm("FiEdit", "EditConfig", FormMethod.Post))
{
<div class="form-group">
<label for="issuerKey">Issuer Key</label>
<input type="text" name="key" />
<input type="submit" class="btn btn-default" value="Search" />
</div>
}
This will POST the parameter key to the EditConfig controller.
If you'd like to post to the action TestEdit in another controller, say the TestController, your code should be changed to the following:
#using (Html.BeginForm("TestEdit", "Test", FormMethod.Post))
...
To resolve the "model item passed into the dictionary" error, change your POST to be this:
[HttpPost]
public ActionResult FiEdit(int key)
{
return View(new IssuerKey() { Key = key });
}
ou can try with:
#using (Html.BeginForm(("FiEdit", "EditConfigController", FormMethod.Post,
new { enctype = "multipart/form-data" })))
{
<div class="form-group">
<label for="issuerKey">Issuer Key</label>
<input type="text" name="key" />
<input type="submit" class="btn btn-default" value="Search" />
</div>
}
Consider the following markup:
<h2>Edit SAS Program</h2>
#using (Html.BeginForm("Edit", "SasProgram", FormMethod.Post))
{
<label for="Name">Name</label>
#Html.TextBoxFor(model => model.Name)
using (Html.BeginForm("Delete", "SasProgram", FormMethod.Post))
{
<input type="submit" class="button" value="Delete" />
}
<input type="submit" class="button" value="Save Changes" />
}
I'd like to have the Delete button on the same view as the Edit. However, it's not letting me have nested forms. What is the appropriate way to handle this situation?
I tried leveraging this answer, How to handle nested forms in ASP.NET MVC, but it's a broken link now.
I would use different values for button name in the same form:
#using (Html.BeginForm("Edit", "SasProgram", FormMethod.Post))
{
<label for="Name">Name</label>
#Html.TextBoxFor(model => model.Name)
<button name="action" value="delete">Delete</button>
<button name="action" value="save">Save Changes</button>
}
and then switch in controller:
[HttpPost]
public ActionResult Edit( SomeModel model, string action )
{
switch( action ) {
case "delete":
// delete action
break;
case "save":
// save action
break;
}
}
The code is written from memory but it works in production. Note that buttons are of default type - submit.
The best and easiest way would be to use two forms but don't nest them:
<h2>Edit SAS Program</h2>
#using (Html.BeginForm("Edit", "SasProgram", FormMethod.Post))
{
<label for="Name">Name</label>
#Html.TextBoxFor(model => model.Name)
<input type="submit" class="button" value="Save Changes" />
}
#using (Html.BeginForm("Delete", "SasProgram", FormMethod.Post))
{
<input type="submit" class="button" value="Delete" />
}
This way you have:
Two separate forms
No GET requests
The delete button below the edit button, which makes more sense when you're on a view that allows you to edit something.
First of all. Every modification request should be use the post method.
I make some R&D and build the basics of a multi submit button handler in a wiki A clean solution to use multiple submit button in ASP.NET MVC.
I think it could solve your problem.
First, you cannot nest <form> element. The specification doesn't allow it. Since you are using the MVC pattern I have two options that came to my mind:
You can retain the save button as the submit button of the form, and make the delete button a HTML link. Then the delete button will target to a different route, it could be something like: GET /program/delete/{id}.
You can have two buttons inside the same form, then with JavaScript after clicking one of the buttons you will change the action attribute of the form.
Update
There is a third option, that is more clean: using two submit buttons with same name attribute and different values.
Your form will have two buttons:
public ActionResult MyAction(string submitButton) {
switch (submitButton) {
case "save":
// ...
case "delete":
// ...
}
}
For more details check this answer: https://stackoverflow.com/a/443047/439427
You can also use html 5 feature to target a form from an input button. Below I have created both a delete and save form and have the submit buttons outside of the forms but targeting them via the form attribute.
I think most browsers support this except IE.
No javascript required.
#using (Html.BeginForm("Edit", "SasProgram", FormMethod.Post, new { id = "editForm" }))
{
<label for="Name">Name</label>
#Html.TextBoxFor(model => model.Name)
}
#using (Html.BeginForm("Delete", "SasProgram", FormMethod.Post, new { id = "deleteForm" }))
{
<input type="submit" class="button" value="Delete" />
}
<input type="submit" class="button" value="Save" form="editForm"/>
<input type="submit" class="button" value="Delete" form="deleteForm" />
This allows for a nice button layout without any fancy javascript or css styling.
The OLD way to do this but still applicable is to have one form tag and change the action with multiple submit buttons.
<input class="btn btn-default" type="submit" value="Save" />
<input class="btn btn-default" type="submit" value="Delete" onclick="this.form.action='/SasProgram/delete/#Model.Id';" />
Edit : Here's how to do it with ajax using an HttpPost.
//
// POST: /Divisions/Delete
[HttpPost, ActionName("Delete"), Authorize]
public ActionResult DeleteConfirmed(int id)
{
Division division = _db.Divisions.Single(x => x.DivisionId == id);
string errorMessage;
if (DbRelationEnforcer.CanDelete(_db, division, out errorMessage))
{
division.SetDeleted(User.Identity.Name);
_db.SaveChanges();
return Json(new JsonResponseCreatePartial { Success = true }, JsonRequestBehavior.AllowGet);
}
return Json(new JsonResponseCreatePartial { Success = false, Message = errorMessage }, JsonRequestBehavior.AllowGet);
}
Then, on the view, you must use the <input type="submit">Save changes</input> to save your changes (within the form), and a simple link/button to delete, like this:
<h2>Edit SAS Program</h2>
#using (Html.BeginForm("Edit", "SasProgram", FormMethod.Post))
{
<label for="Name">Name</label>
#Html.TextBoxFor(model => model.Name)
<input id='delete-btn' type="button" class="button" value="Delete" />
<input type="submit" class="button" value="Save Changes" />
}
Finally, you have to use JS to post to your action from the view, when the user clicks on Delete.
<script type='text/javascript'>
$(function() {
$("input#delete-btn").click(function(){
$.post('#Url.Action("Delete")', '#Model.Id', function(data) {
if(data.Success) {
' ... handle the success case
} else {
' ... error management
}
});
});
});
</script>
This will work, but in order to have a better UX, it would be preferable to have the Delete button from the Index/list view, and using a JQuery UI dialog to confirm before doing the ajax post. This will skip having to load the Edit page if/when you want to delete multiple items one after the other.