Attaching a hidden text field to a form MVC - asp.net-mvc

This very well may end up being a very silly question in a way but basically I have this "form" in a model that gets attached to my View as the form but I haven't been able to actually pass any data do it from the View. It only has two properties: an Id property and a String property. I've been trying to fill the String property with text from a hidden text box on the page with no luck.
Form code:
public class AllocateListForm
{
public int Id { get; set; }
public virtual string HiddenText { get; set; }
}
Relevant View code:
<% using (Html.BeginForm("SaveExit", "User", new { }, FormMethod.Post, new { id = "selectExitPoints" })) { %>
<fieldset>
<input type="hidden" id="HiddenText" />
</fieldset>
<% } %>
There is JQuery behind the scenes that fills HiddenText with text and I can assure you that it is filling. There is also JQuery behind the scenes that performs an Ajax submission and I can promise you that code works as it is used elsewhere in the application without a problem. When I perform the action that submits the form to the server and I go to my controller code that this points to, I have a breakpoint set so I can go into the console and check if the HiddenText field on the form has any data it is null. Can anybody point me in the right direction?

If you assign the input's name to be "HiddenText" the model binder should pick it up. I'm assuming that your controller action accepts an AllocateListForm as a parameter.
<input type="hidden" name="HiddenText" id="HiddenText" />
You can also use Html Helpers like so:
#Html.HiddenFor(model => model.HiddenText, new { id = "HiddenText" })
EDIT: Add an AllocateListForm as a property of your main model and then change the helper to be #Html.HiddenFor(model => model.MyAllocateListForm.HiddenText)

This should do the trick, if you want to do it the Razor-way.
#Html.HiddenFor(model => model.HiddenText);

Related

MVC 4 Passing model from one controller to view and from view to other controller without users able to edit all fields

Im kinda new in MVC4 and im not able to figure it out.
"CustomViewMOdel" "CustomViewMOdel"
"ControllerX" ----------------> "VIEW" -----------------> "ControllerY"
My problem is that i want to pass my customviewmodel to view (which is working just fine!). In the View im showing some of model's fields to users (which is working fine also). BUT Now i want user, to change ONE field of the models fields and then PASS the WHOLE model to Controller X (with all fields filled, including the field what user was able to change AND other fields what were just shown)
Can anyone give a very simple code example of how to do this?
You can just create a form that posts to another controller:
ControllerX:
public ActionResult DoSomething()
{
return View(new CustomVM());
}
ViewA
#Model CustomViewModel
#using Html.BeginForm("DoSomethingElse", "ControllerY")
{
#Html.EditorFor(vm => vm.SomeProperty)
<input type="submit" value="OK" />
}
ControllerY
public ActionResult DoSomethingElse(CustomViewModel vm)
{
// do something else
}
You can use #Html.HiddenFor(o => o.Property) on the form.
This will not show a property on it.
But the advanced user may change the property through a development console. So you should check all the changes in the ControllerY
Example:
#Html.HiddenFor(o => o.Id)
#Html.HiddenFor(o => o.Name)
#Html.EditorFor(o => o.Description)
<input type="submit" value="OK" />
This will only let the user change a description but still have "id" and "name" on the FormCollection.

Pass an entire model on form submission

