I am just learning MVC and wanted to create a couple radio buttons so that I can tell what radio button user has picked and what has he typed in the text box for it. So I did this in Razor:
#using (Html.BeginForm())
{
#Html.RadioButton("rb_settingsupdate", "UpdateEmail");
#Html.RadioButton("rb_settingsupdate", "UpdateQuestions");
#Html.TextBox("userpassword")
<input type="submit" value="Submit"/>
}
Now in the Controller side I was able to use [HttpPost] on my Index method and use the FormCollection to know which radio button they have chosen and what they have typed. My problem is I don't know where to put some text for each radio button in Razor? The method #Html.RadioButton didn't have parameters for it.
How about just using the html if it is static text?
#using (Html.BeginForm())
{
#Html.RadioButton("rb_settingsupdate", "UpdateEmail"); <label>Update Email</label>
#Html.RadioButton("rb_settingsupdate", "UpdateQuestions"); <label>Update Questions</label>
#Html.TextBox("userpassword")
<input type="submit" value="Submit"/>
}
I would not do it that way if I were you. Use a model instead. But if you want to do it that way, you may do it like this:
Update Email: #Html.RadioButton("rb_settingsupdate", "UpdateEmail");
Update Questions: #Html.RadioButton("rb_settingsupdate", "UpdateQuestions");
If you want to use a model, which I encourage, here is an example.
#using (Html.BeginForm())
{
#Html.RadioButton("rb_settingsupdate", "UpdateEmail");
#Html.RadioButton("rb_settingsupdate", "UpdateQuestions");
#Html.TextBox("userpassword")
<input type="submit" value="Submit"/>
}
In your code above, the second parameter in the RadioButton function (e.g. "UpdateEmail") is the value of the radio button and that is the text that will be displayed.
If you want to display text other that that, use a label.
#Html.Label
In terms of best practices for the future once you have a better understanding of MVC, you should make use of view models and use model binding for posting instead of using the form collection. Model binding is a major strength of MVC, you should start leveraging that as soon as possible.
RadioButtons (and Checkbox as well) don't have a "Text" property, because the input type radio itselfs don't have a text property, as you can see here.
Your code will produce something like this:
<input type="radio" name="rb_settingsupdate" value="UpdateEmail">
So, you have to write a plain Text outside the element, like this:
#Html.RadioButton("rb_settingsupdate", "UpdateEmail") <label>Update Email</label>
And it will turn into this:
<input type="radio" name="rb_settingsupdate" value="UpdateEmail"> <label>Update Email</label>
If you have a Model with DataAnnotations and Display properties, you can do in this way:
#Html.RadioButtonFor(x=> x.RbSettingsUpdate, "UpdateEmail") #Html.LabelFor(x=> x.RbSettingsUpdate)
Related
I have a view where an user can trigger an action that will insert input tags in the page:
The 'Add more' button is tied to a jquery click event.
HTML:
<div id="details">
<label>More details</label>
<input placeholder="Foo" asp-for="">
<input placeholder="Bar" asp-for="">
</div>
<button id="add-details" type="button">Add more</button>
JS:
$("#add-details").click(function(){
$("#details").append(`<input placeholder="Foo" asp-for="">
<input placeholder="Bar" asp-for="">`)
});
Now, I want to bind the <input> tags to a C# Model, in order to retrieve their values in a Controller. But there could be any amount of these tags.
The most convenient way to retrieve them would be as a Dictionary<T>, but I don't know what to put in the asp-for attributes.
So how should my Model look like? What should I put in my asp-for attributes?
Although this answer is not about TagHelpers (which you are using), please read it to give you a background of what you need to do and why.
In your case you will want to add input tags so their names are array-like with indices. For example, below:
<input placeholder="Foo" asp-for="[0].Foo">
<input placeholder="Foo" asp-for="[1].Foo">
will map to a collection and the first item's (index 0) will be the contents of the input tag with asp-for="[0].Foo" and the second item's will be the contents of the input tag with asp-for="[1].Foo".
You controller action method should accept a collection. For example, if you were adding students, then the action method may look like this:
[HttpPost]
public ActionResult Index(List<Student> students) { ... }
Finally, please refer the Expression names and Collections of the docs for more info.
With a partial view containing this line
<input asp-for="Form.FirstName" asp- class="form-control" />
I get the following output
<input id="Form_FirstName" name="Form.FirstName" <!-- more stuff --> >
which means I need to account for that "Form" prefix in my action's definition using a Bind attribute like so
public async Task<IActionResult> SendContactForm([Bind(Prefix = "Form")] ContactFormViewModel model)
I don't really like using the Bind attribute, I think it is very verbose and, being text-base, hard to maintain. I would much rather be able to tell the netcore2 input tag helper to simply omit the prefix when generating the HTML but I couldn't find any built-in solution but I might have missed it ...
I looked for inline tag helper attributes as well as attributes to add to my model but couldn't find anything ...
Is there any trick to remove this prefix or am I stuck with this (ugly) Bind ?
In this situation one option is to use a <partial> that contains your form and use the model attribute to pass your model in.
In your view this would be something like this.
<partial name="PartialName" model="#Model.Form">
In your partial, you would no longer need the prefix in your asp-for expressions.
<input asp-for="FirstName" class="form-control" />
I have a textbox set-up, like so:
#Html.TextBoxFor(m => m.NewVehCode, new {data_id = "" })
When a user selects a vehicle, the description of the vehicle becomes the value of the textbox and the vehicle code (which is what I want to send to DB) becomes the data-id (not full code but I set the values like this):
$("#NewVehCode").val(vehDescription);
$("#NewVehCode").attr("data-id", vehCode);
This all works fine, except for the fact that when I submit, MVC grabs the value of the textbox.
Is there a way I can on submit, get the data-id of that textbox instead of the value?
Note that I'm not using .js to gather the data. Form calls a controller action that sends the model directly to the controller.
There is no way to submit values of "data" properties. I am not sure why you wanted to use data property (is that a requirement or not, not sure). But you can have a hidden property in the form so, when user selects a vehicle, along with data property of text box , update this hidden value. This hidden value will be submitted back to form.
Stephen Muecke's comment helped me trigger this solution:
I've added a hidden textbox to use for the vehicle code, and made the textbox that shows the description a standard textbox with no data binding.
<input id="newVehInput" readonly="readonly" class="longInput" type="text">
#Html.TextBoxFor(m => m.NewVehCode, new { style = "display: none"})
This way I can use the value with no issues:
$("#newVehInput").val(vehDescription);
$("#NewVehCode").val(vehCode);
(Will mark as answer in 2 days)
Add a hidden textbox to your html which you post back on submit
In your model:
public string Id {get;set;}
Render it in the view with a hidden class
And with js.
$("#vehicleList").on("change",function(){
$("#Id").val($vehCode)
})
When you submit the value of id should be set in your model
You can have a hidden field hold the Updated value.
HTML:
<input type="hidden" id="HiddenVehCode" name="HiddenVehCode" Value="0"/>
JS
$("#HiddenVehCode").val(vehDescription);
Note: you should have the model set up so that HiddenVehCode will reach the actionMethod on Form Submit.Something Like,
public int HiddenVehCode {get;set;}
I am working on MVC 5 with C#. I am trying to pass some data from a View to a Controller, using hidden input texts.
On my View, I have this
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<input type="text" name="Client_" hidden value=#clientName>
<input type="submit" value="Insert" class="btn btn-default" />
}
When I click on the Insert button, I receive the value of the Client_ input in the controller. It works perfectly if the value of #clientName is a string without spaces. For example if #clientName is equal to "Hola", I receive "Hola" on the controller HttpPost method. But if the value of the string contains spaces such as "Hola mundo", then I only receive "Hola".
I have used two way for receiving the data on the controller.
As a string parameter called as the hidden input.
Using Request object, like
string test = Request["Client_"].ToString();
None of them work properly. I always get only the first word of the string.
Can some of you kindly tell me what is happening?
Do I have a better way to transfer data from the Views to the Controllers
Let's say I have a div like this:
<div id ="carmodel"></div>
This div gets populated using Javascript 5 seconds after pageload, so it will look like this:
<div id ="carmodel">Audi A4</div>
Now I need to send the text inside the "Carmodel" div to the controller when a form is submitted.
#using (Html.BeginForm("Method", "Controller"))
{
#Html.TextBox("textbox1", "")
#Html.TextBox("textbox2", "")
<input type="submit" value="Subtmit"/>
}
I thought about using a hidden field and posting it together, but I don't know how to populate the hidden field with the text in "Carmodel" div:
#Html.Hidden("carmodelhiden", "");
It seems as if I need to use JQuery to retrieve the text like this:
var value = $("#carmodel").text();
But how do I then send this to the controller?
I also thought about using .ajax to post it but not sure how to handle the value in the controller once it's there, since the ajax method in the controller would be separate from where the form gets posted.
Anybody have any advice?
You need to set the value of the hidden input:
$('#carModelHidden').val(...);
Make sure to put the hidden value between the form using statement. Also, use a strongly typed view to bind with a property in your model.
#using (Html.BeginForm("Method", "Controller"))
{
<div id ="carmodel">
#Html.HiddenFor(model => model.SomeProperty)
</div>
}
#section scripts{
<script>
// Hook into some event and set:
$('#carModelHidden').val(...);
</script>
}