Let's suppose I have a form with two submit buttons: save and delete.
How can I remove/disable model validations on delete button?
Assuming you're using standard unobtrusive/jQuery validate; Disable client-side validation by putting a class of "cancel" on the button:
<button type="submit" class="cancel">Delete</button>
This will prevent client-side validation from firing at all in the event of this button being clicked.
For server side, just don't check if the model's valid or not.
For example, if you have a property Name on the model and you want NOT to validate it on delete.
You first need to differentiate if the httppost is coming from the save or delete button.
Add to your Model field IsDelete.
I suggest you add in your view something like:
#Html.HiddenFor(x => x.IsDelete)
Add onclick event to your delete button:
<button type="submit" onclick="javacript: $('#IsDelete').val('true');"> Delete </button>
In the controller do something like:
public ActionResult MyAction(MyModel model)
{
if(model.IsDelete)
ModelState.Remove("Name");
var valid = ModelState.IsValid();
}
You can use two separate forms in the view for the edit and delete.
Ex:
#using(Html.BeginForm("Edit", "Employee"))
{
//Edit inputs - ex textboxes for employee details such as name, age...
<input type="submit" value="Edit" />
}
#using(Html.BeginForm("Delete", "Employee"))
{
//Delete inputs - ex: hidden input for employee id
<input type="submit" value="Delete" />
}
Related
In Asp.net MVC, Is it possible to have a form post to two different actions based on model value when clicked on the same button?
Ex. - I want to add a new customer or update an existing customer on click of the same button "Save". Can the form be posted to two different action methods based on the customer's id value.
if the customer id value = 0 , then post it to "Create" acction method , if the customer id value is already present (not equal to 0), then post the form to "Update" action method?
Is this possible in asp.net mvc?
No You cant call multiple action on submit with fairly way,
You need to add hiddenfield for id
<input type="hidden" name="id" value="#model.Id" />
When you submit the form the value will be retrieve from model
And check the hidden field value is 0 or not
If 0 than the entity needs to create else it is for update
public ActionResult Save(Customer customer){
if(customer.id > 0){
// Update Entity
}
else{
// Create Entity
}
}
Yes. It is possible. There are multiple ways to do it.
1) You can conditionally set the form action attribute value based on your view model property value.
<form method="post" action="#(Model.Id==0?Url.Action("Create","Home")
:Url.Action("Update","Home"))">
<input type="text" name="FirstName" />
<button type="submit">Save</button>
</form>
2) Another option is, you can add html5 formaction to your submit button and the value of that attribute could be the url to create or update action method based on your Id property value.
#using (Html.BeginForm("Create", "Home"))
{
<input type="text" name="FirstName" />
<button type="submit"
formaction="#(Model.Id==0?Url.Action("Create","Home")
:Url.Action("Update","Home"))">Save</button>
}
When you specify the formaction attribute on a submit button, it will overrides the parent form's action attribute value.
3) Another option is to hijack the form submit event in javascript, prevent the default behavior (stopping the form submit) and then update the form's action attribute value to /create or /update and trigger form submit using javascript. You can keep the Id property value in a hidden field inside the form and read the value of that and use that to determine what should be the url for the form's action attribute value.
Assuming you have a hidden element for the Id of type int property in your page
#model YourViewModel
#using (Html.BeginForm("Create", "Home",FormMethod.Post,new {id="yourFormId"}))
{
#Html.TextBoxFor(a=>a.FirstName)
<button type="submit">Save</button>
#Html.HiddenFor(a=>a.Id)
}
and the javascript to hijack the form submit and update the form's action attribute value would be like
$(function () {
$("#yourFormId").submit(function(e) {
e.preventDefault(); // stop the normal form submit
var id=parseInt($("#Id").val());
var url=$(this).attr("action");
if(id===0)
{
url='/Home/Update'; // Use the Url.Action to be safe to generate this
}
// read the data attribute and update the forms action and do a submit
$(this).closest("form").attr('action', url).submit();
});
});
4) Another option is always submitting the form to Update or Create action and inside that method, based on the the Id property value, execute the code for Update or Create as needed.
Yes. This for the View case:
#mode MyModel
#{
string action = Model.Id == 0 ? "Create" : "Edit"
}
#using (Html.BeginForm(action, "MyController"))
{
// if Edit need Id
if(action == "Edit")
{
#Html.HiddenFor(model=> model.Id)
}
#Html.TextBoxFor(model >= model.Name);
<input type="submit" value="Save">
}
I have a form which should print questions dynamically. Foo has a Field object and a Field Definition object. I want the Field to have its fieldDefinition assigned by the form. All of the behind the scenes stuff works fine.
The below code works with assigning Strings and Longs in other scenarios.
Here's the line that's causing trouble:
<input th:type="hidden" th:field="*{fields[__${iterationStatus.index}__].fieldDefinition}" th:value="${fooViewModel.fields[__${iterationStatus.index}__].fieldDefinition}"/>
This is what it looks like when it renders in html:
<input type="hidden" value="com.blah.domain.FieldDefinition#fbb2e392" id="fields0.fieldDefinition" name="fields[0].fieldDefinition">
When I submit the form, no controller action is invoked, and the app simply redirects to the error page.
If it's impossible to actually do the assignment that way, please suggest other methods. The only way I came up with is to have Foo use the FieldDefinitionService to do the assignment after being passed an ID. I don't that Domain class to have access to another Domain object's Service.
Thanks
Just an example: when you need to iterate a form inside an element that has a th:each attribute, you can use the following structure (so far, it's the only way that's working for me).
<tr th:each="rank, stat : ${ranks}">
<td th:text="${rank.name}">This is static</td>
<td th:text="${rank.description}">This is static</td>
<td>
<form th:action="#{/user/ranks/delete}" method="post">
<input type="hidden" id="id" name="id" th:value="${rank.id}"></input>
<button class="btn btn-danger" type="submit">
<span>Delete</span>
</button>
</form>
</td>
</tr>
Here ranks is a list of entities that have to be displayed on a table and, for each entity, there is a delete button associated to a form.
The controller method should be similar to the following fragment, the parameter is availabled with the name id:
#RequestMapping(path = "/delete", method = RequestMethod.POST)
public View deleteRank(Model model, #RequestParam(name = "id") String rankId,
#ModelAttribute("user") User user)
{
Long id = Long.parseLong(rankId);
// delete ...
RedirectView redirectView = new RedirectView("/user/ranks");
return redirectView;
}
I have a scaffold list type table in my view. Above to the table, I have two checkboxes also. When I click on Edit link I need to pass the selected Id as well as the CheckBoxes' value also.
I can use ActionLink to pass the primary key value like
#Html.ActionLink("Action","Controller", new { id=#item.Id })
I can get the CheckBoxes Value by wrapping them into a Html.Beginform like,
#using(Html.BeginForm("Action","Controller",FormMethod="Post"){
<input type="checkbox" name="Check" value="1" />
<input type="checkbox" name="Check" value="2" />
-- table
<input type="Submit" value="Edit"/>
and in my controller, I can handle this like
[HttpPost]
Public ActionResult Edit(IEnumerable<string> check)
{ }
Here, I need to get both the Primary key value as well as Checkboxes' value, I tried in these two ways, and I could get any one of these only. Can anyone help me to get both the values? Thanks in advance.
You can include id in the action parameter. Like
[HttpPost]
Public ActionResult Edit(IEnumerable<string> check, int id)
{ }
Also, you will need to post the form using a submit button not the action link.
So, for sending the id, you will need to put it in a hidden field and it will automatically be sent on post.
Make sure you name the hidden field the same as the parameter name i.e. "id".
Edit
Do like this:
Take a hidden field in form: like this:
<input type="hidden" id="hf" value="TEst" name="hid" />
Then take a edit button in each row and make it call a javascript function. Like below:
<button type="button" onclick="clickfunc(#item.UniqueId)">Edit</button>
Next Come in Javascript and set hidden field and then do a form submit. Like below:
#section scripts{
<script type="text/javascript">
function clickfunc(id) {
$("#hf").val(id);
$('form').submit();
}
</script>
}
Now you get the values in your controller action. In my example it looks like:
public ActionResult EditTry(string hid)
{
return View();
}
You will get selected value in "check" string
To get the name type jquery on submit button click and store it in hidden field and access the hidden field from form collection
var getval = $("#Check option:selected").text();
$("#hdnText").val(getval);
This is controller Code:
[HttpPost]
Public ActionResult Edit(string check, FormCollection collection)
{
string strText = collection["hdnText"].ToString();
string strValue = check;
}
I have two submit buttons which call the same action method. How can I tell which of these buttons was clicked in the formcollection of the action method (without setting the value property of the buttons)?
HTML code for buttons:
<input type="submit" name="button" />
<input type="submit" name="button" />
Action method as:
public ActionResult submitted(FormCollection form)
{
}
i know how to do if we have a value property, but I just want to try like this without value property. How can this be done?
thanks,
michaeld
The best thing to do, is intercept the click action to set a hidden form variable before the form is submitted, e.g.:
<script language="text/javascript">
$("form input[submit]").click(function() {
$("#buttonSelected").val("some unique value here");
});
</script>
Where you might have a hidden input:
<input type="hidden" id="buttonSelected" name="buttonSelected" />
That way, you can then check the specific "buttonSelected" form value to figure out which button was pressed.
I have two submit buttons in one form. I want to call different actions in both buttons. Is there any way to accomplish this without using JavaScript.
Calling different actions is not possible without javascript. You could call the same controller action and inside this action determine which button was pressed using the name property:
<% using (Html.BeginForm()) { %>
<input type="submit" name="save" value="Save" />
<input type="submit" name="update" value="Update" />
<% } %>
and in your controller action:
[HttpPost]
public ActionResult Index(string save)
{
if (!string.IsNullOrEmpty(save))
{
// the save button was pressed
}
else
{
// the update button was pressed
}
return View();
}
Give the buttons different name attributes. Then in your view handler (or equivalent - sorry, not an ASP.NET MVC person), you can check if that button's name is in the HTTP response and act accordingly.
Only one of the submit button names should exist in the response.
Of course there is!
for example, we have following form:
<form>
<input name='customer_name' type='text'/>
<input name='update_user' type='submit' value='Update user info'/>
<input name='delete_user' type='submit' value='Delete user'/>
</form>
when server gets form request there exists only one parameter in the collection: either update_user or delete_user. depends on what user has pressed.