MVC get data from dynamic field - asp.net-mvc

I'm very new in MVC :(
I created a dynamic form by cloning a principal DIV element and its elements. The elements are combobox, textbox and a date textbox. When I create a new "clone", the DIV every member of itself has an incremental ID like tab_Container, tab_Container_1, text, text1, combo, combo1, etc... Now, I'm trying to get the values of each member in the Divs into the controller.
Googling I find something like this:
[HttpPost]
public ActionResult NewEntry(Model Entry)
{
Control myControl = new Control();
myControl.FindControl("Text0");
if (myControl != null)
{
/// apparently, find the control,here i wanna to get the value of each field !! ¿?
/// do i have to create a list[] ... exist something like Entry.Text0 = myControl.value?
}
else
{
Response.Write("Control not found");
}
return View(Entry);
}
Any suggestion? Is Control the best option? Do I have to do something else in Javascript code?

While it's normally better to have some sort of Model / ViewModel this situation is a bit different. MVC binds on the "Name" property of your form inputs.
So say for instance your razor syntax generates something like this:
<form>
<input type="text" name="input1" />
<input type="text" name="input2" />
<!-- etc etc etc -->
<input type="submit" value="submit" />
</form>
since this is dynamically generated and you don't have a model that would cleanly bind to this. You can use the FormCollection type as the parameter of your action. This gives you a collection of all items posted to the server that you could then loop through or peer into to get the properties that you want.
public ActionResult myAction(FormCollection collection)
{
var value = collection["input1"];
var value2 = collection["input2"];
return View();
}

Related

ASP Net Core - hidden input field data is not passed in the Controller

I need to pass which button is clicked for the form submit. But the hidden input is not received in the controller. Below are my code snippets
View Model:
public class DocumentViewModel
{
public int Id { get; set; }
public int ActionId { get; set; }
}
razor(cshtml):
<form....>
<input id="docActionId" name="docActionId" asp-for="ActionId" type="hidden" value="initialValue" />
</form>
JavaScript:
$("#save_btn").on("click", function ()
{
$("#docActionId").val("test1");
});
$("#submit_btn").on("click", function ()
{
$("#docActionId").val("test2");
});
I tried showing the current value in alert function if it is change and it did.
In my Controller/Action when I debug, I get a null value for the ActionId variable. I think this is very simple but I don't know what I did wrong.
Please help. I'm stucked in this for 2 hours now. Thanks in advance.
remove the "Id" attribute... that's all you need. "asp-for" does that. adding yours duplicates it kind
Remove the name="docActionId" html attributes, they will be generated automatically by Razor.
Specifically by the asp-for="ActionId" attribute.
Furthermore the reason this doesn't work is because the name attribute which is docActionId != ActionId which is the name of the property of your object. So it doesn't know where to bind it to.
<form id="myform">
<input id="docActionId" asp-for="ActionId" type="hidden" value="initialValue" />
<button type="submit" id="save">Submit</button>
</form>
Try this javascript perhaps the form is submitted before you attach the value
var saveButton = documnet.getElementById('save')
saveButton.addEventListener('click', function(e) {
e.stopPropagation();
documnet.getElementById('docActionId').value = "test value"
documnet.getElementById('myform').submit()
})
<input type="hidden" id="tag" >
type="hidden" didn't work for me with .net core 7 but only hidden keyword worked.
<input hidden id="tag">

MVC HTTP Post input return null

Controller:
public ActionResult MyController()
{
ViewBag.DateNow = DateTime.Now.ToString("yyyy-MM-dd");
}
[HTTPPost]
public ActionResult MyController(string fromDate)
{
ViewBag.DateNow = fromDate;
}
View:
#using (Html.BeginForm("MyController", "Account", FormMethod.Post))
{
//datepicker class: bootstrap-datepicker.js
<input id="fromDate" type="text" class="datepicker" />
<buttontype="submit" value="Search" class="btn btn btn-primary">
Search
</button>
}
What I'm trying to achieve is before POST the data that pass into ViewBag.DateNow is the current date and it successfully bring in to the view. However when I'm trying to fill up the input form with (eg: 2016-05-10) and click on the Search button. But seems like the fromDate string return NullReferenceException. I'm trying out with some solution online but I still can't get it right and that's why I decided to get this posted up. Thanks in advance!
For this to work properly you need to specify the name attribute in your textbox. It needs to be the same value as the input variable in your HTTP post action method, namely fromDate. Currently the id attribute is set to fromDate:
<input id="fromDate" name="fromDate" type="text" value="#ViewBag.DateNow" />
If you do not specify this name attribute then when you post your form fromDate will always be null. Specifying it like above will make sure that fromDate will always have a value (if entered).
I want to go a bit off-topic here, I would like to suggest that you make use of view models for your form submissions. Instead of having individual input variables in your action method you can just have your view model as input parameter.
I wrote an answer as to what view models are here, please go and read it if you have the time:
What is ViewModel in MVC?
Working on your example, I would have a view model that contains just one property, namely FromDate. FromDate will contain the value in your textbox. It is setup as a string because you want to pass it a formatted date value:
public class TestModel
{
public string FromDate { get; set; }
}
This value will be set in your HTTP get action method and the view model will be sent to the view:
public ActionResult Index()
{
TestModel model = new TestModel();
model.FromDate = DateTime.Now.ToString("yyyy-MM-dd");
return View(model);
}
In your view you will accept this view model and create the form accordingly:
#model WebApplication_Test.Models.TestModel
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.FromDate)
<button type="submit">Search</button>
}
When you submit this form, you need an HTTP post action method to handle the submission. Because the view is bound to the view model, the action method will accept it as an input parameter:
[HttpPost]
public ActionResult Index(TestModel model)
{
// Do what you need to do
string date = model.FromDate;
return View(model);
}
Your way of doing it is also correct. I have just shown you an alternative way to do it. Some day you might have a huge form with many input values, then my approach will be 'cleaner'.
Try this:
1) Replace with [HttpPost] instead of [HTTPPost]
2) You should add name=" " for input like this:
<input id="fromDate" name="fromDate" type="text" class="datepicker" />

