Handling form submit event - c#

I have the following form:
#using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl, #class = "form-vertical login-form", id = "loginform" }))
<button type="submit" class="btn green pull-right">
Login <i class="m-icon-swapright m-icon-white"></i>
</button>
}
And this the javascript handling the event function
$(document).ready(function () {
$("#loginform").submit(function () {
alert('Handler for .submit() called.');
return false;
});
}
However this doesn't work at all.
the alert is never triggered

That's normal, you never assigned your form an id or a class. Look at the generated HTML in your browser to understand what I mean.
You are using a completely wrong overload of the BeginForm helper.
Try this instead:
#using (Html.BeginForm(null, null, new { returnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { #class = "form-vertical login-form", id = "loginform" }))
{
<button type="submit" class="btn green pull-right">
Login <i class="m-icon-swapright m-icon-white"></i>
</button>
}
Now please read about the different BeginForm overloads on MSDN and compare yours with mine.
As you can see there's a difference between the routeValues parameter and the htmlAttributes parameter.

Related

How to manage multiple submit button in my case in MVC 5?

I am a beginner to MVC, I am using MVC 5
_Layout.cshtml code
_Layout.cshtml has navbar, it contains Logout, More button if user already loggedin, Also, it will render body part(Index.cshtml)
//Navbar
#if (ViewBag.name != null)
{
<input type="submit" class="dropdown-item" formaction="Logout" value="Logout" id="btnLogout" />
}
else{
<a class="nav-link" href="#">Login & Signup</a>
}
<input type="submit" class="dropdown-item" formaction="More" value="More" id="btnMore" />
//body
<div class="container body-content">
#RenderBody() //Index.cshtml
</div>
Index.cshtml
Index.cshtml it has some links and also some buttons and anchor links, and it will call partial view (_Login)
#using TestProject.Models
#model ViewSignInAndSignUp
//some html code
<input type="submit" class="dropdown-item" formaction="Action1" value="Action1" id="btnAction1" />
<input type="submit" class="dropdown-item" formaction="Action2" value="Action1" id="btnAction2" />
#Html.Partial("_Login") //partialview
_Login.cshtml
_Login.cshtml this one partial view, if user visit any links, this partial view will popup to request the user to make login. This partial view buttons are working
#model TestProject.Models.SignIn
#using (Html.BeginForm("ControllerSignIn", "Home"))
{
#Html.TextBoxFor(si => si.userName, new { #class = "form-control", #id = "txtLogin" })
#Html.TextBoxFor(si => si.password, new { #class = "form-control", #id = "txtPassword", #type = "password" })
<input type="submit" class="btn btn-sm btn-primary btn-rounded" value="Login" id="btnLoginSubmit" />
}
HomeController
[HttpPost]
public ActionResult Logout(string submitButton)
{
// some coding
return RedirectToAction("Index", "Home");
}
[HttpPost]
public ActionResult More(string str1)
{
// some coding
return RedirectToAction("Index", "Home");
}
[HttpPost]
public ActionResult Action1(string str1)
{
// some coding
return RedirectToAction("Index", "Home");
}
[HttpPost]
public ActionResult Action2(string str1)
{
// some coding
return RedirectToAction("Index", "Home");
}
Now, How can I manage all the buttons from _Layout.cshtml, Index.cshtml, _Login.cshtml(Partial view)
Note
my login button is working, but, logout, more, action1, action2 buttons are not working
Replace this
<input type="submit" class="dropdown-item" formaction="Logout" value="Logout" id="btnLogout" />
with this
Logout
Replace the href with the logout endpoint for your application if different than stated above. Remove any form pointing you to the logout endpoint also as it is not needed anymore.
The submit button submits the form using action URL defined in <form> tag, if you want to use multiple submit buttons then you need to wrap them inside multiple forms with different values of action attribute.
However, there's no need to use multiple submit buttons for those action methods, because redundant <form> tags are inefficient. You may just use #Html.ActionLink() helper to call them like this (and then use styling for those links to look like a button):
#Html.ActionLink("Logout", "Logout", "Home", null, new { #class = "dropdown-item", #id = "btnLogout" })
If the action contains parameter(s), you should add routeValues like example below:
#Html.ActionLink("Action1", "Action1", "Home", new { str1 = "SomeValue" }, new { #class = "dropdown-item", #id = "btnAction1" })
And change HTTP method to GET because ActionLink helper generates anchor <a> tag with href attribute which should use GET method:
[HttpGet]
public ActionResult Logout()
{
// some coding
return RedirectToAction("Index", "Home");
}
The same treatment should be applied to More, Action1 and Action2 action methods as well.
Further reference:
ActionLink helper

MVC, show modal content dependent on dropdown (ajax)

I have no idea how to do something like this.
I have a dropdown with six element, and button.
When I click butto I want to show bootstrap modalpopup. It's a simple.
But I want to tt depends on the selection drop down.
My view:
<button type="button" class="btn btn-default" data-toggle="modal" data-target=".bs-example-modal-lg-addCompanyRisk">
<i class="fa fa-plus"></i> Add
</button>
<div class="modal fade bs-example-modal-lg-addCompanyRisk" tabindex="-1" role="dialog" aria-hidden="true" id="allCustomerModal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
[... Load index from other view...]
<div class="modal-body">
<button type="submit" class="btn btn-default" data-dismiss="modal">#Resources.Common.Cancel</button>
</div>
</div>
</div>
</div>
the content of the list which is to settle on a modal should be dependent on the dropdown.
If the backet all form and button (class="btn btn-default") is a submit, then I dont know how show modal from ActionResult(controller)
EDIT
Partially I solved my problem.
I add to dropdown Ajax.BeginForm and submit
#using (Ajax.BeginForm("GetAllRiskForCompanu", "InsuranceCompanyRisks", null, new AjaxOptions
{
HttpMethod = "Post",
}))
{
#Html.AntiForgeryToken()
#Html.DropDownListFor(model => model.InsuranceCompanyId, ViewBag.InsuranceCompany as SelectList, #Resources.Common.Select, new { #class = "form-control", #required = "required", onchange = "$(this.form).submit();" })
#Html.ValidationMessageFor(model => model.InsuranceCompanyId, "", new { #class = "text-danger" })
}
on controller write method:
[HttpPost]
public Void GetAllRiskForCompanu(FormCollection form)
{
int? companyId = form["InsuranceCompanyId"].GetNullableInt();
if (companyId.HasValue)
{
//set session varible
InsurancePolicySession.InsuranceCompanyRisks = icrf.GetAll(companyId.Value);
}
}
by button add I show modala with render partialView
#Html.Partial("~/Views/InsurancePolicyItem/IndexPolicyCompanyRisk.cshtml", #InsurancePolicySession.InsuranceCompanyRisks)
when I change dropdown selected value the session refresh but when I show modal still view old value.
Rather than mess around with an AjaxForm and directly manipulating a Bootstrap modal, you might find it easier to use something like Bootbox, which will generate your Bootstrap modal as needed.
I would use a normal form:
#using(Html.BeginForm("action", "controller", FormMethod.Post, new { id="some-id", role="form" }))
{
#Html.DropDownListFor(m => m.SomeId, Model.Somethings, new { #class="form-control" })
<button type="submit" class="btn btn-default">Submit</button>
}
Then, capture the form submission and do an Ajax request to get your content:
$(function(){
$('#some-id').on('submit', function(e){
e.preventDefault(); // prevent normal form submit
var form = $(this);
var data = form.serialize();
$.post(form.attr('action'), data)
.done(function(response, status, jqxhr){
// handle response...
})
})
})
Inside the success handler (.done()), build up your dialog. Bootbox has built-in functions for alert, confirm, and prompt (it's primary purpose is to mostly replicate those native functions), but you'll probably want to use dialog(), which lets you completely customize the modal. You'll want to read the documentation to get the most out of it, but a basic usage could be (starting from where you see // handle response... above):
var dialog = bootbox.dialog({
title: 'Some Title',
message: response,
buttons: {
cancel: {
label: 'Cancel',
className: 'btn-default',
callback: function(){
dialog.modal('hide');
}
},
save: {
label: 'Submit',
className: 'btn-primary',
callback: function(){
// submit your data from the injected content, somehow...
}
}
}
});
I primarily use Bootbox at this point, simply because I find it easier than having the modal template on the page. I've also run into the same issue you seem to be having, which is that a reused modal doesn't seem to want to update it's content.
Disclaimer: I am currently a collaborator on the Bootbox project, although I am mostly there to keep the documentation up to date and triage issues.

Post data from a partial view to another action

Just started with MVC and trying to do the following:
having a Details.cshtml with the following part on one of my tabs:
<!-- DETAILS TAB CONTENT -->
<div class="tab-pane profile active" id="details-tab">
#if (ViewBag.ScreenMode == Constants.ScreenMode.View)
{
#Html.Partial("_ViewDetails", Model)
}
else
{
#*#Html.Partial("_EditDetails", Model)*#
<div id="DetailsEdit">
#{Html.RenderPartial("_EditDetails");}
</div>
}
</div>
My _ViewDetails.cshtml shows detail information and has the following to go to the Edit mode:
#Html.ActionLink("Edit", "Details", new { id = Model.EmployeeId, screenMode = Constants.ScreenMode.Edit })
When clicked, indeed the tab shows the contents of the partial view _EditDetails. My _EditDetails.cshtml looks like this:
#using (Html.BeginForm("Edit", "Employee", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.EmployeeId)
#* fields with editable controls. Left it out here *#
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
and having the following methods in my controller:
public ActionResult Details(Guid? id, Constants.ScreenMode? screenMode)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Employee employee = employeeManager.Get(id.GetValueOrDefault());
if (employee == null || employee.EmployeeId == null || employee.EmployeeId == Guid.Empty)
return HttpNotFound();
if (screenMode == null)
screenMode = Constants.ScreenMode.View;
ViewBag.ScreenMode = screenMode;
return View(employee);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Guid? id, HttpPostedFileBase upload)
{
// code here
return RedirectToAction("Details", "Employee", new { id = employeeToUpdate.EmployeeId, screenMode = Constants.ScreenMode.View });
}
However, when I press the save button from the edit partial view, it never hits my code Edit action in my controller. It only goes back to the Details action, which gets the info again. I thought by using the following at the beginning of my partial view, I could make the post go to my Edit action:
#using (Html.BeginForm("Edit", "Employee", FormMethod.Post, new { enctype = "multipart/form-data" }))
What do I miss or are my thoughts completely wrong?
Thanks in advance.
Aarghhhh, found it.
My Details.cshtml started with:
#using (Html.BeginForm("Details", "Employee", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
Removed this and now it's working.
Overlooked this for days.
Thanks.

