How to configure an MVC dropdown depending on which view calls it - asp.net-mvc

I have two views, BatchReceipt and Receipt which utilise the same model. Until now they have used the same display template of ReceiptType. But I want to have one exclude certain items and the other to have the full list (so essentially a second .cshtml display template called ReceiptTypeFull). How do I configure each of these views in Visual Studio to utilise the different Display Templates?
Some additions to show the code being used:
I have file ReceiptType.cshtml being used as a DisplayTemplate which contains the following to setup the receipt dropdown
#using Clinton.Web.Helpers.EnumHelpers
#{
var item = EnumsHelper.GetNameFromEnumValue(Model);
}
I want to use a different DisplayTemplate, call it ReceiptTypeFull.cshtml
#using Clinton.Web.Helpers.EnumHelpersFull
#{
var item = EnumsHelper.GetNameFromEnumValue(Model);
}
#item
The difference is in calling the enumhelper or the enumhelperfull to vary the query populating the dropdown. My problem is that I cannot see how to redirect the view to use the different enumhelper/displaytemplate/
Thanks

I think I understand what you are getting at. You want to control which template is used for an Enum in the view.
I will explain using editor templates but it works the same way if you use display templates. You should be able to follow and apply for your scenario.
The idea is to use this overload of the editor html helper.
public static MvcHtmlString Editor(this HtmlHelper html, string expression, string templateName);
It is called like this
#Html.Editor("{property name}", "{template name}").
Below is an example to show it being used.
Suppose we have this enum
public enum MyItems
{
Item1 = 1,
Item2 = 2,
Item3 = 3
}
This helper
public static class MyEnumHelper
{
public static List<MyItems> GetAllItems()
{
return new List<MyItems>()
{
MyItems.Item1,
MyItems.Item2,
MyItems.Item3
};
}
public static List<MyItems> GetSomeItems()
{
return new List<MyItems>()
{
MyItems.Item1,
MyItems.Item2
};
}
}
This controller
public class HomeController : Controller
{
public ActionResult AllItems()
{
return View();
}
public ActionResult SomeItems()
{
return View();
}
}
We have these 2 editor templates, which are put in views/shared/editortemplates
First one called MyItems.cshtml which is the all one
#model MyItems?
#{
var values = MyEnumHelper.GetAllItems().Cast<object>()
.Select(v => new SelectListItem
{
Selected = v.Equals(Model),
Text = v.ToString(),
Value = v.ToString()
});
}
#Html.DropDownList("", values)
Second one called MyItems2.cshtml which is the some one
#model MyItems?
#{
var values = MyEnumHelper.GetSomeItems().Cast<object>()
.Select(v => new SelectListItem
{
Selected = v.Equals(Model),
Text = v.ToString(),
Value = v.ToString()
});
}
#Html.DropDownList("", values)
Then in the AllItems.cshtml to get the MyItems.cshtml template called we need
#model MyItemsViewModel
#using (Html.BeginForm())
{
#Html.EditorFor(x => x.MyItem)
<submit typeof="submit" value="submit"/>
}
And in the SomeItems.cshtml to get some of the items by calling MyItems2.cshtml we use
#model MyItemsViewModel
#using (Html.BeginForm())
{
#Html.Editor("MyItem", "MyItems2") #* this bit answers your question *#
<submit typeof="submit" value="submit" />
}

Related

How do i retrive dropdownlist using mymodel object

How do i retrive in view dropdownlist using mymodel object
List<object> mymodel = new List<object>();
mymodel.Add(db.Events.ToList());
mymodel.Add(db.Purposes.ToList());
return View(mymodel);
I would recommend creating a Model for your view and also implement few other best practices on the way. Various aspects of the solution will look like below:
In Models folder create a model for your view as below:
public class MyViewModelClass
{
public IEnumerable<SelectListItem> Events { get; set; }
public IEnumerable<SelectListItem> Purposes { get; set; }
}
In your Controller, populate the model for the view and return it to the view as shown below. Note that you should select the two properties for the drop down list. "Value" which will be behind the scene value associated to each item in the drop down and "Text" which will be shown to the end user. Also note that I am returning SelectListItem which I can then later bind with the Drop down list.
MyViewModelClass mymodel = new MyViewModelClass();
mymodel.Events = db.Events.ToList().Select(x =>
new SelectListItem
{
Value = x.EventID.ToString(),
Text = x.EventName
});
mymodel.Purposes = db.Purposes.ToList().Select(x =>
new SelectListItem
{
Value = x.PurposeID.ToString(),
Text = x.PurposeName
});
return View(mymodel);
Now comes the last part, your View. You need to implement three things here:
Inform the view what kind of model to expect.
Create HTML form
Generate the Drop down list
The complete view will look like below for Events drop down:
#model MyViewModelClass
#{
ViewBag.Title = "Home Page";
}
<div>
#using (Html.BeginForm())
{
#Html.DropDownListFor(m=>m.Events,Model.Events,"--select--")
}
</div>