Accessing Data attribute of html input control in MVC2 controller

I am submiiting a form from view which contains input field with specific data attribute
<form>
<input type="text" data-user="001" name="mytext" />
</form>
this from is submitted to a controller
[HttpPost]
public ActionResult Settings(FormCollection formValues)
{
//here i can access input control's value by its name like
string user= formValues["mytext"];
}
but how i can get value of data-user attribute in controller?
I do not think you can do it. You can access session variable from controller like this, however:
string strsetting1 = (string)HttpContext.Session["setting1"];
In your Global.asax.cs:
protected void session_start()
{
Session["setting1"] = "Y";
}

Posting an array of HTML.DropDownList values to controller action method

So in my view I am dynamically creating dropdown lists in a for loop. I use the same name value in unique id values.
#foreach(var item in Model.Items)
{
#Html.DropDownList("Items" Model.GenerateSelectList(item.id), new { id = item.id })
}
In my controller action method for the post I can get the values of the dropdowns like this:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize]
public ActionResult ClassicLineup(IList<int> items)
{
}
I cannot figure out how to get BOTH the dropdown id and associated value.
Seems like it should be simple but it has me stumped...
Thanks.
On form submit browser sends only the selected value of a dropdown, so there is no bult in mechanism to read the text of selected item, but you can create one for you.
In below code i have created a hidden input which stores the text of current selected item, and is send to the server on form post.
You can create below list in controller or in view (preferred place in controller);
var items= (from item in Model.Items
select new SelectListItem
{
Value= item.DisplayProperty
Text= item.Value
}).toList();
<form action="controller/test">
#*This will create DD*#
#Html.DropDownList("MyDropDownList", items)
#*Hidden input*#
<input type="hidden" id="ddSelectedName" name="ddSelectedName" />
<br>
<input type="submit" value="submit"/>
</form>
Include jQuery in ur code and then add this
<script type="text/javascript">
$('#MyDropDownList').change(function () {
$('#ddSelectedName').val($(this).find(':selected').text());
});
</script>
Controller
public string test(string MyDropDownList, string ddSelectedName)
{
return MyDropDownList+ "--"+ddSelectedName ;
}
I just ended up looping through the forms collection and parsing the dropdown id (form.key) and the dropdown value (form.key.value).
Apparently there is not an easy way to have MVC bind the dropdown values and id to a collection in the controller action parameter.

ASP.NET MVC - Dynamic action and parameter for a form

I'm working on a bit of MVC where I'm needing to dynamically route a form to a certain action and parameter combination. So far, I've got this:
PageViewModel
{
public string Action {get;set;}
public string Parameter {get;set;}
/*... other properties for the form */
}
PageController
{
public ViewResult MyAction(string myParamterName) {
return View("CommonView",
new PageViewModel{Action="MyAction", Parameter="myParameterName"));
}
public ViewResult YourAction(string yourParamterName) {
return View("CommonView",
new PageViewModel{Action="YourAction", Parameter="yourParameterName"));
}
/* ... and about 15 more of these */
}
CommonView.aspx:
<%-- ... --%>
<% using (Html.BeginForm(Model.Action,"PageController",FormMethod.Get)) {%>
<%=Html.TextBox(Model.Parameter)%>
<input id="submit" type="submit" value="Submit" />
<%}%>
<%-- ... --%>
This works, but it's got a lot of strings floating around to tell it where to go.
What I'd like to have is a type-safe way of defining the form parameters inside the view, but I'm a bit lost on how to accomplish this. Perhaps something that looks like this -
<% using (Html.BeginForm<PageController>(Model.??ExpressionToGetAction??)) {%>
<%=Html.TextBox(Model.??ExpressionToGetParameter??)%>
<input id="submit" type="submit" value="Submit" />
<%}%>
Or, is there a way to get the action and parameter used to generate this view, perhaps from route data?
Or should there be a custom routing scheme that can handle all of this automagically?
So, what I'm really wanting is the most elegant and type-safe way to accomplish this. Thanks!
EDIT
As Josh points out, the form will submit back to the action. This trims the code somewhat :
PageViewModel
{
public string ParameterName {get;set;}
/*... other properties for the form */
}
PageController
{
public ViewResult MyAction(string myParamterName) {
return View("CommonView",
new PageViewModel{ParameterName ="myParameterName"));
}
public ViewResult YourAction(string yourParamterName) {
return View("CommonView",
new PageViewModel{ParameterName ="yourParameterName"));
}
/* ... and about 15 more of these */
}
CommonView.aspx:
<%-- ... --%>
<% using (Html.BeginForm(FormMethod.Get)) {%>
<%=Html.TextBox(Model.ParameterName)%>
<input id="submit" type="submit" value="Submit" />
<%}%>
<%-- ... --%>
It is still unclear how to have the textbox bind a parameter by name back to the action from which the view was created without explicitly specifying it.
Or, is there a way to get the action and parameter used to generate this view
If you leave the action and controller portion of the BeginForm arguments empty, it will to post back to where it came from. You can have two action with the same name, one decorated as HttpGet and the other HttpPost, as long as they have different parameters. Usually the get has one or none, and the post has several or a model bind.

Resources