I understand that I can use #Html.HiddenFor(m => m.parameter) and when the form is submitted, that parameter will be passed to the controller. My model has many properties.
Is there a shorter way of passing the entire model at once to the controller or must I do it one by one each time?
The model will be passed to the controller in its entirety, but the values of properties that are not bound by input or hidden fields will be lost.
You have to either bind the properties in the form on the client-side, or re-fetch the entity on the server-side.
You seem to be asking for something like #Html.HiddenFor(m => m.Model), and that is not possible. Sorry
One thing to keep in mind, if you have tons of hidden fields, you may be sending more data to the view than you really need. Consider employing view models
For anyone else who looks at this you can do a #Html.EditorForModel() in a hidden div. You'd also have to use #Html.EditorFor(model => model.ObjectProperty) for each object property of the model.
<div hidden="hidden">
#Html.EditorForModel()
#Html.EditorFor(model => model.ObjectProperty)
#Html.EditorFor(model => model.ListOfObjectsProperty)
</div>
The entire model will be posted if you are using a FORM element. Your elements using the Model obviously need to be inside the form element
You can also POST the form yourself say by using JQuery
See this other stack issue for that : jQuery AJAX submit form
Have a close look at the anwser by "Alfrekjv"
This is already built in. Consider this model:
public class MyModel
{
public string PropertyA { get; set; }
public string parameter { get; set; }
}
and now consider this action:
[HttpPost]
public ActionResult PostSomeData(MyModel model)
{
}
MVC will leverage the FormCollection and fill in the MyModel class where it can. If you don't have the PropertyA in the form then it will be null. But since you have an input for the parameter property it will be filled in.
You can check only the properties you want:
if (this.ModelState.IsValidField("Name"))
{
// .....
}
instead of:
if (this.ModelState.IsValid)
{
// .....
}
#using (Ajax.BeginForm("my_function", "my_controller", new AjaxOptions { InsertionMode = InsertionMode.Replace }, mymodel))

How do I set up a check box with ASP MVC in my view?

I have the following class:
public class City {
public string Name { get; set; }
public bool CityValid { get; set; }
}
I know how to set up the name but how can I set up the CityValid field so it acts like a checkbox. I'd like to do this without using HTML helpers.
If you really don't want to use helpers, you would use a normal HTML input tag:
<input type="checkbox" id="CityValid" name="CityValid" value="#Model.CityValid" />
<input type="hidden" id="CityValue_Hidden" name="CityValid" value="false" />
The name attribute has to match your property name so that the model binder will pick it up correctly when you post back to the server.
When you use the helpers, something similar to the above markup will be generated. The hidden field is there so that a value is always sent with the form post data, regardless of whether you check the box or not (if you leave the box unchecked, no value gets sent by default, not even a 'false').
However, unless you're doing something really weird, I'd recommend you stick to using the helpers. Either:
#Html.CheckboxFor(m => m.CityValid)
or
#Html.EditorFor(m => m.CityValid)
In your view you could use the EditorFor helper:
#model City
...
#Html.EditorFor(x => x.CityValid)
The default editor template for a boolean field generates a checkbox.
You could first create it with a HTML-helper, look at the markup that gets created when running the page, and then recreate that markup...

Losing ViewModel Data after POST

I don't see this problem too often but I've got a .cshtml that uses a layout. In the layout I've got:
#using (Html.BeginForm(null, null, FormMethod.Post, new { #class = "someCssClass", #id = "UserForm" }))
{
...rest of the code
}
My main .cshtml using this layout has the model defined at the top as we always do:
#model CarViewModel
#{
Layout = "~/Views/Shared/_CarLayout.cshtml";
}
When It gets back to my action method, I get nulls for all values of the model:
public ActionResult Cars(CarViewModel model)
{
carBL.RemoveCars(model.CarIds, model.DealerId);
...
}
Not sure what I need to do here and why this is happening. Usually I just get it back successfully via autobind. It seems to me when the model is used via RAzor in the markup- that gets posted back fine with the returned ViewModel but if I'm not using those fields, it doesn't...so I assume that's how that works and if I don't use them in mark-up I need to send them back as hidden values then to force the persistence since I am not using x fields from the ViewModel (Which would have automatically persisted those fields if I had used them in the form)?
If the values are not bound to a form field, they will come back null.
in the form use the below for things like ID fields.
#Html.HiddenFor(x => x...)
A quick test, to see if the form is being posted correctly would be to modify the signature of your action:
public ActionResult Cars(FormCollection form)
{
...
}
If form is not populated then you have an issue with the form post. As a side, note you could accomplish this when reviewing the post data of the form with a tool like FireBug, Chrome Dev tools or Fiddler if you prefer.
If the form is posting correctly, then I you should check to make sure the name's of the input fields on the form align with the names of the CarViewModel you are expecting.
Not sure if this has been resolved yet, but this is how I do it (partial code):
#model MyProject.ViewModels.MyViewModel
#using (Html.BeginForm())
{
<table>
<tr>
<td>First Name:</td>
<td>#Html.TextBoxFor(x => x.FirstName, new { maxlength = "50" })
#Html.ValidationMessageFor(x => x.FirstName)
</td>
</tr>
</table>
<button id="btnSave" type="submit">Save</button>
<button id="btnCancel" type="button">Cancel</button>
}
Then my action method to handle the HTTP post request:
[HttpPost]
public ActionResult Create(MyViewModel viewModel)
{
// Check for null on viewModel
// Do what needs to be done
}
Doing it this way should not let you loose your values filled in on the form/view.

