What is a best usag Razor checkbox with postback?
for examle I have a class as follow
public class Person
{
public string Name { get; set; }
public string SurName { get; set; }
public bool hi { get; set; }
}
and a view(with script):
<script type="text/javascript">
$(function () {
$('#hi').change(function () {
$(this).closest("form").submit();
});
});
</script>
#using (Html.BeginForm(FormMethod.Post))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Person</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.SurName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SurName)
#Html.ValidationMessageFor(model => model.SurName)
</div>
#Html.CheckBoxFor(model => model.hi)
</fieldset>
}
I want postback when I click "hi" checkbox. How can I do it?
a bit jQuery:
$(function(){
$('#hi').change(function () {
$(this).closest("form").submit();
});
});
I haven't tried this out yet. But on the top of my mind, I would add a submit button within the Html.BeginForm(FormMethod.Post) curly braces, and add a style to it to display=none. In other words, it'l be hidden. Then I would add a checkbox event such as onValueChange using jquery (or maybe onClick maybe?, not sure of all of the events by heart.) Within the event block i'd simulate the button click by $('#btnInvisibleButton').Click(); Note that i had trouble executing .Clic() on Safari I think (there's a way around it by adding additional code specific to that browser , so you should test your code on all browsers.
Try this code, just make sure that the submit button is within the form tag:
$('#yourCheckBox').change(function () {
$("#btnInvisibleButton").click();
});
Related
The scenario: I am trying to add a view to Create new users by admin. The app is form authentication. There is a logged in user(admin). When a Password For is added to the view, the view automatically populates the fields with the logged in user.
The controller code:
public ActionResult Create()
{
var userViewModel = new UserViewModel();
return View(userViewModel);
}
The view code:
#model MVC4.Models.UserViewModel
#{
ViewBag.Title = "Create";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>UserVireModelcs</legend>
<div class="editor-label">
#Html.LabelFor(model => model.UserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserName)
#Html.ValidationMessageFor(model => model.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.PasswordFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
What I suspect is happening here is that the application isn't pre-filling the fields, but the browser is. This is because this form looks exactly like a login prompt. (You can test this by clearing your information from the browser itself so that it doesn't auto-fill any login prompt on this site.)
What I would recommend is to semantically separate the concepts of logging in and creating a user. Basically... rename the fields. A simple view model with some more specific names would help:
public class CreateUserViewModel
{
public string NewUserUsername { get; set; }
public string NewUserPasswords { get; set; }
}
Then use that in your view:
<div class="editor-label">
#Html.LabelFor(model => model. NewUserUsername)
</div>
<div class="editor-field">
#Html.EditorFor(model => model. NewUserUsername)
#Html.ValidationMessageFor(model => model. NewUserUsername)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.NewUserPassword)
</div>
<div class="editor-field">
#Html.PasswordFor(model => model.NewUserPassword)
#Html.ValidationMessageFor(model => model.NewUserPassword)
</div>
It's a little more verbose than perhaps one might want it to be (I would agree that simpler is always better), but adding some explicit context to the naming in this case makes it more clear to the browser that this isn't a login form. Use any naming that makes sense for your needs, just make it more descriptive than Username and Password.
i have the following code for view:
#model test1.Models.CustomerVM
#{
ViewBag.Title = "Create";
}
<link href="~/Content/themes/base/jquery.ui.all.css" rel="stylesheet" />
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Customer</legend>
#Html.HiddenFor(model=>model.UserId)
#Html.HiddenFor(model=>model.Id)
<div class="editor-label">
#Html.LabelFor(model => model.User)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.User)
#Html.ValidationMessageFor(model => model.User)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.PasswordFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ConfirmPassword)
</div>
<div class="editor-field">
#Html.PasswordFor(model => model.ConfirmPassword)
#Html.ValidationMessageFor(model => model.ConfirmPassword)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.NameTitle)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.NameTitle, Model.NameTitleColl)
#Html.ValidationMessageFor(model => model.NameTitle)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.FName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FName)
#Html.ValidationMessageFor(model => model.FName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LName)
#Html.ValidationMessageFor(model => model.LName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Gender)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.Gender, Model.GenderColl)
#Html.ValidationMessageFor(model => model.Gender)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.DOB)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.DOB)
#Html.ValidationMessageFor(model => model.DOB)
</div>
#* contacts *#
<div class="editor-label">
#Html.LabelFor(model => model.AddressL1)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.AddressL1)
#Html.ValidationMessageFor(model => model.AddressL1)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.AddressL2)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.AddressL2)
#Html.ValidationMessageFor(model => model.AddressL2)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Suburb)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Suburb)
#Html.ValidationMessageFor(model => model.Suburb)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Country)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Country)
#Html.ValidationMessageFor(model => model.Country)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Phone)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Phone)
#Html.ValidationMessageFor(model => model.Phone)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
<script src="~/Scripts/jquery-2.1.4.min.js"></script>
<script src="~/Scripts/jquery-ui-1.11.4.min.js"></script>
#Scripts.Render("~/bundles/jqueryval")
<script>
$(document).ready(function () {
$('#DOB').datepicker({
appendText: 'mm/dd/yyyy',
showOn: 'both',
buttonText: 'click me',
dateFormat: 'mm/dd/yy',
changeMonth: 'true',
changeYear: 'true',
yearRange: '1900:2016'
});
});
</script>
}
the view works fine displays data as it should be. but when i click Create to save record the following error throws : Object reference not set to an instance of an object This is thrown when it executes the line db.SaveChanges();
Here is the action that does the save. Note: though the view has more field but im not saving all only the ones i have stated in Create() will be saved a.k.a only data in mst_users will be saved
[HttpPost]
public ActionResult Create(CustomerVM custObject)
{
if (ModelState.IsValid)
{
mst_users user = new mst_users
{
uName=custObject.User,
password=custObject.Password,
dtCreated=DateTime.UtcNow,
isLocked=false
};
db.mst_users.Add(user);
db.SaveChanges();
}
}
when i check the receiving data to the method it has all the required data to do the save but funny thing is when it throws the exception the debugger takes the control to the the view and points to the NameTitle field.
Line 44: </div>
Line 45: <div class="editor-field">
Line 46: #Html.DropDownListFor(model => model.NameTitle, Model.NameTitleColl)
Line 47: #Html.ValidationMessageFor(model => model.NameTitle)
Line 48: </div>
here is the table that maps to Entity class mst_users
[uName] varchar
[password] varchar
[dtCreated] datetime
[dtUpdated] datetime
[isLocked] bit
here is the entity class:
here is the video
Here is a null reference error video
As you stated that:
but funny thing is when it throws the exception the debugger takes the control to the the view and points to the NameTitle field.
The problem is not exactly at SaveChanges(), but the exception actually occurs when your action is successfully executed and your same Create view is rendered again. This time, your Model or Model.NameTitleColl is null.
When you make get call to your Create action, you must be populating your CustomerVM method and returning it to view. But after making POST call call to your Create method, if you want to render the same view again, you must populate your CustomerVM again, at the end, and pass it to the view. something like:
[HttpPost]
public ActionResult Create(CustomerVM custObject)
{
if (ModelState.IsValid)
{
mst_users user = new mst_users
{
uName=custObject.User,
password=custObject.Password,
dtCreated=DateTime.UtcNow,
isLocked=false
};
db.mst_users.Add(user);
db.SaveChanges();
}
return View(custObject);
//or return View(new CustomerVM()) just to make you understand
}
UPDATE: (based on video you attached)
You are only populating User, Password and ConfirmPassword field of your CustomerVM model. And you have decorated your Address, Fname and several other properties with *[Required]* attribute. Which means, it MUST not be null when posted, (in order to make model valid). Otherwise, your model state would be invalid. You can clearly see in video, custObject contains null for required values. so exactly as expected, you ModelState.IsValid will give you false in return.
UPDATE: (based on second video you attached)
You are right, your exception occurs at db.SaveChanges() line. The reason for why your debugger takes you to view is following piece of code in your action:
try
{
....
db.SaveChanges();
}
catch()
{
return View(); // <- this line
}
so technically, exception occurs, and the control of your program is moved to your catch block. and you execute return View() in order to handle your exception and when view is rendered, Model.NameTitleColl is null. This throws another exception, which you actually see. whereas, you have skipped the orignal exception.
Reason and Solution:
From your code, I can see, you do not initialize your db object in your action, which throws the orignal exception. Please initialize the db object before you perform any action on it. You can do something like:
db = new YourDbContextNameHere(); //initialize your db object with your Dbcontext class constructor
and then do:
db.mst_users.Add(user);
db.SaveChanges();
it will work fine this way.
This NullPointerException is thrown for db or db.mst_users? In my opinion any one of them is not properly Instantiated.
Based on #Zeeshan answer, I presume your mst_users is being saved to the database the very first time you click the Create button. The problem is likely to be that you are returning same view without passing in the appropriate model that contains the Model.NameTitleColl which is used to populate the dropdown. Hence, the NullExpception.
Update 1
Your model will be invalid because most of your required fields in CustomerVM are null.
For example
the following required field
LName, FName etc are all null. in your video, this values are not provided in the view.
I have a modal popup dialog box that loads a form to be submitted to the database. the form works fine if all the fields are filled out. If i leave blank fields and click the Create button the validation should kick in but it does not. I get the following error:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
Now I know what the error is. The values in the fields are null and they cannot be null to submit to the database. Also ModelState is false as well.
this is my model:
using System.ComponentModel.DataAnnotations;
using MVC_CSAlerts.Models;
namespace MVC_CSAlerts.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
public partial class csAlert
{
public int AlertID { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Must Enter a Route")]
public string Routes { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Must Enter an Issue")]
public string Issue { get; set; }
public string Detour { get; set; }
[DisplayName("Date")]
[DataType(DataType.DateTime)]
[Required]
public Nullable<System.DateTime> DateEntered { get; set; }
[Required]
[DisplayName("Entered By")]
public string EnteredBy { get; set; }
public Nullable<int> Count { get; set; }
[DisplayName("Send Email")]
public string SendEmail { get; set; }
[DisplayName("Is this a child alert")]
public string IsChildAlert { get; set; }
}
}
this is my view
#model MVC_CSAlerts.Models.csAlert
#{
ViewBag.Title = "Create";
}
<h2>Create New Alert</h2>
<script type="text/javascript">
$(document).ready(function () {
// We will test DataPicker
$('#DateEntered').datepicker();
// We will test tabs
$(function () {
$(document).tooltip();
});
});
</script>
#using (Ajax.BeginForm("Create","Alerts",new AjaxOptions()))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>New Alert</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Routes)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Routes)
#Html.ValidationMessageFor(model => model.Routes)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Issue)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.Issue)
#Html.ValidationMessageFor(model => model.Issue)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Detour)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.Detour)
#Html.ValidationMessageFor(model => model.Detour)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.DateEntered)
#Html.ValidationMessageFor(Model => Model.DateEntered)
</div>
<div class="editor-field">
#Html.JQueryUI().DatepickerFor(model => model.DateEntered)
#Html.ValidationMessageFor(model => model.DateEntered)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Count)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Count)
#Html.ValidationMessageFor(model => model.Count)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.SendEmail)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.SendEmail, new
SelectList(new List<object>{
new{ value = "Y", text="Yes"},
new{ value = "N",text="No"}
},
"value",
"text",
"Y"))
#* #Html.EditorFor(model => model.SendEmail)*#
#Html.ValidationMessageFor(model => model.SendEmail)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.IsChildAlert)
</div> <div class="editor-field> #Html.DropDownListFor(model =>
model.IsChildAlert, new SelectList(new List<object>{
new{ value = "Y", text="Yes"},
new{ value = "N",text="No"}
},
"value",
"text",
"Y"))
#* #Html.EditorFor(model => model.IsChildAlert)*#
#Html.ValidationMessageFor(model => model.IsChildAlert)
</div>
<p>
<input type="submit" value="Create New Alert" />
</p>
</fieldset>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
How do I get the clientside validation to load? do I have to do javascript validation in the modal window?
thanks
Try moving your: #Scripts.Render("~/bundles/jqueryval") to the Parent View instead of having it in the Modal View.
My model is simple, one client can have many phone numbers :
I have represented this in Entity Framework
Generated client class is as below.
public partial class Client
{
public Client()
{
this.PhoneNumbers = new HashSet<PhoneNumber>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<PhoneNumber> PhoneNumbers { get; set; }
}
And now I need to create a view page for "create client". This page should have space to enter PhoneNumbers also (ex: By default there should be two text boxes to enter phone numbers)
<fieldset>
<legend>Client</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
as the above "create view" we can easily give an space for "model.Name", because it is a simple property. But how can i do something similar for collection of phone numbers..??
I know that we can achieve this with ugly javascript code, but I would like to know the best easy and simple way, that we can use with ASP.NET MVC ... ?
You have to do a few things:
First create a ViewModel that has the properties you need:
public class ClientViewModel
{
public int Id {get;set;}
public string Name {get;set;}
public PhoneNumber PhoneNumber1 {get;set;}
public PhoneNumber PhoneNumber2 {get;set;}
}
Change Create to return the ClientViewModel
[HttpGet]
public ActionResult Create()
{
return View(new ClientViewModel());
}
Map the HttpPost to use the ClientViewModel and map the values to it:
[HttpPost]
public ActionResult Create(ClientViewModel clientViewModel)
{
var client = new Client();
client.Name = clientViewModel.Name;
client.PhoneNumbers.Add(clientViewModel.PhoneNumber1);
client.PhoneNumbers.Add(clientViewModel.PhoneNumber2);
db.Clients.Add(client);
db.SaveChanges();
return RedirectToAction("Index", "Client");
}
Then, finally, modify your view:
<fieldset>
<legend>Client</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PhoneNumber1.Number)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhoneNumber1.Number)
#Html.ValidationMessageFor(model => model.PhoneNumber1.Number)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PhoneNumber2.Number)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhoneNumber2.Number)
#Html.ValidationMessageFor(model => model.PhoneNumber2.Number)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
For the collection you can use something like this:
#for(int i = 0; i < Model.PhoneNumbers.Count; i++)
{
<div class="editor-field">
#Html.EditorFor(model => model.PhoneNumbers[i])
#Html.ValidationMessageFor(model => model.PhoneNumbers[i])
</div>
}
I have a Html.BeginForm in a view that contains details for a user: firstname, surname, email etc.
Then I have 2 buttons. Approve and Reject
When approve is clicked I go to one view.
When reject, I go to another.
What would be the best way to handle which one was clicked?
in my View:
<% using (Html.BeginForm("PublishGroupsForRecommendedUser", "Recommend", FormMethod.Post, new { id = ViewBag.UserId }))
{ %>
<div class="section _100">
<%: Html.LabelFor(model => model.Email)%>
<div>
<%: Html.EditorFor(model => model.Email)%>
<%: Html.ValidationMessageFor(model => model.Email)%>
</div>
</div>
//etc
<input type="hidden" name="action">
<div class="actions">
<div class="actions-right">
<input type="submit" value="Approve" class="submit_button" />
</div>
<div class="actions-left">
<input type="submit" value="Reject" class="submit_button" />
</div>
</div>
<% } %>
In my Controller:
[HttpPost]
public ActionResult PublishGroupsForRecommendedUser(int userId)
{
var recommendedUser = ZincService.UserService.GetRecommendedUserForId(userId);
var visibleGroups = ZincContext.CurrentUserGroups.Get();
var groupEntities = ZincService.GroupService.GetVisibleGroupsForUser(CurrentUser.UserId).ToList();
var viewModel = GetGroupPublishingViewModelForSelectedGroups(
recommendedUser.RecommendedUserId, Zinc.Enums.PublishingMode.ParticipatingGroupUsersOnly,
recommendedUser.Email, groupEntities);
return View(viewModel);
}
[HttpGet]
public ActionResult RejectUser(RecommendUserViewModel model)
{
Entities.RecommendedUser user = new RecommendedUser();
user.ReasonForRejection = model.ReasonForRejection;
ZincService.UserService.UpdateRecommendedUser(user);
return View(user);
}
So I cannot use the line using (Html.BeginForm("PublishGroupsForRecommendedUser", "Recommend", FormMethod.Post, new { id = ViewBag.UserId })) anymore because depending on which button was clicked I need to go to the PublishGroupsForRecommendedUser or RejectUser action which in turn will call the corresponding View.
Can someone recommend me the best way?
I'm not entirely sure what you want, but I think a little restructuring would help your code:
ASP.NET-MVC makes it easy to handle input from forms by using a specific ViewModel for your view. Make a property for everything you want to post back:
You make a simple POCO object, like:
public class Person {
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public bool IsApproved { get; set; }
}
The ID is in a much better place on your Model than it is in ViewBag. It is a part of the model, don't be afraid to put it there. It will also be filled on getting the results of the post. Quite conveniently.
Let's say your first action is:
public ActionResult PersonForm()
{
var model = new Person()
{
ID = WhateverYouWant()
};
return this.View(model);
}
You can use it as a model from your View:
<%# Page Title="Anything" Language="C#" Inherits="System.Web.Mvc.ViewPage<MVC3ASPX.Models.Person>"... %>
...
...
<% using (Html.BeginForm())
{ %>
<%: Html.ValidationSummary(true) %>
<%: Html.HiddenFor(model => model.ID)%>
<div>
<%: Html.LabelFor(model => model.Name)%>
<div>
<%: Html.EditorFor(model => model.Name)%>
<%: Html.ValidationMessageFor(model => model.Name)%>
</div>
</div>
<div>
<%: Html.LabelFor(model => model.Age)%>
<div>
<%: Html.EditorFor(model => model.Age)%>
<%: Html.ValidationMessageFor(model => model.Age)%>
</div>
</div>
<% } %>
Notice how I made a hidden input field for the ID. It will get posted back.
Also notice that I didn't specify the method (get or post). Post is the default, it will suffice for our needs. I also didn't specify WHERE to post it. By default, the form will post back to the url it is on. In our case this will be the action PersonForm.
Posting 2 ways is not the best practice in ASP.NET. Post to one action and make an if there to decide what to do.
So make 2 buttons. <button>s are more flexible than <input>s for submitting something, as they can have different text and value.
<div class="actions">
<div class="actions-right">
<button type="submit" name="IsApproved" value="True" class="submit_button">Approve</button>
</div>
<div class="actions-left">
<button type="submit" name="IsApproved" value="False" class="submit_button">Reject</button>
</div>
</div>
Note that the buttons will have the text "Approve" and "Reject", but the value posted back will be True or False, depending where you clicked.
Your action handling the post should look like:
[HttpPost]
public ActionResult PersonForm(Person model)
{
if (this.ModelState.IsValid) // Validation never hurts
{
if (model.IsApproved)
{
return this.PersonFormApproved(model); // Your first method goes here
}
else
{
return this.PersonFormRejected(model); // Your second goes here
}
}
return this.View(model); // If the model's state is invalid, let's try this one more time!
}
In the model variable you will have every property filled from the values of your form. Also since there is a property called IsApproved, it will get filled by the form element of the same name. The button. And only the pressed one.
Notice that I have extracted most of the inner logic to methods: PersonFormApproved and PersonFormRejected. These should be private to avoid accidental calls by the program mistakenly thinking they are callable actions.
They should return ActionResult though, since PersonForm action will return their results.
Also check ModelState.IsValid. Only handle the info if it is valid. Check out DataAnnotations on how do you want your model to be validated.
If you use jquery, one solution could be,
Give the form an id, and set the action url for both submit button in the element as data attribute.
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "my-form" }))
{
//form elements
<input type="submit" name="action" value="Approve" data-action="#Url.Action("Approve", "YourController")" />
<input type="submit" name="action" value="Reject" data-action="#Url.Action("Reject", "YourController")"/>
}
and then attach the submit buttons click event with jquery and aattch the action to the form.
$(function () {
$('#my-form :submit').click(function (e) {
var button = $(this);
button.closest('form').attr('action', button.attr('data-action'));
});
});
hope this helps.
in my view:
<asp:Content ID="Content2" ContentPlaceHolderID="ScriptPlaceHolder" runat="server">
<script type="text/javascript">
function RejectUser(userId) {
$.ajax({
url: '<%= Url.Action("RejectUser", "Recommend") %>',
type: 'GET',
dataType: 'json',
data: { id: userId, reasonForRejection: $('#textarea').val() },
success: function (data) {
window.location.href = data.redirectTo;
}
});
}
</script>
</asp:Content>
<div class="actions">
<div class="actions-right">
<input type="submit" value="Approve" class="submit_button" />
</div>
<div class="actions-left">
Reject
</div>
</div>
and in the controller:
[HttpGet]
public JsonResult RejectUser(int id, string reasonForRejection)
{
if (!String.IsNullOrWhiteSpace(reasonForRejection))
{
Entities.RecommendedUser user = new RecommendedUser();
user = ZincService.UserService.GetRecommendedUserForId(id);
user.ReasonForRejection = reasonForRejection;
ZincService.UserService.UpdateRecommendedUser(user);
ZincService.SaveChanges();
}
return Json(new
{
redirectTo = Url.Action("RecommendedUsers"),
}, JsonRequestBehavior.AllowGet);
}
thanks all!