Making Partial View Reusable - asp.net

Say I have a partial view that renders a dropdown list of Applications. When selecting an item in the dropdown it renders another partial view.
This dropdown list exists in a few places in the application but on each page a different partial view needs to be rendered when selecting an application. Is there an easy way to make the dropdown reusable? ie I need to set a different data_url depending on which page the partial view is rendered.
Partial View:
<script type="text/javascript">
$(function () {
$('#ApplicationsDropdownList').change(function () {
var url = $(this).data('url');
var applicationId = $(this).val();
$('#RolesForApplication').load(url, { applicationId: applicationId})
});
});
</script>
<div>
<label for='ApplicationsDropdownList'>Application:</label>
#Html.DropDownListFor(
x => x.SelectedApplicationId,
new SelectList(Model.Applications, "Value", "Text"),
"-- Select Application --",
new
{
id = "ApplicationsDropdownList",
data_url = Url.Action("ViewRolesTableForApplication", "Index")
}
)
</div>
Controller:
public ActionResult ViewRolesTableForApplication(string applicationId)
{
...
return View("_RolesTableForApplicationPartial");
}

You could add a string property containing the data_url to the model that you use for your partial view.
So in addition to the Model containing Applications it will have public string DataUrl { get; set; } as well.

Related

MVC update ListboxFor with selected values from DropDownListFor

