Handling hidden field in multiple forms in Mvc 4.0 - asp.net-mvc

I am having multiple forms in one page and that page inherits one single model.Every form submission requires a common value. So, common value is stored in hidden field. The hidden field is kept global i.e outside of all the forms but my problem is whenever I submit form, that hidden field is coming to be empty.The hidden field is #Html.HiddenfieldFor(m=>m.FkId) and this FkId is of string type proprty in model i.e public string FkId{get;set;} .Can somebody please guide me how to handle this situation. If I keep hidden field in one of the forms then , it is coming in controller but only for that form submission where I have kept it. But I want that property to be set once and can use in all the form submissions.Please help me. How can I sort out this problem
Some related code
<div id="tabs">
<ul>
<li>Nunc tincidunt</li>
<li>Proin dolor</li>
<li>Aenean lacinia</li>
</ul>
<div id="tabs-1">
#using (Ajax.BeginForm("Evaluation","SaveTab1"{new AjaxOptions { Onsucess= "DisplayMessage" }))
{
#Html.HiddenFieldfor(m=>m.fkID)
<input type="Submit" id="btnTab1" value="Submit" onclick="CheckUser();"/>
}
</div>
<div id="tabs-2">
#using (Ajax.BeginForm("Evaluation","SaveTab2"{new AjaxOptions { Onsucess= "DisplayMessage" }))
{
#Html.HiddenFieldfor(m=>m.fkID)
<input type="Submit" id="btnTab2" value="Submit" />
}
</div>
<div id="tabs-3">
#using (Ajax.BeginForm("Evaluation","SaveTab3"{new AjaxOptions { Onsucess= "DisplayMessage" }))
{
#Html.HiddenFieldfor(m=>m.fkID)
<input type="Submit" id="btnTab3" value="Submit" />
}
</div>
</div>
<script type="text/javascript">
function DisplayMessage(Json)
{
alert( $("#fkID").val(Json.hdn));
// and Alert is showing the value
$("#fkID").val(Json.hdn);
}
</script>
In the Controller I have:
public ActionResult SaveTab1(Model obj)
{
tbl ob =new tbl();
ob.FkId=Obj.fkID;
// after saving, I return
return json(new{hdn=Obj.fkID})
}
public ActionResult SaveTab2(Model obj)
{
tbl ob =new tbl();
ob.FkId=Obj.fkID;
//after saving, I return
return json(new{hdn=Obj.fkID})
}
Similar for tab three, but unfortunately the hidden filed only comes for first form submit. Then I return value to view by json and again set the hidden field property but then it comes null for second form.Please help

First of all, your View does not inherit the Model, it is strongly-typed to the type of your Model. These two are completely different.
But, to answer your question, there's no such a thing as a global hidden field. Fields are not variables. If you want a field to be posted to your Controller, you need to put it inside the form. If you have multiple forms in your View, then you'll have to put the same hidden field inside all the those forms. So, you need to put #Html.HiddenFor(m => m.FkId) inside all the forms in your View.
UPDATE: By the way, it's not Html.HiddenFieldFor, it's Html.HiddenFor.

I have solved the problem. Instead of taking same field in all the forms which was not working, I have taken a unique and different Hidden field properties and after on seperated success function of each form and set the every hidden field a value in success method.

Related

MVC Checkboxes Collection Displays Correctly in View but I on Post Back the Collection is Empty

