Add controls dynamically on button click in asp.net mvc - asp.net-mvc

I am creating an asp.net MVC application in which I want to provide a functionality to add a controls dynamically. I have a form in which there are 2 text boxes for First Name and Last name which serve as a single control. Now an user can add any number of this group of controls. I am able to add these controls on the page using java script. But I do not know how to access the values of these control when the user submits.
Please help in this or suggest another approach
Thanks

Look at using a Jquery AJAX call for the submit operation.
You can interate through your controls (easy with jquery class selector and $.each) and push the variables into a js variable.
Parse it as JSON and pass the data back to the controller using the ajax call..

Have a read of the article Editing a variable length list, ASP.NET MVC 2-style by Steve Sanderson. It shows you how to do what you are looking for in a clean, MVC style.

If you're coming from a webforms perspective, you're accustomed to adding those new controls programmatically in the codebehind. Using ASP.NET MVC, you're better off doing this with javascript.
It should be trivial to write a javascript function that adds FirstName1, FirstName2, FirstName3, etc. In the Controller, inspect the Request.Form.AllKeys to determine how many fields were added by the user.
You could also iterate a number in a hidden field called "txtNumFields", then use that as your controlling value in a for loop:
int numFields = int.Parse(Request.Form["txtNumFields"]);
for (i==0;i<numFields ;i++)
{
string firstName = Request.Form["FirstName" + i.ToString()];
...
}

Related

"Next" Button disabled until values are selected and typed in DropDownLists and Textboxes in MVC?

I am using MVC-Viewmodel, EF model first on my project.
I have 3 DropDonLista and a few TextBoxes in my View, User can select Values in the DropDownLists and Type inside the TextBoxes. I want that my "Next" button is disabled until values are selected and textboxes are filled then it gets enabled.
How can I easiest way accomplish this?
I've done this kind of things with C# Winforms and its pretty easy but in MVC I have no clue how I can do this.
Thanks in Advance!
You would need to use a client side scripting language like JavaScript. JQuery (a framework to make JavaScript easier to use) is now integrated in to MVC3+, so implementing it is much easier than it has been in the past.
You can target HTML DOM elements (HTML tags in your page, in layman terms) in jquery using "selectors" - i.e. if you want to access a HTML textbox called "test" in your form, and check the value, you can do the following:
var value = $("#test").val();
if(value == '') {
// do something
}
JavaScript syntax is strikingly similar to C#, but it works on the client side (it's processed by the browser), rather than the server.
you can use javascript/jquery to check if values are selected and textboxes are filled then enable the next button.

ASP.NET MVC - Complicated view logic