I'm currently working on a website in MVC, I have created a partial view with a DropDownListFor everytime a value is selected in the DropDownListFor it goes to the HttpPost and adds the value to a List. I also have a ListBoxFor that is bound to this list.
What I would like to achieve:
Everytime a new value is added to the List with the DropDownListFor it should update the ListBoxFor automatically so the selected value gets added to this Listbox. I wonder what the best way would be to achieve this.
Code:
Submit.cshtml:
<div class="create-ingredient">
#Html.Partial("_CreateIngredient")
</div>
<br/>
<div class="add-ingredient">
#Html.Partial("_AddIngredient")
</div>
<br/>
<div class="ingredient-listbox">
#Html.LabelFor(model => model.Ingredients,"Current Ingredients")
#Html.ListBoxFor(model => model.Ingredients, new MultiSelectList(Model.SelectedIngredients), new { style = "width:50%;" })
</div>
_AddIngredient.cshtml (Partial View):
#model Recepten.Models.IngredientSelectModel
#using (Ajax.BeginForm("AddIngredient", "Recipe", new AjaxOptions() { UpdateTargetId = "add-ingredient", HttpMethod = "Post" }))
{
#Html.LabelFor(model => model.Ingredients, "Add Ingredient")
#Html.DropDownListFor(model => model.SelectedIngredient, Model.Ingredients, "Select Ingredient", new { #onchange = "$(this).parents('form').submit();" })
}
AddIngredient:
[HttpPost]
public ActionResult AddIngredient(IngredientSelectModel ing)
{
ing.SelectedIngredients.Add(ing.SelectedIngredient);
return PartialView(ing);
}
IngredientSelectModel:
public RecipeModel Recipe { get; set; }
public IEnumerable<SelectListItem> Ingredients { get; set; }
public int SelectedIngredient { get; set; }
public string addIngredient { get; set; }
public List<int> SelectedIngredients { get; set; }
public IngredientSelectModel()
{
SelectedIngredients = new List<int>();
}
Thank you for your time!
As I think you've figured, the reason the current approach isn't working is that the IngredientSelectModel created for and updated by the AddIngredient action is separate from the one used to populate the ListBox.
If Ajax and unobtrusive JQuery are set up correctly (the browser URL shouldn't change when you select an ingredient), #pinhead's answer will send the selected value to the action, but SelectedIngredients won't accumulate the values you select because its value isn't included in the ajax data. For that to work you need to change the multi-select to be bound to SelectedIngredients:
#Html.ListBoxFor(
model => model.SelectedIngredients,
new MultiSelectList(Model.SelectedIngredients),
new { style = "width:50%;" })
...and move it inside the form declaration so its value is posted to the action along with the new ingredient to add.
That said, I wouldn't say you're doing enough work to justify a round-trip to the server, so after making the above change you could just add the ingredient entirely on the client side like this:
#Html.DropDownListFor(
model => model.SelectedIngredient,
Model.Ingredients,
"Select Ingredient",
new { #onchange = "$('#SelectedIngredients').append('<option>' + $(this).val() + '</option>')" })
I believe one solution is to move your ListBoxFor helper into your partial view so that it is updated and recreated once your action returns the partial view.
Submit.cshtml:
<div class="create-ingredient">
#Html.Partial("_CreateIngredient")
</div>
<br/>
<div class="add-ingredient">
#Html.Partial("_AddIngredient")
</div>
_AddIngredient.cshtml (Partial View):
#model Recepten.Models.IngredientSelectModel
#using (Ajax.BeginForm("AddIngredient", "Recipe", new AjaxOptions() { UpdateTargetId = "add-ingredient", HttpMethod = "Post" }))
{
#Html.LabelFor(model => model.Ingredients, "Add Ingredient")
#Html.DropDownListFor(model => model.SelectedIngredient, Model.Ingredients, "Select Ingredient", new { #onchange = "$(this).parents('form').submit();" })
}
#Html.LabelFor(model => model.Ingredients,"Current Ingredients")
#Html.ListBoxFor(model => model.Ingredients, new MultiSelectList(Model.SelectedIngredients), new { style = "width:50%;" })

How to set focus on controls inside TabPage in DevExpress MVC tabpage?

I am using DevExpress MVC for my application.In that I am using three TabPages.The content of the Tab Pages are in different Partial Views.My Question is How to set focus on controls in each tab page when the tab page is clicked?
You can try it with Html.RenderAction. For example:
#Html.DevExpress().PageControl(
settings =>
{
settings.Name = "myTabs";
settings.CallbackRouteValues = new { Controller = "Tabs", Action = "CallbackTabs" };
settings.TabPages.Add("Tab1").SetContent(() =>
{
ViewContext.Writer.Write("<div class='tab1Content'>");
Html.RenderAction("GetTab1", "Tabs");
ViewContext.Writer.Write("</div>");
});
settings.TabPages.Add("Tab2").SetContent(() =>
{
ViewContext.Writer.Write("<div class='tab1Content'>");
Html.RenderAction("GetTab2", "Tabs");
ViewContext.Writer.Write("</div>");
});
}
And controller actions:
public ActionResult GetTab1()
{
return PartialView("_Tab1", result);
}
public ActionResult GetTab2()
{
return PartialView("_Tab2", result);
}

MVC 3 Razor not displaying selected item from dropdown list

I have created a form with a dropdown list for 'Region'. Once the form has been submitted I want to be able to view the details from the form. In particular I want the name of the 'Region' to be displayed but I am currently getting the name, ID and labels.
The dropdown list Controller:
public ActionResult Add()
{
var db = new AssociateDBEntities();
var region = db.Regions.Select(r => new { r.RegionId, r.RegionName });
ViewBag.Regions = new SelectList(region.OrderBy(r => r.RegionName).AsEnumerable(), "RegionId", "RegionName");
return View();
}
'Details' Controller:
public ActionResult Details(int id)
{
using (var db = new AssociateDBEntities())
{
ViewData["Region"] = new SelectList(db.Regions.ToList(),"RegionName");
return View(db.Associates.Find(id));
}
}
'Details' View:
<div class="form-grid-1">
<div class="display-label">#Html.LabelFor(model => model.Region)</div>
<div class="display-field">#Html.DisplayFor(model => model.Region)</div>
</div>
How can I just get the name (RegionName) to display?
Just use
#Html.LabelFor(model => model.Region.RegionName)
Or create a DisplayTemplate for Region. Check out
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

Model Binding using many partial views strongly typed contained within a Main View

I have a main View PersonEdit.cshtml bound to a Main class PersonEdit- it is internally a container class for Many Models like BasicInfo, EductaionalInfo, EmploymentInfo etc.
I save all the information on clicking on Submit on the PersonEdit.cshtml. The View is composed of many partial views which are loaded by different Action methods called asynchronously by AJAX.
The problem I am facing is the Model Binding does not happen on clicking on Submit on PersonEdit.cshtml as the names in the Partial views are not the same as expected for Model Binding.
class structure
public class PersonEdit
{
BasicInfo basicInfo { get; set; }
EducationalInfo eduInfo { get; set; }
EmploymentInfo empInfo { get; set; }
}
Kindly suggest me as to how can i accomplish Model Binding in this situation.
I am loading the Partial Views like this:
//Basic Info
$(document).ready(function () {
DisplayBasicInfo();
});
function DisplayBasicInfo() {
var $MainContent = $("#divBasicInfo");
var resourceURL = "/Home/Home/GetBasicInfo";
var personID = $("#PersonEdit_PersonID").val();
personID = 0;
$MainContent.css("text-align", "center");
$.ajax({
cache: false,
type: "GET",
async: true,
url: resourceURL,
dataType: "text/html",
data: { personID: personID },
success: function (data) {
$MainContent.html(data);
$.validator.unobtrusive.parse($("#divBasicInfo"));
},
error: function (xhr) {
$('#divBasicInfo').show().html("Unexpected Error in basic Info- Please contact administrator!");
$("#divBasicInfo").dialog({
modal: true,
width: 'auto',
opacity: 0.7,
height: 'auto',
position: 'center',
title: 'Warning',
buttons: {
'OK': function () { $(this).dialog("close"); }
}
});
}
});
}
I think you are using different partial views for BasicInfo,EducationInfo and EmploymentInfo.
Like
#Html.Partial("partialViewName",Model.basicInfo) in the main view.
Lets your BasicInfo class be like,
class BasicInfo
{
public string FirstName{get;set;}
public string LastName{get;set;}
}
So, in the view (if you will see the source code) the name of properties for BasicInfo will be displayed like "FirstName" or "LastName" instead of "basicInfo.FirstName" and "basicInfo.LastName".So Model binder will not be able to bind it to PersonEdit class.
The solution will be to EditorFor instead of Partial
use,
#Html.EditorFor(m=>m.basicInfo,"editorFileName")
Editor files are same as partial views but will be placed under "EditorTemplates" folder structure.In this the base object property name will be added to property names of BasicInfo properties.

mvc3 partial view error

I want to make a form for entering customer data. It consists of several text boxes and a combobox. And it is the whole problem lies in this combobox. When I trying to render this partialview , gets error: "Object reference not set to an instance of an object."
This is partialview controller code
public PartialViewResult GetStates()
{
var states = from s in conn.order_data select s.state;
return PartialView(states.ToList());
}
GetStates partialview
#model IEnumerable<bookstore.state>
#foreach (var item in Model) {
<select>
<option>#item.STATE_Name</option>
</select>
}
part of main view
<div class="editor-field">
#{Html.RenderPartial("GetStates");}
</div>
Please, help
Unless you are loading the view dynamically (in which case you could do it with jquery get)
here is how you could do it
Controller:
public ActionMethod MainView()
{
var model = new myMainModel { States = from s in conn.order_data select s.state };
return View()
}
Main View:
#Html.Partial("MyPartialViewName", Model.States);
Try this:
if(states != null)
{
return PartialView(states.ToList());
}
return PartialView();

Resources