Button Event in ASP.NET MVC

I have created view page in MVC like
<%using (Html.BeginForm())
{ %>
<%=LabelHelpers.Label("firstname", "FirstName:")%>
<br/>
<%=Html.TextBox("firstname")%>
<br/><br/>
<%=LabelHelpers.Label("lastname", "Lastname:")%>
<br/>
<%=Html.TextBox("lastname")%>
<br/><br/>
<input type="Button" value="Register"/>
<%} %>
Here I want to write Buttonclick Event ...How and Where should i write?
Your input is of type button - these don't do anything without additional client side code.
If you want to handle the 'event' on the server in a similar way that you would have in ASP.NET, you should convert it to a submit button. Assuming your controller is called 'Account' and your action is called 'Register' your current code would look something like this:
public ViewResult Register()
{
return View();
}
You want to start by passing a model to the view:
public ViewResult Register()
{
var registerModel = new RegisterModel();
return View(registerModel);
}
Your current view is using loosely typed inputs. Since you're passing it a model you can use strongly typed views. Your model should look something like this:
public class RegisterMode
{
public string Firstname { get; set; }
public string Surname { get; set; }
}
To use strongly typed views, change your view to look like this:
<%using (Html.BeginForm())
{ %>
<%=Html.LabelFor(x => x.Firstname)%>
<br/>
<%=Html.TextBoxFor(x => x.Firstname)%>
<br/><br/>
<%=Html.LabelFor(x => x.Surname)%>
<br/>
<%=Html.TextBoxFor(x => x.Surname)%>
<br/><br/>
<input type="submit" value="Register"/>
<%} %>
What we've done is told the view to build labels and text boxes for your RegisterModel type. This will allow the model values to be automatically mapped when you POST the form to the controller.
Do accept the post, we need to add a new Action to the controller, with the same name, but accepting a parameter of type RegisterModel:
public ActionResult Register(RegisterModel model)
{
// do something with the model, such as inserting it into the database.
// model.Firstname will contain the value of the firstname textbox
// model.Surname will contain the value of the surnaem textbox
return RedirectToAction("Success");
}
One last thing to do, to be safe, is to add the [HttpGet] and [HttpPost] attributes to your controller actions to control the methods they accept:
[HttpGet]
public ViewResult Register()
and
[HttpPost]
public ActionResult Register(RegisterModel model)
I suggest you read up on MVC at http://www.asp.net/mvc and read the NerdDinner tutorial chapter in Professional MVC (available for free online in PDF format).
joining to the question, want to make it more concrete
i have a form, the form already has a submit button, but i need to bind an additional action to another button.
yes, i do know that MVC does not support events 'cause HTML forms doesn't support them.
so the solution i've came to is to create to hidden inputs inside the form and bind an 'onclick' event (jquery 'live' method) to every... oh, what the hell? here is the code:
html:
<input type="hidden" id="SenderControlID" name="SenderControlID" value="-1" />
<input type="hidden" id="SenderControlValue" name="SenderControlValue" value="-1" />
js:
if ($('#SenderControlID')[0]) {
$('input[type="submit"], input[type="button"], input[type="checkbox"], input[type="radio"]').live('click', function () {
$('#SenderControlID').val($(this).attr('name'));
$('#SenderControlValue').val($(this).val());
});
}
but maybe there is more elegant solution?

Resources