I'm making the transition from webforms to MVC (I know, 3 years late) and I "get it" for the most part, but there's a few things I'd like advice and clarification on:
First off, what happens if you want to dynamically add inputs to a view? for example, in an old webform for generating invoices I had a button with a server-side click event handler that added an extra 5 invoice item rows. The stateful nature of webforms meant the server handled the POST event "safely" without altering the rest of the page.
In MVC I can't think how I'd do this without using client-side scripting (not a showstopper, but I would like to support clients that don't have scripting enabled).
The second problem relates to the invoices example. If my Model has a List, how should I be generating inputs for it?
I know data binding is a possible solution, but I dint like surrendering control.
Finally, back to the "stateful pages" concept - say I've got a Dashboard page that has a calendar on it (I wrote my own calendar Control class, the control itself is stateless, but can use the webform viewstate to store paging information) - how could a user page through the calendar months? Obviously POST is inappropriate, so it would have to be with GET with a querystring parameter - how can I do this in MVC? (don't say AJAX).
Thanks!
In MVC you design your actions to accommodate your needs. For example, if you wanted to be able to add 5 rows to an invoice NOT using client-side scripting, you'd probably have your GET action for the invoice generation take a nullable int parameter for the number of rows. Store the current number of rows in the view model for the page and generate a link on the page to your GET action that has the parameter value set to 5 more than the current value. The user clicks the link and the GET view generates the page with the requested number of rows.
Controller
[HttpGet]
public ActionResult Invoice( int? rows )
{
rows = rows ?? 5; // probably you'd pull the default from a configuration
...
viewModel.CurrentRows = rows;
return View( viewModel );
}
View
#Html.ActionLink( "Add 5 Lines", "invoice", new { rows = Model.CurrentRows + 5 }, new { #class = "add-rows" } )
You would probably also add some script to the page that intercepts the click handler and does the same thing via the script that your action would do so that in the general case the user doesn't have to do a round trip to the server.
<script type="text/javascript">
$(function() {
$('.add-rows').click( function() {
...add additional inputs to the invoice...
return false; // abort the request
});
});
</script>
Likewise for your calendar. The general idea is you put enough information in your view model to generate all the actions that you want to perform from your view. Construct the links or forms (yes you can have multiple forms!) in your view to do the action. Use parameters to communicate to the controller/action what needs to be done. In the rare case where you need to retain state between actions, say when performing a wizard that takes multiple actions, you can store the information in the session or use TempData (which uses the session).
For things like a calendar you'd need the current date and the current view type (month/day/year). From that you can construct an action that takes you to the next month/day/year. For a paged list you need the current page, the current sort column and direction, the number of items per page, and the number of pages. Using this information you can construct your paging links that call back to actions expecting those parameters which simply do the right thing for the parameters with which they are called.
Lastly, don't fear AJAX, embrace it. It's not always appropriate (you can't upload files with it, for example), but your users will appreciate an AJAX-enabled interface.
In MVC you can store application state in various ways. In your controller you have direct access to the Session object and you can also store state to the database.
your view can contain basic control flow logic, so, if your model has a list you can iterate over it in the view and, for example, render an input control for each item in the list. you could also set a variable in a model to be the maximum number of rows on the viewpage and then render a row in a table for the number specified by the model.
paging is basically the same thing. you can create a partial view (user control in the webform world) that shows page numbers as links, where each link calls an action that fetches the data for that page of results.
i'm not sure what your beef is with ajax or javascript

Providing data to Menu in my ASP.NET MVC Master Page

We are beginning the process of moving from Web Forms to MVC for all of our new applications. I am working on porting our Master Page over and am trying to satisfy the requirements that we need a single master page to be used by all applications. The primary navigation for the application needs to be in a menu within the master page. Accomplishing this was easy, the hard part is that each application may need to determine what to display in the menu using a unique set of rules. Some apps can simply say, here's the menu structure to use via something like a SiteMap. Others need to determine what is displayed in the menu based on what roles the user has, this can also be handled easily with a SiteMap. The situation that I'm struggling with is that some apps need to generate the menus based on the roles the user has, but also on the data on which they are working. i.e. The same user may have different option in the menu for a page if they are working on object 'foo' than they do if working on object 'bar'.
What I've done at this point, is I've created an HtmlHelper that is called by the master page view and takes a list of objects of a custom type and returns an unordered list that is styled by a jQuery plugin to display the menu. The list of objects the helper method takes are passed to the view using the ViewData dictionary. Currently, the value of this ViewData node is set within the constructor of each controller. This allows each page, and potentially each method, to set a different menu without having to set the value in each action method, unless its needed. I have also created a class that parses a SiteMap and returns the list of items needed to build the menu. This class is what I'm using to set the ViewData value in the controller. The idea being that if an application needed more control of how the menu data was generated, they could create their own class to generate the data as long as it returns a list of the correct type of objects.
This solution seems to work fine so far, it just doesn't 'feel' right for some reason. I'm hoping that I can either get some ideas of better way to do this or some reassurance that this is a valid approach to solving this problem.
If it is something that will be on every page, do something like this:
Create a base controller:
public class MyBaseController : Controller
Have this controller get the data it needs and send that data in the ViewData["menu"] to the View. Then have all your controllers inherit from this one:
public class HomeController : MyBaseController
In the Master Page, loop through your ViewData and create your menu.
(I did something like this for my sub-menu which displayed a list of categories.)
In the book I am reading (Pro ASP.NET MVC Framework by Apress) they use Html.RenderAction for the menu in the masterpage. I am a Asp.net MVC novice so maybe somebody else can give more info about this.
You can download the sourcecode at apress.com though so maybe that could help.

ASP .NET MVC: Html.Radiobutton onclick -- set ViewData[""]

I'm new to ASP .NET MVC and to web programming in general.
I'm wondering if there is a way to set ViewData variables when a radiobutton is selected -- but before the page is submitted.
Maybe I'm barking up the wrong tree but what I'm trying to do is create a form where new fields are added based on which radio button is selected. So what I want to do is when a radiobutton is clicked it sets a ViewData variable and based on that ViewData variable a different partial view loads the appropriate fields below the current field.
I imagine there must be someway of doing a onclick="some C# function that sets ViewData(args)"
Thanks
There are a couple of ways you could go about this.
1) You could have an Ajax form where through Javascript you post the form back and check to see if it's an Ajax Request, there by returning a partial view to a div that you specify.
2) Post the form as is and check server-side to see if the radio button was clicked, and thus redisplay the form with the new options visible.
If you take the first approach it would be easy enough to fall through to the second one for those without Javascript enabled.
There aren't really "onclick" events as I'm assuming you are used to from Webforms, you would basically have to roll your own Javascript to handle such things. Once you do a few, I think you'll find it's really not too bad, with the benefit that you'll have more control over what you're doing and through that gain a better understanding of the larger picture.
ViewData only exists, and only exists server-side, for the lifetime of the request. So, once the page is rendered the object no longer exists.
Some alternate approaches you can take:
1 - Use client-side Javascript to add a form and inputs as necessary. More info here:
ASP.NET MVC & JQuery Dynamic Form Content
2 - Pre-render the new form, but hide it via CSS, and unhide it when the appropriate radio button is clicked. More info here:
expand collapse html field Firefox
3 - Use AJAX to render the new form when the appropriate radio button is clicked. More info here:
http://www.asp.net/learn/mvc/tutorial-32-cs.aspx

