Dropdown list in mvc having some issues - c#

I have two models called channels and programs.. in showing the dropdown of channels and all I want is that when I select any channel, the view will show the programs of the specific channel. Problem is when I select any channel, it takes the value of channel and return it to the controller and apply filtering logic and pass the data to the new View..Although the view is executing all values properly on the browser it is not visible.. any help would be grateful.
View Code:
#model SitefinityWebApp.Mvc.Models.Channel
#Html.DropDownListFor(m => m.Title, Model.Items, "Select Channel-", new { #id = "ddl" })
<div id="myddl">
</div>
<script>
$('#ddl').change(function () {
var selectedValue = $('#ddl').val();
$.post('#Url.Action("GetProgramByChannel", "Channels")', { selection : selectedValue }, function (data) {
});
});
</script>
GetProgramByChannel Method Taking the selected value
public ActionResult GetProgramByChannel(string selection)
{
var model = new ProgramsModel();
return View("ProgramsByChannel", model.GetChildItemsOfChannel(selection));
}
ProgramsByChannelView
#model SitefinityWebApp.Mvc.Models.Channel
<div id="ddl">
#foreach (var item in Model.Programs)
{
#Html.DisplayFor(m => item.Title) <br />
#Html.DisplayFor(m => item.ShortDescription) <br />
#Html.DisplayFor(m => item.LongDescription) <br />
}
</div>

Because,with your current code, when user make a selection on the dropdown, you are making an ajax call and the result (the new view result with channels will come as the response for this ajax call) is not being used anywhere.
Instead of doing the ajax call, you can make a new GET request to the action method which will return the view.
$('#ddl').change(function () {
var v = $(this).val();
var url ='#Url.Action("GetProgramByChannel", "Channels")?selection='+v;
window.location.href=url;
});
If you do not want to issue a new GET request,but want to show the result in the same view, then all you have to do is update the DOM with the results coming back from the ajax call.
$('#ddl').change(function () {
var v = $(this).val();
var url ='#Url.Action("GetProgramByChannel", "Channels")';
$.post(url, { selection : v} ,function(result){
$("#myddl").html(result); //update the myddl div
});
});
Now you have to make sure that your action method return a view without layout as you are looking for the partial page result. You can use the PartialView method to do so.
public ActionResult GetProgramByChannel(string selection)
{
var model = new ProgramsModel();
return PartialView("ProgramsByChannel", model.GetChildItemsOfChannel(selection));
}
Also, I see you are overwriting the Id value of dropdown to ddl. Why would you do that ? What is wrong with Title being the Id value of the SELECT element ? If you do not override, the helper will generate the SELECT element with Title as the value of Id and name attributes

Related

Assigning a Model Property to a textbox using jQuery

I'm unsure if this is possible but I want to use jQuery to assign value from my bound model to different textboxes inside a PartialView.
Originally when the page loads, it populates correctly with all of the model information. However I would like to implement a DDL to view historical updates (retrieved from my pre-populated DB).
I am able to call an Action method inside my respective controller which accepts a revisionID. I have verified that the method is returning the correct data.
Please see below for my code snippets:
Partial View:
$('#revisionDDL').change(function () {
var selectedRevisionID = $(this).val();
if (selectedRevisionID == '') {
selectedRevisionID = #Model.RevisionID - 1;
}
var url = '#Url.Action("GetAgreementByRevision")';
$.get(url, { revisionID: selectedRevisionID }, function () {
$('#ChangeReason').val('#Model.ChangeReason');
})
});
Input element:
<div class="input-group">
<span class="input-group-addon" id="change-reason">Change Reason</span>
#Html.TextAreaFor(m => m.ChangeReason, new { #class = "form-control", #rows = "1" })
</div>
Controller method:
public ActionResult GetAgreementByRevision(int revisionID)
{
Agreement revisedAgreement = new Agreement();
revisedAgreement = _agreementService.GetAgreementDetailsByRevision(revisionID);
return PartialView("AgreementDetailsFormPartial", revisedAgreement);
}
If I am not able to accomplish this, what would be my other options?
Your method in the controller returns PartialView which returns HTML content and you're trying to pass that HTML content as a value in the text area - this is not how it should work. You should return Json(revisedAgreement, JsonRequestBehavior.AllowGet); and then access this object in JavaScript.
$.get(url, { revisionID: selectedRevisionID }, function (data) {
// 'data' is your Agreement object
$('#ChangeReason').val(data.SomePropertyHere);
});

Pass values from Hidden field to ActionLink then to Controller