Summernote and form submission in MVC c#

I am using the summernote plugin for text box:
http://summernote.org/#/getting-started#basic-api
This is the form I have using summmernote:
<div class="modal-body" style="max-height: 600px">
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset class="form-horizontal">
<div id="textForLabelLanguage"></div>
<button type="submit" class="btn btn-primary">Save changes</button>
#Html.ActionLink("Cancel", "Index", null, new { #class = "btn " })
</fieldset>
}
</div>
<script type="text/javascript">
$(document).ready(function () {
$('#textForLabelLanguage').summernote();
});
</script>
Now, In my controller, this is the code I have:
public ActionResult Create(UserInfo newInfo , [Bind(Prefix = "textForLabelLanguage")] string textForLabelLanguage)
{
//logic here
}
Now the problem is that textForLabelLanguage param is always null.
This happens because I have to pass $('#textForLabelLanguage').code(); into MVC when submiting the form but I have no idea how to do that!
How do I solve my problem?
I found my solution to the problem. This is how I am making the controller get the correct information:
<div class="modal-body" style="max-height: 600px">
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset class="form-horizontal">
<textarea name="textForLabelLanguage" id="textForLabelLanguage" />
<button type="submit" class="btn btn-primary">Save changes</button>
#Html.ActionLink("Cancel", "Index", null, new { #class = "btn " })
</fieldset>
}
</div>
<script type="text/javascript">
$(document).ready(function () {
$('#textForLabelLanguage').summernote();
});
</script>
Basically, if I use a textarea with a name instead of an input or anything else, it works!
However, and be warned, even though this solution works, I then get a error in the controller saying:
A potentially dangerous Request.Form value was detected from the client
This happens because I am allowing HTML. But this is a problem for another question!
Please, use [AllowHTML]
There's a good article on MSDN
Request Validation in ASP.NET
"To disable request validation for a specific property, mark the property definition with the AllowHtml attribute:"
[AllowHtml]
public string Prop1 { get; set; }
similar to what was posted earlier you can use the HTML helper
#HTML.TextAreaFor( m=> m.text, new {#id = "textFor*Model*"})
instead of <textarea>

