Ok so I have an Html.DropDownList and I want to be able to execute a controller method ActionResult output(string test) and send a parameter to it. I have something like this already but I get an Uncaught TypeError: Cannot set property 'action' of null message:
#Html.DropDownList(
"revisions", ViewData["revisions"] as SelectList,
new
{
onchange = "this.form.action = '/Shops/output('test')'; this.form.submit();"
})
How do I go about fixing my code?
If your Action method's parameter name is id,
public ActionResult output(string id)
{
//do something
}
then you may use your form action url like this.(The default routing will take care of rest)
/Shops/output/somestringhere.
If you have a different name, use that as the query string
public ActionResult output(string name)
{
//do something
}
Now use your form action url like
/Shops/output?name=somestringhere
Another suggestion about your code is to avoid Viewdata for rendering the dropdown. Try to use strongly typed view model and it's properties for transfering data to your view. Also try to move your javascript from your view and make it unobutrusive. So that your view stays as clean markup only.
Assuming you want to show a Revision dropdown in a document create view, Add a property to your viewmodel to have the dropdown items.
public class DocumentCreateViewModel
{
//Other properties also here
public List<SelectListItem> Revisions{ set;get;}
public int SelectedRevision { set;get;}
public DocumentCreateViewModel()
{
Revisions=new List<SelectListItem>();
}
}
and in your GET action, fill the dropdown content to the Revisions property.
public ActionResult Create()
{
var vm=new DocumentCreateViewModel();
vm.Revisions=GetRevisionItemsFromSomeWhere();
return View(vm);
}
And in your strongly typed view,
#model DocumentCreateViewModel
#using(Html.Beginform())
{
#Html.DropDownListFor(x => x.SelectedRevision,
new SelectList(Model.Revisions,"Value","Text"), "Select..")
<input type="submit" />
}
Now to handle the form submit on change event of dropdown, add this script.
$(function(){
$("#SelectedRevision").change(function(){
var _this=$(this);
var selectedRevision=_this.val();
$("form#YourFormIDHere")
.attr("action","./Shops/output/"+selectedRevision).submit();
});
});
Instead of hardcoding the url to shops/output, you may use the razor helper method(#Url.Action) to get the proper path.
#Html.DropDownList(
"revisions", ViewData["revisions"] as SelectList,
new
{
onchange = "submitForm();"
})
and your Javacript goes here
function submitForm()
{
var form = document.forms[0];
form = '/Shops/output?test=test';
form.submit();
}
Related
I'm totally new to ASP.NET and MVC architecture. I have a controller function and it is something like this.
public ActionResult Calculate()
{
var Message = "Hello There!";
return Content(Message);
}
I need to set this return value to a text box in a view..
if the name of the textbox is "text3", how can I do that?
Thanks in advance.
First, create a ViewModel to hold the message.
public class CalculateViewModel {
public string Message { get; set; }
}
Create a cshtml file to serve as View for this ViewModel. By convention, this file should be named like the action that renders it, i.e. Calculate.cshtml, and be placed in a folder with the name of the controller under Views\.
#model CalculateViewModel
#* render textbox for "Message" property in ViewModel *#
#Html.TextBoxFor(m => m.Message)
Note that this will render an <input name="Message" />. If you want the textbox to be named "text3", the property in the ViewModel should be named "text3" instead of "Message".
In the controller action, return a View with the correctly initialized ViewModel:
[HttpGet]
public ActionResult Calculate() {
var vm = new CalculateViewModel {
Message = "Hello There!";
};
return View("Calculate", vm);
}
I am a new to ASP.NET MVC, I am developing an application. I want to bind the data in the drop down list in create view.
How to bind the data in the drop down? I have go through many question and answers here...
I have seen usually everyone suggested to use List<SelectListItem> what is its purpose?
Do I need to use ViewModel while binding the data to drop down list?
Can I get simple example where data get bind in the dropdown using viewbag?
I have created a list in controller
List<string> items = new List<string>();
and I want to pass this list to view using viewbag and simply want to bind to drop down list.
How to do this ?
I'd suggest using a ViewModel as it makes interaction with user input so much easier. Here's an example of how you might bind data from your ViewModel to a drop down in your View. First, the ViewModel:
public class CrowdViewModel
{
public string SelectedPerson { get; set;}
public IEnumerable<SelectListItem> People { get; set; }
}
So yes, you're right - use a collection of SelectListItems. I'm guessing in your case, the SelectListItem's Value and Text property will be the same. You could turn your List into IEnumerable like this:
[HttpGet]
public ActionResult Home()
{
// get your list of strings somehow
// ...
var viewModel = new CrowdViewModel
{
People = items.Select(x => new SelectListItem { Text = x, Value = x })
}
return View(viewModel);
}
Now you need to bind that ViewModel's property to the DropDown on your view. If you're using the Razor ViewEngine, the code will look something like this:
#model MyApp.ViewModels.CrowdViewModel
#using (Html.BeginForm())
{
#Html.DropDownListFor(model => model.SelectedPerson, Model.People)
}
Now when you post that form, MVC will bind the selected value to the ViewModel's SelectedPerson property!
[HttpPost]
public ActionResult Home(CrowdViewModel viewModel)
{
// viewModel.SelectedPerson == whatever the user selected
// ...
}
Easy as that!
Update:
If you really want to use the ViewBag (don't do it), you can pass your list through from your Controller action like so:
[HttpGet]
public ActionResult Home()
{
ViewBag.People = new List<string> { "Bob", "Harry", "John" };
return View();
}
And then create a SelectList on your View:
#Html.DropDownList("SelectedPerson", new SelectList(ViewBag.People, Model))
This may sound simple but i am stuck up at a very strange problem.
I have created dropdown's in my application and i am not able to fetch the selected value On Edit.
Here is my View:
<div class="editor-field">
#Html.DropDownListFor(model => model.Hobbyhome.HobbyHomeAddressList.First().ProvincialState.ProvincialStateID, new SelectList(ViewBag.State, "ProvincialStateID", "ProvincialStateName"), "-----Select State-----", new { #id = "State" })<font color="red">*</font>
</div>
i have written a function in controller to fetch the value and i am also able to fetch the value but when it goes in View it doesnot show me the value
i have created another dropdown like this:
#Html.DropDownListFor(model => model.Hobbydetail.Hobbymaster.HobbyId, new SelectList(ViewBag.Hobby, "HobbyId", "HobbyName"), "----Select Hobby----", new { #id = "Hobby" })<font color="red">*</font>
And the strange thing is i can see the value of the second dropdown but not for first One
What i think is maybe because i am using an list.First() in the first dropdown and so it isgiving this problem bcoz On edit view page it only shows me "-----Select State--" as value for first dropdown.
Please Help me
To get the "selected value object" in you edit view :
#Html.DropDownListFor(model => model.Hobbydetail.Hobbymaster.HobbyId,
new SelectList(ViewBag.Hobby, "HobbyId", "HobbyName", Model.Hobbydetail.Hobbymaster.HobbyId),
"----Select Hobby----", new { #id = "Hobby" })
To have all elements in your DropDown, be sure that your ViewBag.Hobby is initialized and filled in your controller before showing Edit view!
First() method returns the first element of a sequence. It will throw you an exception if the source sequence is empty.
Why you need to use First() there ? I think you are doing it in the wrong way. your first paramenter of DropDownListFor should be a variable which holds the selected value, in this purticular overload you are using.
public static MvcHtmlString DropDownList(
this HtmlHelper htmlHelper,
string name,
IEnumerable<SelectListItem> selectList,
IDictionary<string, Object> htmlAttributes
)
name : The name of the form field to return.
You should be using the second approach
I would make a clean ViewModel to handle this. This makes my Views Clean.
public class AddHobbyViewModel
{
public int SelectedHobbyId { set;get;}
public IEnumerable<Hobby> Hobbys { set;get;}
//other relevant properties for the View.
}
In the GET action method, Instead of returning the data in ViewBag, I would return it in the ViewModel.
public ActionResult Add()
{
AddHobbyViewModel model=new AddHobbyViewModel ();
model.Hobbys=db.Hobbies(); // get all available hobbies.
return View(model);
}
And in the View,
#Html.DropDownListFor(model => SelectedHobbyId , new SelectList(Hobbys , "HobbyId", "HobbyName"), "----Select Hobby----", new { #id = "Hobby" })
Now you will have the selected value available in your httppost mehod in the SelectedHobbyId property
[HttpPost]
public ActionResult Add(AddHobbyViewModel model)
{
// check model.SelectedHobbyId here
}
Below Scenario, I think I must see the START text in my form when first loaded.
When I click send data button and submit, I was waiting to see FINISH text in my form.
Buy the START text never changes when I click the button and post the form...
Anybody can tell the problem?
MY CONTROLLER:
namespace MvcApplication1.Controllers
{
public class BuyController : Controller
{
public ActionResult Index(BuyModel model)
{
if (Request.HttpMethod == "GET")
{
model.Message= "START";
return View(model);
}
else
{
BuyModel newModel = new BuyModel();
newModel.Message= "FINISH";
return View(newModel);
}
}
}
}
MY VIEW :
#model MvcApplication1.Models.BuyModel
#using (Html.BeginForm("Index", "Buy", FormMethod.Post))
{
#Html.TextBoxFor(s => s.Message)
<button type="submit" >Send</button>
}
MY MODEL:
public class BuyModel
{
public string Message { get; set; }
}
public class BuyController : Controller
{
public ActionResult Index()
{
BuyModel model = new BuyModel();
model.Message= "START";
return View(model);
}
[HttpPost]
public ActionResult Index(BuyModel model)
{
model = new BuyModel();
model.Message= "FINISH";
ModelState.Clear(); // the fix
return View(model);
}
}
View:
#model MvcApplication1.Models.BuyModel
#using (Html.BeginForm("Index", "Buy"))
{
#Html.TextBoxFor(s => s.Message)
<button type="submit" >Send</button>
}
Your issue is because your original code, that Action Method will only be executed as an HTTP GET request. ASP.NET MVC allows you to specify a post with the [HttpPost] attribute (see above code).
I'm not sure what you are getting at with your POST desired-behavior. It seems like you are just wiping out whatever form values are pushed on the POST. So modify my above code accordingly, but it should give you the general idea.
Edit: it seems to be that the text box is retaining its value after the POST. It's not just with "START", but if you type anything into that text box and hit submit, you'll have a POST with the exact same text in the text box that was there when you submitted the form.
Edit Edit: see the changed code. Call ModelState.Clear() in your POST action method and you'll have the right value reflected.
If you are posting, and not returning a RedirectResult, by default the helpers will use the value from ModelState. You either need to clear ModelState or have a different approach.
The PRG (post redirect get) pattern in MVC is very important. So if its a post, and you aren't redirecting, the helpers assume there is an error that needs to be corrected and the value is pulled from ModelState.
In asp.net mvc3 how to keep dropdown list selected item after postback.
Do something Like this :
[HttpPost]
public ActionResult Create(FormCollection collection)
{ if (TryUpdateModel(yourmodel))
{ //your logic
return RedirectToAction("Index");
}
int selectedvalue = Convert.ToInt32(collection["selectedValue"]);
ViewData["dropdownlist"] = new SelectList(getAllEvents.ToList(), "EventID", "Name", selectedvalue);// your dropdownlist
return View();
}
And in the View:
<%: Html.DropDownListFor(model => model.ProductID, (SelectList)ViewData["dropdownlist"])%>
Even easier, you can include the name(s) of your dropdowns in your ActionResult input parameters. Your dropdowns should be in form tags. When the ActionResult is posted to, ASP.Net will iterate through querystrings, form values and cookies. As long as you include your dropdown names, the selected values will be preserved.
Here I have a form with 3 dropdowns that posts to an ActionResult. The dropdown names are (non-case sensitive): ReportName, Year, and Month.
//MAKE SURE TO ACCEPT THE VALUES FOR REPORTNAME, YEAR, AND MONTH SO THAT THEY PERSIST IN THE DROPDOWNS EVEN AFTER POST!!!!
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ReportSelection(string reportName, string year, string month)
{
PopulateFilterDrowdowns();
return View("NameOfMyView");
}
MVC does not use ViewState, which means you will need to manage the value persistence yourself. Typically this is done through your model. So, given that you have a view model, e.g.:
public class MyViewModel { }
And your controller:
public class MyController : Controller
{
public ActionResult Something()
{
return View(new MyViewModel());
}
public ActionResult Something(MyViewModel model)
{
if (!ModelState.IsValid)
return View(model);
return RedirectToAction("Index");
}
}
Now, when you pass the model back to the view with data (probably incorrect - failed validation), when you use your DropDownListFor method, just pass in the value:
#Model.DropDownListFor(m => m.Whatever, new SelectList(...))
... etc.
MVC's model binding will take care of the reading of the data into your model, you just need to ensure you pass that back to the view to show the same value again.
Assuming the selected item is part of the post, the controller now knows what it is. Simply have an entry in the ViewData dictionary indicating which item should be selected (null on get or if nothing was selected). In the view, check the value and if it's not null, select the appropriate option.
Use HttpRequestBase object.
In the view, this should work:
#Html.DropDownList("mydropdown", ViewBag.Itens as IEnumerable<SelectListItem>, new { value = Request["mydropdown"] })
If you are building the drop down list data source in the controller Action Method you can send the selected value to it
Controller:
public ActionResult Index( int serviceid=0)
{
// build the drop down list data source
List<Service> services = db.Service.ToList();
services.Insert(0, new Service() { ServiceID = 0, ServiceName = "All" });
// serviceid is the selected value you want to maintain
ViewBag.ServicesList = new SelectList(services, "ServiceID", "ServiceName",serviceid);
if (serviceid == 0)
{
//do something
}
else
{
// do another thing
}
return View();
}
View:
//ServiceList is coming from ViewBag
#Html.DropDownList("ServicesList", null, htmlAttributes: new { #class = "form-control" })