Passing HTML table information from MVC view to controller? - c#

Is there a "best" (or preferred) way to pass information from an HTML table in an ASP.Net MVC view to a controller? I am working with MVC2, and if I stick with using the Context objects (mainly Request.Form[::variables::], I'm at a loss as to how to retrieve information presented in the view using the table/table cell structure. The table I am working with has a check box corresponding to each row of data, and I want to make the data from "checked" rows available to the controller. The following quick fixes come to mind:
1) Since the table in question has a check box, and HTML elements of type "input" have the "id" attribute, the data values could be stored in some kind of concatenated string in the "id" attribute for the check box.
2) Similar to the above misuse of the check box "id" attribute, the data values could be stored in the "text" attribute for a text (textbox) input element.
...but that all seems really klugey, even if it does work. I am relatively new to the field of web programming/development (although not new to programming), so if anyone can suggest alternate methods and/or technologies (I'm open to trying stuff via JavaScript, etc) I would appreciate it. I would appreciate even just links to relevant tutorials (or, related StackOverflow posts I may have missed). :-p

If you have a form like this:
<form action="." method="POST">
<table>
<tbody>
<tr>
<td>
<input type="checkbox" name="checkedValues" value="1" />
</td>
</tr>
<tr>
<td>
<input type="checkbox" name="checkedValues" value="2" />
</td>
</tr>
<tr>
<td>
<input type="checkbox" name="checkedValues" value="3" />
</td>
</tr>
</tbody>
</table>
</form>
That will map to this parameter in your controller action when a post occurs, where the values of the checked boxes are stored in the checkedValues array:
public ActionResult MyAction(int[] checkedValues)
{
}
The values of the check boxes can be strings as well, if that's preferred.

Related

Keeping values in textboxes permanently until changed by user in a sharepoint webpart

I am working on a Visual Web Part for a SharePoint 2013 site that is a "scoreboard" for people to track progress on a project. Basically what I have is a lot of textboxes that users will enter values in. I want the values to stay in the textbox until someone changes it.
<tr>
<td> </td>
<td>A-Crew</td>
<td>B-Crew</td>
<td>C-Crew</td>
<td>D-Crew</td>
</tr>
<tr>
<td>Daily</td>
<td>
<input id="msaCrewDaily" type="text" />
</td>
<td>
<input id="msbCrewDaily" type="text" />
</td>
<td>
<input id="mscCrewDaily" type="text" />
</td>
<td>
<input id="msdCrewDaily" type="text" />
</td>
</tr>
A few things I have tried are using PHP inside the input tag to save the value but it doesn't keep it after closing and re-opening the page with webpart on it. I've thought about using local storage but i'm not sure if that will work.
My Question
Is there a way to keep the the input even if the page is closed? If not would it be better to set up a list as a Data Source? Is the something I could do in C# to keep the values?
Other Information
This is a temporary solution until a database is set up then the values will come from there. However its going to take some time to set that up. Also as of now all my code is HTML and CSS. Any help or ideas are very much appreciated and thank you in advanced!!!
So my understanding is each user opens the page and edits the value right? Then why not create a simple list with the required columns you create one item with default 0 values/or whatever you want. And send the display Item form url to all the users. Whoever wants to edit, will just click on edit and save the form. You can in fact just add this on the page enabling the inline editing and share the page with others.
You can use local storage "jStorage" write a javascript which will be called onkey of textbox and store value on local storage and call it on page load. Just check on page load if local storage contains any value if yes then set the textbox with that value

Model binding nested collections in editor templates

I have an editor template that I use for a view model, EditFeeContentViewModel. This view model holds a collection that's added/removed through JavaScript. I'm adding the following HTML via microtemplating for whenever a new item is added so the model binding will work:
<script id="feeContentTemplate" type="text/html">
<tr id='RowContentId<%= ContentId%>'>
<td>
<input type="hidden" name="ContentFeeViewModels.Index" value="<%= ContentId%>"/>
<input type="hidden" name="ContentFeeViewModels[<%= ContentId%>].ContentId" value="<%= ContentId%>" />
<%= ContentId%>
</td>
<td><input type="hidden" name="ContentFeeViewModels[<%= ContentId%>].ContentName" value="<%= ContentName%>" />
<%= ContentName%>
</td>
<td><input type="text" name="ContentFeeViewModels[<%= ContentId%>].Allocation" value="<%= Allocation%>" /></td>
<td><input type="text" name="ContentFeeViewModels[<%= ContentId%>].Comments" value="<%= Comments%>"/></td>
<td>Remove</td>
</tr>
</script>
Now, this works fine for when my view model isn't nested. It submits to the controller, has all of the data intact, etc.
However, when it's nested, obviously the name is no longer correct and the model binding fails. Instead of ContentFeeViewModels.Index, I might need FeeContents.ContentFeeViewModels.Index.
Since this is being done through JavaScript, I don't know how I could use the HTML helpers to generate the names correctly. How can I find out if/where the view model is nested and generate a string to represent its location so the modelbinding happens correctly?
I thought about manually setting a string in EditFeeContentViewModel that a parent view model could set to represent the property name, but that seems cumbersome and error prone. Is there a better approach to this?
I figured out that you could use ViewData.TemplateInfo.HtmlFieldPrefix to get the path value.
So my code now looks like:
var contentFeeModelPrefix = "";
if ("#ViewData.TemplateInfo.HtmlFieldPrefix" != "") {
contentFeeModelPrefix = "#ViewData.TemplateInfo.HtmlFieldPrefix" + ".";
}
I can then use that variable in my JavaScript as the prefix to the various fields.

Can I pass a different value as a input from using button but display something else in MVC3

I have a list of button which has to display the number of comments as the value of the button. But when I click the button I want to send/pass the comment Id to the method that is submitted. Is there a way to achieve this kind of thing?
Edited:
What I did was, In the table That I have list of buttons
#foreach(var s in Model.List)
{
<tr>
<td style="text-align:left;">#s.ID</td>
<td style="text-align:center;">#s.CD</td>
<td style="text-align:center;">#s.DE</td>
<td style="text-align:center;">
<input class="xxxxx" style="text-align:center;" type="submit" name="count" value ="#s.k" />
<input type="hidden" name="SupportID" value="#s.ID" />
</td>
</tr>
}
This is passing the S.ID to the controller method, But it is not intuitive and I feel that is not the best method to do it.
Do you need to pass anything else apart from the ID ?
If not then you can just use a simple anchor and set the URL to be something like
href="/Page/Method/#s.ID"
and create the method that accepts the ID.
Alternatively you can use jQuery to do an AJAX call to the method, you will then have access to any attributes on the button element to then use in the AJAX Call.

Maintaining state in MVC 3

I am simply devloping entry form using mvc 3. I have many text boxes,radio button, lables. so while post back data from view to controller it loses entered data. how to retain this for all postbacks? is there any mvc mechanisam avialable by default? which means by enabling some properties do we command mvc to handle state by itself?
i am not interested to send viewdata object to view. except that what is default mechanism availble in mvc3?
Update:
#using (Html.BeginForm())
{
<table>
<tr>
<td>
#Html.TextBox("txtTitle")
#Html.CheckBox("chkOption")
</td>
<td>
#Html.TextBox("txtDetails")
#Html.DropDownList("drpList")
</td>
<td>
<input type="submit" value="Cancel" name="action" />
<input type="submit" value="Create" name="action" />
</td>
</tr>
</table>
}
How to maintain state for entered and selected value for all post backs?
You could use Session to persist state across multiple postbacks.
It looks like you need to create a Model and use the #Html.TextBoxFor(), #Html.CheckBoxFor() and #Html.DropdownListFor() methods instead, on the properties of your model.
You would then have a similarly named action method, decorated with a [HttpPost] attribute and the model as a parameter. You will then be able to perform validation on attempted form submissions and process the model if the form state is valid.
I'd look into researching strongly typed views, models and maybe go through a few online tutorials.
The link included below seems a good tutorial, it's a few pages long, but should go through everything you need to get started.
http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/cs/intro-to-aspnet-mvc-3

Reading dynamically generated HTML element value in codebehind in ASP.NET

I have an asp.net page where I have the below markup. Basically this markup is generated from codebehind by reading records from a table and looping through them. For each record in table, there will be a div block.
Basically this form is to read/show settings for a user. The settings entries are stored in a table.
<div id='divContainer' runat='server'>
<div id='div1' runat='server'>
<table>
<tr>
<th>Name</th>
<td><input type='text' id='txtName1' value='something' /></td>
</tr>
</table>
</div>
<div id='div2' runat='server'>
<table>
<tr>
<th>Domain name</th>
<td><input type='text' id='txtName2' value='something' /></td>
</tr>
</table>
</div>
<div id='div3' runat='server'>
<table>
<tr>
<th>URL</th>
<td><input type='text' id='txtName3' value='something' /></td>
</tr>
</table>
</div>
<div id='div4' runat='server'>
<table>
<tr>
<th>Some other value is enabled ?</th>
<td><input type='checkbox' id='chk4' /></td>
</tr>
</table>
</div>
</div>
The id's of each input element will be unique. Now in codebehind I want to read the values of each input element to save the changes user made. How can I read the elements here? Since the mark up is generated in codebehind as a string and appended the the INNER HTML of the external div, I can't read values like we do for a control which we drag and drop in the IDE.
If these are being sent back to the page in a standard HTTP POST then you can read the values in the Request.Form NameValueCollection.
Essentially, all of the server controls that become form elements get translated into standard HTML form elements just as you have there, albeit with more markup generated by .NET to help it identify them. Then it automatically maps their values back to the server controls for you on the postback, but the values themselves are still just in a standard HTTP POST, which you can access manually.
(This is also a common method used when posting a form from one ASP .NET application to another.)
If you want to grab your values for the generated controls you have to do 2 things.
Generate the input controls with a runat='server' tag for each control (otherwise they will not be included in the Request.Forms collection.) This is probably the step your missing.
<input type='text' id='txtName1' runat='server' value='something' />
Grab your values from the Request.Form collection on postback
string txtValue1 = Request.Form["txtName1"];
It really should be that easy. I tested this against your code using a DIV as the container and a simple javascript to inject the control string into the innerHTML. If your getting any issues you may have to debug and see if the dynamic control ID has changed due to inserting them into naming container or something.
So the brunt of the story is that when you dynamically add a control after Page_Init then POSTBACK values can not be inserted back into those controls.
CF: http://www.15seconds.com/issue/020102.htm and http://msdn.microsoft.com/en-us/library/ms178472.aspx
Some of the other answers here suggest "oh, add a runat=server to the control" but when you create it in the codebehind, and not in the Page_Init, then that makes ZERO difference.
Let me know if that's not how you're creating the controls or if that's not how you're using them and I'll revise this answer on more details. It really all boils down to how you're trying to access the values.
Generally, you'd place those input controls you're creating dynamically (in this case, a TextBox) inside something like a panel control (the container). Then after the user has posted their data, you'd loop that container panel.Controls collection and retrieve each TextBox text.
Be aware that some caveats apply when working with dynamically created controls because ASP is of stateless nature.
This page shows how to implement this:
Adding Dynamic Rows in ASP.Net GridView Control with TextBoxes
I didn't test it but I can suggest that:
Add your dynamic controls with runat="server" tag inside another controls with runat="server"(such as panel control). Then you can access them like this:
Textbox t = (Textbox)panel1.controls.findControl("dynamicControlId");

Categories