MVC Ajax.BeginForm and Content Security Policy

To prevent cross side scripting i implement CSP to one of my applications. At moment i´m reconfigure all html classes, so that javascript always comes from my server.
Now i found a page with an Ajax.BeginForm and always get the error "Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self'"." if i want to submit the form and update the view.
Can anybody help me, where the problem is?
Here is my html classes (shorted):
UserInformation.cshtml:
<div id="OpenAccountInformation">#Html.Action("OpenAccountInformation")</div>
</div>
AccountInformation.cshtml:
#Scripts.Render("~/Scripts/bundles/ManageUsers/AccountInformation")
#model Tumormodelle.Models.ViewModels.AzaraUserModel
<input type="hidden" value="#ViewBag.Editable" id="EditableUserInformation">
<div id="Editable">
#using (Ajax.BeginForm("EditUser", "ManageUsers", new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "OpenAccountInformation", HttpMethod = "post", }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.UserID)
<div>
<div>
#Html.LabelFor(m => m.Username, new { #class = "entryFieldLabel" })
</div>
</div>
<div>
<div>
<button name="button" value="save" class="formbutton" id="saveButton">save</button>
<button name="button" value="cancel" class="formbutton" id="cancelButton">cancel</button>
</div>
}
</div>
<div id="NonEditable">
<div>
<div>
#Html.LabelFor(m => m.Username, new { #class = "entryFieldLabel" })
</div>
</div>
<div>
<div>
<button name="button" value="edit" class="formbutton" id="editButton" type="button">edit</button>
</div>
</div>
</div>
and the c# methods:
public ActionResult EditUser(AzaraUserModel AzaraUserModel, string button)
{
if (button == Tumormodelle.Properties.Resources.Save)
{
if (ModelState.IsValid)
{
azaraUserManagement.Update(AzaraUserModel.Username, AzaraUserModel.Title, AzaraUserModel.FirstName, AzaraUserModel.LastName, AzaraUserModel.EMailAddress, null, AzaraUserModel.Phone, AzaraUserModel.UserID, (byte)AzaraUserModel.ShowMail.ID);
ViewBag.Message = Tumormodelle.Properties.Resources.Personal_Data_Changed;
ViewBag.Editable = true;
}
else ViewBag.Editable = false;
BindShowMailList();
return PartialView("AccountInformation", AzaraUserModel);
}
else
{
return RedirectToAction("OpenAccountInformation", "ManageUsers");
}
}
public ActionResult UserInformation()
{
return View("UserInformation");
}
public PartialViewResult OpenAccountInformation()
{
AzaraUserModel AzaraUserModel = new AzaraUserModel(azaraUserManagement.GetSingle(AzaraSession.Current.UserComparison.GetUser().Id));
BindShowMailList();
ViewBag.Editable = true;
return PartialView("AccountInformation", AzaraUserModel);
}
Edit: With help of Chrome debugger i find out, that the error is thrown in the moment form becomes submited.
Ajax.BeginForm will be generating inline script in the generated HTML of your page, which you have disallowed by use of script-src 'self' in your Content Security Policy.
If you want to use the CSP to prevent any inline injected scripts you must use Html.BeginForm instead and add the JavaScript to submit this via Ajax in an external .js file.
try to add this attribute to your controller post action
[ValidateInput(false)]

Categories