mvc parse and display contents of json in a checkbox

I am new to mvc and this is my requirement. I am developing a page which should render a text and a checkbox. The checkbox will be checked depending on the T/F value from the database. So I am passing all the necessary data from db to the view as Json object in GetData() method.
namespace ClinicalAdvantage.Web.Controllers.UserAppSettingC
{
using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using NHibernate.Mapping;
public class UserAppSettingsController : Controller
{
private readonly IAgg1 agg;
public UserAppSettingsController(IAgg1 agg)
{
this.agg = agg;
}
#region Public Methods and Operators
public ActionResult Index()
{
return this.View();
}
public ActionResult GetData()
{
return new JsonNetResult() { Data = this.agg.GetAllUserAppSettings() };
}
public ActionResult Save(JObject userAppSettings)
{
if (userAppSettings != null)
{
this.agg.SaveAllUserAppSettings(userAppSettings);
}
return this.Json(new { Status = "Success" });
}
#endregion
}
}
I have once tried returning the same data written as a viewmodel as a result of the index(). I had done something like
public ActionResult Index()
{
return this.View(model);
}
And for this I wrote out the in the corresponding view as
#model ClinicalAdvantage.Web.ViewModels.UserAppSettings1.UserAppSettingsViewModel
<form action="#Url.Action("Save")" method="post">
#Html.CheckBoxFor(x => x.IsM, new { maxlength = "50", size = "50" })
<!-- Form content goes here -->
<input type="submit" value="Save" />
</form>
But for some reason I am not using viewmodel to return data. So the above way of coding the veiw might not be right. I am not using GetData() to pass data to the front end and I can't really change this.
public ActionResult GetData() { return new JsonNetResult() { Data = this.agg.GetAllUserAppSettings() }; }
But I want to know how to code the front end to parse this json data when I am returning it as result of GetData method as tyype JsonNetResult.. Where will my view be. What should be the code if I want to display a checkbox and save button. The checkbox will be populated based on value returned by json.
This is the json I am returning
{"MaskPatientName":{"enabled":true,"value":false}}
There should be a label called MaskPatienTName
The check box should be checked if value property is true
On click of save butoon the save method in the controller shld be called.
Please help me
Simplest solution is to pass the populated view model to the view in your Index action
public ViewResult Index()
{
return View(agg.GetAllUserAppSettings());
}
And then your view should look something like this (use the Html helper to create form markup). This assumes that IsM is a property of UserAppSettingsViewModel.
#model ClinicalAdvantage.Web.ViewModels.UserAppSettings1.UserAppSettingsViewModel
#using (Html.BeginForm("Save", "UserAppSettings")) {
#Html.CheckBoxFor(x => x.IsM, new { maxlength = "50", size = "50" })
<!-- Form content goes here -->
<input type="submit" value="Save" />
}

How to get sequence/array index in Editor Template?