I'm trying to dynamically set the StudentIds by letting the user select check boxes for the reports they want. When they click the ActionLink, I use jQuery to set the values of the ids in a hidden field. I need the Action Link to read the ids from hidden field.
The values are getting set in the hidden field, but they are not being passed to the controller from the actionLink.
I need to pass the ReportIds to the controller.
#Html.ActionLink("PrintMed", "GetMedEdVerificationReport", "Student", new { studentIdList = Model.ReportIds }, new { #class = "button print_selected print_selectedMedEd disabled" })
#Html.HiddenFor(model => model.ReportIds)
javascript
$('.print_selectedMedEd').bind('click', function () {
var ids = getPrintIds();
if (ids.length == 0) {
return false;
}
$('#ReportIds').val(ids.toString());
return true;
});
When the asp.net mvc render your ActionLink it will generate a link with a parameter that you have on the model. Event you change the value of the model, it will not change the value on the output generated by ActionLink.
Given this, you have to se again the value, try to generate an ACtionLink without the argument:
#Html.ActionLink("PrintMed", "GetMedEdVerificationReport", "Student", null, new { #class = "button print_selected print_selectedMedEd disabled" })
On the javascript side, you could try using the on method to bind a event handler and call the preventDefault method from the event argument, for sample:
$('.print_selectedMedEd').on('click', function (e) {
e.preventDefault();
var ids = getPrintIds();
if (ids.length > 0) {
$('##Html.IdFor(model => model.ReportIds)').val(ids.toString());
// make an url to redirect
var url = $(this).prop("href") + "?studentIdList=" + ids.toString();
// redirect using the generated url
window.location.href = url;
}
});
Remember to use the Html.IdForm() to make sure you have the right id for a specific property.
That is because #Html.ActionLinkdoesn't use the hidden fields to make the request. Once the action link renders it becomes
PrintMed
so you would need to modify the html on the anchor tag.
You should be using Html.Beginform instead in order to pass along the model.
#using (Html.BeginForm("GetMedEdVerificationReport", "Student", FormMethod.Post, null))
{
#Html.HiddenFor(model => model.ReportIds)
<input type="submit" value="PrintMed" />
}
#Html.HiddenFor(modelItem => item.OrderId)
<td>
<input type="button" value="Pickup" onclick="location.href='#Url.Action("Edit", "Assignment", new { ID = item.OrderId })'" />

How do I instantly get updated value of dropdown box selected item in C# MVC?