I am having trouble with a simple Visual Basic Code for MVC using Check Boxes.
I am trying to create a Form where the user could choose which Office Department will have access to a particular Document.
Here is the output in the browser:
The data gets displayed correctly from the Model to Controller to View.
However, I cannot get the clicked values from the View back to the Controller.
Here is the Model:
Public Class Department
<Required>
<Display(Name:="Department ID")>
Public Property DepartmentID As Integer = 1
<Required>
<Display(Name:="Department Name")>
Public Property DepartmentName As String = ""
<Required>
<Display(Name:="Department Image")>
Public Property DeptImage As String = ""
Public Property IsSelected As Boolean = False
End Class
Here is the View
<section class="checkBoxListFor">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Access Rights</h3>
</div>
<div class="panel-body">
#For Each oDept As Department In Model.DeptList
#<text>
#Html.CheckBoxFor(Function(m) oDept.IsSelected)
#oDept.DepartmentName
#Html.HiddenFor(Function(m) oDept.DepartmentID)
#Html.HiddenFor(Function(m) oDept.DepartmentName) <br />
</text>
Next
</div>
</div>
</section>
I have read an article here about NOT using a For Each Loop to display the collection of Form Controls since when you look at the generated HTML Code, the "name" will not be correct and hence it won't bind to the Controller when POST Back is called.
The problem is I do not know how to do it.
Any help is appreciated on how to properly implement this simple task.
Thanks!
Ok, I found the problem.
It is because of the
<fieldset>
</fieldset>
tag.
The checkbox collection loop is outside of these tags.
Although all of the fields and the Check Boxes are under the html helper "BeginForm"
the checkboxes loop is outside of the tag.
This is the reason why these checkbox's values were never passed back to the controller during post back.
I put the loop inside the tag and viola, they are now populated on the "POST" controller.

Post in MVC only returns editable fields

I'm new to MVC.
I have a partial view with editable fields and not editable fields:
<li>
<b>
#Resource.Field1:
</b>
#model.Field1
</li>
<li>
<b>
#Resource.Field2:
</b>
#Html.TextBoxFor(sb => sb.Field2)
</li>
<input type="image" src="~/Resources/Images/DoSomething.png" border="0" alt="Submit" value="DoSomething" name="DoSomething"/>
The controller function:
[HttpPost]
[MultipleButton]
public ActionResult DoSomething(MyModel myModel)
{
DoSomethingToManipulateTheModel(myModel);
return PartialView("~/Views/MyPartialView.cshtml", myModel);
}
But I have a problem:
In the myModel object, that is passed the doSomething function, only the fields that are editable in the view are filled, all other fields are null. So I can't send the model back to the view because the view will only show the editable values.
Has anybody an idea how I can get all values back without making them all editable?
Store your data in Session, or use HiddenField in Razor.
Like this
#Html.HidddenBox(sb => sb.HiddenVariable)

Cookieless rendering of a side bar with links enabled based on a parameter

I have an MVC 4 site that renders a left sidebar with a bunch of menu links on it. When the user signs in, they are directed to a page where they search for someone. Once they've selected someone and submitted the form, an id cookie gets set.
This id determines whether or not various links in the sidebar menu are enabled, as it is a required parameter for many of the actions that those links lead to. The menu itself, since it is on every page of the site, is set up in the _Layout partial:
<div id="contentwrapper">
<div id="left-menu">
#Html.Action("Display", "Menu", new { Area = "" })
</div>
<div id="mainbody">
<section>
#RenderBody()
</section>
</div>
<div id="footer">
</div>
</div>
Display returns a partial view representing the sidebar menu. Since I'm rendering the menu sidebar in the _Layout, I don't have a model to work with. Is there any way I can get the parameter to my menu partial view without using a cookie?
I would use a hidden field and viewbag
Public ActionResult Index(){
ViewBag.id = // set your id initially
}
if javascript/jquery is ok with you...
$(function(){
var myID = #Html.Raw(Json.Encode(ViewBag.id));
$('#hidID').val(myID);
});
HTML
<input type="hidden" name="hidID" id="hidID" />
Then.. Display Action
Public ActionResult Display(int hidID){
// this will be current id,
// if id is reset , pass the new one to viewbag , jquery will reset hidden field on client
}

Successive submit of my ajax form still give me the same data in my action controller