Naming of ASP.NET controls inside User Controls with ASP.NET MVC

I am wondering if there is a way to make ASP.NET controls play nicely with my ASP.NET MVC app. Here is what I am doing.
I have an order page which displays info about a single Order object. The page will normally have a bunch of rows of data, each row representing an OrderItem object. Each row is an ASP.NET User Control. On the user control there is a form element with two text boxes (Quantity and Price), and an update button.
When I click the update button, I expect the form to post the data for that individual OrderItem row to a controller method and update the OrderItem record in the database.
Here is my problem: When the post happens, the framework complains because the fields on the form don't match the parameters on the controller method. Each form field is something like "OrderItem_1$Quantity" or "OrderItem_2$Price" instead of just "Quantity" or "Price" which would match my method parameters.
I have been told that I can overcome this by making sure that the IDs of all my controls are unique for the page, but allow the NAMEs to be repeated between different forms, so that if a form for an individual row is posted, the name can be something that will match what is on my controller method.
The only problem is that I am using ASP.NET controls for my text boxes (which I REALLY want to continue doing) and I can't find any way to override the name field. There is no Name propery on an ASP.NET control, and even when I try to set it using the Attributes accessor property by saying "control.Attributes["Name"] = "Price";" it just adds another name= attribute to the HTML tag which doesn't work.
Does any one know how I can make this work? I really don't like all of the HtmlHelper functions like TextBox and DropDown because I hate having my .aspx be so PHP or ASP like with the <%%> tags and everything. Thanks!
I think you're straddled between two worlds of ASP.NET WebForms and ASP.NET MVC. You really need to use the Html.TextBox methods, etc. in MVC. This gives you complete control over the markup, which is one of the main benefits of MVC.
The very problem you're having with control over the generated HTML, e.g. getting two name attributes, is exactly what MVC is designed to address. If you stop fighting it and go with the flow, it'll work much better.
<% %> tags aren't a problem unless you have logic in there. Putting simple presentation logic on your view is fine.
If you don't like this, then maybe it's better to stick with standard ASP.NET.

Resources