I have a list of "practices" that I need to filter on based on user selection. My view has a dropdown that looks like this:
#Html.DropDownList("practice", (List<SelectListItem>)ViewBag.PracticeList)
It allows the user to select one of 6 or so practices to filter another list on. I need to retrieve the value and have the page updated. I have the page filling with the valued by default without mind to the practice filter, I just can't update it because I can't seem to retrieve the value. I just need to get this value so I can incorporate it into my loop to rebuild the list.
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.User.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.Email)
</td>
<td>
#Html.TextBox("Hours")
</td>
</tr>
}
You can also use #Ajax.BeginForm and in the action of the controller return partial view and render it on the client side in the success handler of the ajax form.
Here a post on #Ajax.BeginForm
Using Ajax.BeginForm in MVC4
But you will have to have a jquery script that submits the form on your select change event.
Start by using jquery to capture a change in the select:
$('#selectList').on('change', function() {
})
fiddle
then, ajax to a controller that will return your other items:
$.ajax({
url: '#Url.Action("Action","Controller")',
data: { 'selection' : $(this).val() },
type: "post",
cache: false,
success: function (items) {
//update the other select
};
});
Using Razor:
#using (Ajax.BeginForm("Action", "Controller", new AjaxOptions {UpdateTargetId = "DivToUpdate"}))
{
#Html.DropDownList("practice", (List<SelectListItem>)ViewBag.PracticeList, new { onchange="this.form.submit()"})
}
you could then return the dropdownlist from your controller, or however you want to handle that.
EDIT
Actually, I don't think you'll be able to use the Ajax.BeginForm approach as you would have nested forms. You may be stuck with jQuery
You can use AjaxBeginFormfor like this:
#model YourModel
#using (Ajax.BeginForm("Action", "Controller", null,
new AjaxOptions { HttpMethod = "POST",
OnSuccess = "functionIfYouWant(data)",
UpdateTargetId = "divid",
InsertionMode=InsertionMode.InsertAfter},
new { id = "formId" }))
{
#Html.DropDownListFor(c=>c.SelectedVal, (List<SelectListItem>)ViewBag.PracticeList)
<div id="divId">
</div>
<input type="submit" value="Submit"/>
//or add #Html.DropDownListFor(c=>c.SelectedVal, // List<SelectListItem>)ViewBag.PracticeList,new {onChange="jQuery("#formId").submit()"})
}
Now you can post model to controller and the returned content will be appended to content of div that have id="divId"
Hope you understand what I was trying to explain .
Also try to avoid ViewBag in your aplciation is not good practice.Try to use SelectlistItem in your model to populate dropdown.
so suppose you have your model:
public class Model
{
public int SelectedItem{get;set;}
public IList<DropDownObj> ListObj{get;set;
public IList<SelectListItem> SelectListItemListObj{get;set;}
{
get
{
var list = (from item in ListObj
select new SelectListItem()
{
Text = item.Id.ToString(CultureInfo.InvariantCulture),
Value item.Name
}).ToList();
return list;
}
set{}
}
}
public class DropDownObj
{
public int Id{get;set;}
public string Name{get;set;
}
In controller you will need to set(populate from db or from somewhere ) your list of DropDownObj.
and in view you will be able to do something like this :
#Html.DropDownListFor(c=>c.SelectedItem,Model.SelectListItemListObj)
This is how mvc dropdownlsit should look in mvc.

How to postback to a controller function when a value is selected from dropdown

I have created a dropdownlist on the view and showing a list.
#Html.DropDownListFor(m => m.SelectedId, new SelectList(Model.List, "ID", "Name"))
I want to refresh the page when the user selects the value from the drop down.
I don't know how to map the selection event from dropdown to a controller function without clicking any button.
On the view load there is a controller function which is populating the view with the list.
public ActionResult Populate()
{
List<string> list = get it from sql server
ViewModel viewModel = new ViewModel();
viewModel.list = list;
return view();
}
But how do you call a controller function which will take the selected value as an Id and retrieves the data and refreshes the page with the result.
You can't do it without javascript help. Just bind on select event and send the form or make an ajax request.
using jQuery:
$('#yourDropDownId').change(function(){
$('#yourFormId').submit();
});
or if you need ajax call insted of submit use $.post or $.get.
Add this to your layout in the head:
<script type="text/javascript">
$(document).ready(function () {
$('select:[autopostback=true],input[type=checkbox]:[autopostback=true],input[type=radio]:[autopostback=true]').live('change',function () {
$(this).closest('form').submit();
});
});
</script>
in your view:
#using (Html.BeginForm())
{
#Html.DropDownListFor(m => m.SelectedId, new SelectList(Model.List, "ID", "Name"), new { autopostback = "true" })
}
The form that your dropdownlist is in will get submitted when you change selection of your dropdownlist. If the result of the action of that form is the same page, it will be reloaded with whatever stuff being updated
$(document).ready(function() {
$("#ddl").change(function() {
var strSelected = "";
$("#ddl option:selected").each(function() {
strSelected += $(this)[0].value;
});
var url = "/Home/MyAction/" + strSelected;
$.post(url, function(data) {
// do something if necessary
});
});
});
or
<%=Html.DropDownListFor(m => m.SelectedId, new SelectList(Model.List, "ID", "Name"), new { onchange="this.form.submit();" })%>
It's simple. In your javascript you have:
$(document).ready(function () {
$('#SelectedId').change(function () {
var id = $(this).val();
$.getJSON("/YourController/YourAction", { id: id},
function (data) {
$("#SomeDivSelector").html(data);
});
});
});
Your controller should look like:
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult YourAction(int id)
{
//do something
return Json(ControlToString("~/Views/YourController/YourView.cshtml", yourModelWithData), JsonRequestBehavior.AllowGet);
}
And ControlToString is defined:
private string ControlToString(string controlPath, object model)
{
//CshtmlView control = new CshtmlView(controlPath);
RazorView control = new RazorView(this.ControllerContext, controlPath, null, false, null);
this.ViewData.Model = model;
using (System.Web.UI.HtmlTextWriter writer = new System.Web.UI.HtmlTextWriter(new System.IO.StringWriter()))
{
control.Render(new ViewContext(this.ControllerContext, control, this.ViewData, this.TempData, writer), writer);
string value = ((System.IO.StringWriter)writer.InnerWriter).ToString();
return value;
}
}
Regards.
What you want to apply, against the concept of the technology you're using.
MVC based on ASP.NET technology, but another way executing. MVC not use better of life cycle of ASP.NET, so, does not "Postback". MVC - in the root based on architectural pattern, that allows to separate the different layers of any system, therefore approach to the development on current technology is completely different. learn more about MVC: http://www.asp.net/mvc
if you want still implement your problem you can use ASP.NET concept and use AutoPostback property of DropDownList control.

DataBinding a DropDownList in ASP.NET MVC 2

I'm extremely frustrated trying to switch to MVC after a couple years of webforms development.
Here's my extremely simple problem that I can't manage to solve:
I have a list of States in a table called StateProvince.
I have a DropDownList.
I want the DropDownList to display all of the States.
Keep it simple, I know nothing about MVC.
Here's what I have. All this gives me is a DropDownList filled with "System.Web.Mvc.SelectListItem".
Action:
public ActionResult Create()
{
var dbTimecard = new TimecardDbDataContext();
IEnumerable<SelectListItem> stateProvinces = dbTimecard.StateProvinces.Select(p => new SelectListItem
{
Value = p.StateProvinceId.ToString(),
Text = p.Name
});
SelectList theList = new SelectList(stateProvinces);
ViewData["StateProvince"] = theList;
return View();
}
View:
<div class="editor-label">
<%: Html.LabelFor(model => model.StateProvinceId) %>
</div>
<div class="editor-field">
<%: Html.DropDownListFor(model => model.StateProvinceId, (SelectList)ViewData["StateProvince"])%>
<%: Html.ValidationMessageFor(model => model.StateProvinceId) %>
</div>
Here is what I was looking for:
Action:
public ActionResult Create()
{
var dbTimecard = new TimecardDbDataContext();
IEnumerable<SelectListItem> stateProvinces = dbTimecard.StateProvinces.Select(p => new SelectListItem
{
Value = p.StateProvinceId.ToString(),
Text = p.Name
});
ViewData["StateProvince"] = stateProvinces;
return View();
}
View:
<div class="editor-field">
<%: Html.DropDownListFor(model => model.StateProvinceId, (IEnumerable<SelectListItem>)ViewData["StateProvince"])%>
<%: Html.ValidationMessageFor(model => model.StateProvinceId) %>
</div>
Try replacing this
SelectList theList = new SelectList(stateProvinces);
with this...
SelectList theList = new SelectList(stateProvinces, "Value", "Text");
Common browsers don't support PUT verb within HTML forms. You might need to handle this using ajax:
$(function() {
// when some button is clicked:
$('#someButton').click(function() {
$.ajax({
url: '/controller/action',
data: { selectedState: $('#StateProvinceId').val() },
type: 'PUT',
success: function(data) {
alert('state successfully submitted');
}
});
return false;
});
});
When the data is posted, the items listed in the DropDown are not posted back to the model so I am assuming you are not fetching them again and re-adding them to your model before returning your model back to the view.
You need to make sure on your post that you are filling Model.StateProvinces and then passing it to your View. Only the values are persisted unlike WebForms which would maintain the DropDownList items in the ViewState and rebuild them for you.
So assuming your controller looks something like:
// POST: /YourController/YourAction/{ID}
[HttpPost]
public ActionResult YourAction(YourModel model, int id)
{
// model.StateProvinceId has the selected value
// you need to fill StateProvinces since it is empty as the list is not posted
// back so it is not autofilled into your model.
model.StateProvinces = LoadYourStateProvincesList();
// This would blow up if StateProvinces is null because your View is assuming that
// it has a valid list of StateProvinces in it to build the DropDown
return View(model);
}
I actually asked a question a while back that might be of some use to help explain how to handle DropDown lists:
Best way of implementing DropDownList in ASP.NET MVC 2?
EDIT: Based on your comment it you are not even getting the first list up... well it looks like you might not have your model setup correctly. Do you even have a model? Your create is just returning View() with no model data in it. You need to create a Model and return it.
Eg.
public class YourModel
{
public int StateProvinceId { get; set; }
/// ... whatever else you need
}
// Then in your view your controller you need to set it and create it
View(new YourModel() { StateProvinceId = 123 };);
You need the model so that when the form IS posted back you can retrieve the value because MVC will stuff the value into your model like th example I posted above regarding the POST part.
EDIT: Ok now that question is clearer and a lot simpler than the original question was making the problem out to be. The problem is your SelectList needs tell it which fields to put where:
SelectList theList = new SelectList(stateProvinces, "Value", "Text");
In your original question you had:
<%: Html.DropDownListFor(model => model.StateProvinceId, new SelectList(Model.StateProvinces, "StateProvinceId", "Name") )%>
Which was totally correct but it was how you were building up Model.StateProvinces that was wrong so it threw me off thinking it had to be something else.

Categories