I use an ajax form for removing items from a list. The first time I submit something, it works but the second times, the reference of the item submitted is not correct: it is the first reference that is still used.
Here is my ajax form:
<div>
<table>
#foreach (var item in Model.ProjectTechnology)
{
<tr>
<td>#Html.DisplayFor(m => item.TechnologyID) </td>
<td>#using (Ajax.BeginForm("RemoveLinkedTechnology", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "AddedTechnologies" })) {
#Html.Hidden("projectID", item.ProjectID)
#Html.Hidden("removedTechnologyID", item.TechnologyID)
<input type="submit" value="Suppr" />
}</td>
</tr>
}
</table>
</div>
Here is the action in my controller:
[HttpPost]
public ActionResult RemoveLinkedTechnology(int projectID, string removedTechnologyID)
{
// some code here...
}
Example:
Lets say I proceed the submitting like this: first submit: AA; second submit: BB.
For the first call: removedTechnologyID contains AA.
For the second call: removedTechnologyID still contains AA.
Any idea?
Thanks
I suspect that in your controller action you are returning a partial view which updates the contents of the <table> you have shown. Now since Html helpers such as Hidden or TextBox first look for values in ModelState before binding and then in the model what happens is that #Html.Hidden("removedTechnologyID", item.TechnologyID) sees that there is a removedTechnologyID="AA" in the model state and completely ignores your model value which is item.TechnologyID. So if you have looked at the DOM after the first AJAX request you would have seen that all hidden fields have the old values inside them.
To fix this you have 3 possibilities:
Clear the item in model state in your controller action:
[HttpPost]
public ActionResult RemoveLinkedTechnology(int projectID, string removedTechnologyID)
{
...
ModelState.Remove("removedTechnologyID");
ModelState.Remove("projectID");
return View(...);
}
Don't use helpers to generate the hidden fields:
<input type="hidden" name="projectID" value="#item.ProjectID" />
<input type="hidden" name="removedTechnologyID" value="#item.TechnologyID" />
Write a custom Html.Hidden helper which will first use the values in the model before looking at modelstate (out of scope for this answer)

Best way to display a search form and its results in the same page?

Suppose I have a simple search form with a textbox. And upon submitting the form I send the contents of the textbox to a stored procedure which returns to me the results. I want the results to be displayed on the same page the form was, except just below it.
Right now I'm doing the following but it's not working out exactly the way I want:
"Index" View of my SearchController
#using (Html.BeginForm("SearchResults", "Search", FormMethod.Post, new { #class = "searchform" }))`{
<fieldset>
<legend>Name</legend>
<div class="editor-label">
#Html.Label("Search")
</div>
<div class="editor-field">
#Html.TextBox("Name")
</div>
<input type="submit" value="Search" class="formbutton" />
</fieldset>
#{ Html.RenderPartial("SearchResults", null);
This is my "SearchResults" View:
#model IEnumerable<MyProject.Models.spSearchName_Result>
<table>
#foreach (var item in Model)
{
<tr>
<td>
#item.Name
</td>
</tr>
}
</table>
This is my Controller:
// GET: /Search/SearchResult
[HttpPost]
public ActionResult SearchResult(FormCollection collection)
{
var result = myentity.spSearchName(collection["Name"]);
return PartialView("SearchResults", result);
}
I can only seem to get the results to display on an entirely new page (not being embedded as a partial view), or I get an error when I load the search page because there are no results (since I hadn't searched yet).
Is there any better way to achieve what I'm trying to do? I feel like I'm going against some of the best practices in MVC.
You could return the results in a ViewData object then only show on the view it if is not null.
Very similar to this question MVC 3 form post and persisting model data
For this instance it looks like you are not passing the results to your partial view. Try this?
#{ Html.RenderPartial("SearchResults", Model.Results);
Since you are not persisting your search information using a model, the search information will be lost when the search form is posted.
Given your design and stated goal, it would be best to convert the form in your Index view into an Ajax form, then your controller can send your partial view back to populate a div below your Ajax form.
counsellorben

Resources