Case:
I have a list of items of Class X displayed using Editor Template for Class X.
Problem:
How can I get index of an item being processed on the inside of the Editor Template?
I've been using this HtmlExtension that returns only the needed id of an iteration. It's basically a regex on ViewData.TemplateInfo.HtmlFieldPrefix that's capturing the last number.
public static class HtmlExtensions
public static MvcHtmlString Index(this HtmlHelper html)
{
var prefix = html.ViewData.TemplateInfo.HtmlFieldPrefix;
var m = Regex.Match(prefix, #".+\[(\d+)\]");
if (m.Success && m.Groups.Count == 2)
return MvcHtmlString.Create(m.Groups[1].Value);
return null;
}
}
Can be used in an EditorFor-template like this:
#Html.Index()
Use a for loop instead of for each and pass the indexer into the EditorFor extension; razor should handle the rest.
#for(var i = 0; i < Model.count(); i++)
{
#Html.EditorFor(m => Model.ToArray()[i], new { index = i })
}
Update:
pass in the the index of the item using view data as show above.
In your editor template access the item via the ViewBag
<span> Item Index: #ViewBag.index </span>
Using the EditorTemplate is the best solution when viewing models that contain a list of something.
In order to find the index for the sub-model being rendered you can use the property that Razor sets by default:
ViewData.TemplateInfo.HtmlFieldPrefix
Say, for example, you have the following view models:
public class ParagraphVM
{
public int ParagraphId { get; set; }
public List<LineVM> Lines { get; set; }
}
and
public class LineVM
{
public int Id { get; set; }
public string Text {get; set;}
}
and you want to be able to edit all the "LineVM" within a "ParagraphVM". Then you would use an Editor Template so you would create a view at the following folder (if it doesn't exist) with the same name as the sub-model Views/Shared/EditorTemplates/LineVM.cshtml:
#model MyProject.Web.MVC.ViewModels.Paragraphs.LineVM
#{
//this will give you the List's element like Lines[index_number]
var field = ViewData.TemplateInfo.HtmlFieldPrefix;
}
<div id="#field">
#Html.EditorFor(l => l.Text)
</div>
Assuming you have a Controller's ActionResult that is returning a View and passing a ParagrapghVM viewmodel to a view, for example Views/Paragraph/_Paragraph.cshtml:
#model MyProject.Web.MVC.ViewModels.Paragraphs.ParagraphVM
#using (Html.BeginForm("Details", "Paragraphs", FormMethod.Post))
{
#Html.EditorFor(p => p.Lines)
}
This view would render as many editors for the list Lines as items contains that list.
So if, for example, the property list ParagraphVM.Lines contains 3 items it would render something like:
<div id="#Lines[0]">
<input id="Lines_0__Text name="Lines[0].Text"/>
</div>
<div id="#Lines[1]">
<input id="Lines_1__Text name="Lines[1].Text"/>
</div>
<div id="#Lines[2]">
<input id="Lines_2__Text name="Lines[2].Text"/>
</div>
With that you can know exactly what position each items is within the list and for example use some javascript to create a carousel or whatever you want to do with it. But remember that to edit that list you don't really need to know the position as Razor takes care of it for you. If you post back the model ParagraphVM, the list Lines will have the values bound (if any) without any additional work.
How about:
#using System
#using System.Text.RegularExpressions
var i = Convert.ToInt32(Regex.Matches(
ViewData.TemplateInfo.HtmlFieldPrefix,
#"\[([0-9]+)?\]")[0].Groups[1].ToString());
I think the easiest way is:
#Regex.Match(ViewData.TemplateInfo.HtmlFieldPrefix, #"(?!\[)\d+(?=\])")
Or as helper:
public static string Index(this HtmlHelper html)
{
Match m = Regex.Match(html.ViewData.TemplateInfo.HtmlFieldPrefix, #"(?!\[)\d+(?=\])");
return m.Success ? m.Value : null;
}
Inspired by #Jona and #Ryan Penfold
You can use #Html.NameFor(m => m.AnyField). That expression will output the full name property including the index. You could extract the index there...

get dropdownlist selected value in controller MVC3 Razor

Hi in my MVC3 Project with RAZOR, i Have one doubt.
i have a page named CatlogPage.cshtml. in that page i have a Dropdownlist control.
#(Html.Telerik().DropDownListFor(m => m.CatalogName)
.BindTo(Model.CatalogName).HtmlAttributes(new { style = "width:235px" }))
<input type="submit" value="Next" />
I have a controller named Hierarchy.cs:
in that controller,
public ActionResult Hierarchy()
{
// Need to get the selected value in DropDownList
return View("Hierarchy");
}
How to get the value(CatalogName) from dropDownList to the controller?
This is my model code.
public List<SelectListItem> GetCatalogNameModel()
{
try{
var cat = from s in _entities.Catalogs.ToList()
select new SelectListItem()
{
Text = s.CatalogName,
Value = s.CatalogName
};
return cat.ToList();}
catch (Exception ex)
{
CreateLogFiles.ErrorLog(HttpContext.Current.Server.MapPath("~/Logs/ErrorLog"), ex, "CatalogService", "GetCatlogName");
return null;
}
}
So assuming that the first code snippet is from a strongly typed view (object DatabaseModel.CatalogModel) and that you are submitting the form to the Hierachy method, then passing in a CatalogModel and accessing the CatalogName should be what your after?
i.e.
public ActionResult Hierarchy(DatabaseModel.CatalogModel inputModel)
{
inputModel.CatalogName; //This will be the value from the drop down list
return View("Hierarchy");
}
For DropDownList, I use an Int prop to receive the selected Id. So My answer is:
Add this property to your ViewModel:
public Int32 SelectedCatalogId {get;set;}
And bind it to the DropDownList:
#Html.DropDownListFor(m => m.SelectedCatalogId, Model.GetCatalogNameModel())

How to display and edit fractions in an MVC/Razor View

I am trying to display and edit fractions in an MVC application. Previously in WPF I used the concept of a converter to take a double and format it as a fraction for the user and then take the users input and covert it back to a fraction. What would be the best way to do this in a Razor view?
I Admit it was harder than I thought. I'm still not sure if it's the best way to do it or not, but it works.
I defined a super simple Model:
public class MyModel
{
[DataType("Fraction")] //It's important to define DataType
public double MyDouble { get; set; }
}
and here is my simple controller:
public class HomeController : Controller
{
public ActionResult Index()
{
MyModel ViewModel = new MyModel { MyDouble = 0.06 };
return View(ViewModel);
}
[HttpPost]
public ActionResult Index(MyModel model)
{
// Update db.
// Do what you want to do.
return View(model);
}
}
Index view (\Views\Home\Index.cshtml):
#model MvcApplication1.Models.MyModel
#{ViewBag.Title = "Index";}
#Html.DisplayFor(m => m.MyDouble)
<br />
#using (Html.BeginForm("Index", "Home"))
{
#Html.EditorFor(m => m.MyDouble)
<input type="submit" value="Submit" />
}
<script type="text/javascript">
function fraction_changing(hiddenFieldId, numeratorId, denominatorId) {
var numeratorValue = document.getElementById(numeratorId).value;
var denominatorValue = document.getElementById(denominatorId).value;
var hiddenField = document.getElementById(hiddenFieldId);
hiddenField.value = numeratorValue / denominatorValue;
}
</script>
You will find out about the above Javascript code in just a minute.
Display Template is also so easy. I just used Fraction class (By Syed Mehroz Alam) to convert double values to Fraction.
As you know, Templates (which are Partial Views) should be placed in "DisplayTemplates" and "EditorTemplates" folders under "Views" folder. I prefer to put them in "Views\Shared\" so all other Views are able to use it.
Fraction.cshtml (\Views\Shared**DisplayTemplates\Fraction.cshtml**)
#using Mehroz // Fraction class lives in Mehroz namespace
#inherits System.Web.Mvc.WebViewPage<double>
#{
Fraction fraction = new Fraction(Model);
}
#fraction.Numerator / #fraction.Denominator
Let's now take a look at the tricky part, which is Edit Template.
So here is Fraction.cshtml (\Views\Shared**EditorTemplates\Fraction.cshtml**)
#using Mehroz
#inherits System.Web.Mvc.WebViewPage<double>
#{
Fraction fraction = new Fraction(Model);
string numeratorStr = fraction.Numerator.ToString();
string denominatorStr = fraction.Denominator.ToString();
string unifier = Guid.NewGuid().ToString().Replace('-', '_');
string hiddenFieldElementId = string.Format("hiddenField{0}", unifier);
string numeratorElementId = string.Format("numerator{0}", unifier);
string denominatorElementId = string.Format("denominator{0}", unifier);
string onchangingFunctionSyntax =
string.Format("fraction_changing('{0}', '{1}', '{2}')",
hiddenFieldElementId,
numeratorElementId,
denominatorElementId);
}
#Html.HiddenFor(m => m, new { id = hiddenFieldElementId })
#Html.TextBox("Numerator", numeratorStr,
new { id = numeratorElementId, onchange = onchangingFunctionSyntax }) /
#Html.TextBox("Denominator", denominatorStr,
new { id = denominatorElementId, onchange = onchangingFunctionSyntax })
What this template really do is:
Converting double value (its model) to an instance of Fraction.
Showing numerator and denominator value of the Fraction in separate Text Input.
Recalculate the double value (by Javascript)
Because Javascript code needs unique Id to get an element by document.getElementById(id), our Edit Template has to generate these unique IDs for related elements.
You can download the code here: http://sdrv.ms/MlyDI2
The best and cleanest way to solve your issue is to develop a Display/Edit Template.
Here is a nice article about it:
Overriding DisplayFor and EditorFor to create custom outputs for MVC

Resources