I want to set enum in datatable ColumnProperty of nopcommerce 4.4.
I tried things like
new ColumnProperty(nameof(await(((TransmitEnumStatus)Model.StatusId).ToSelectListAsync())))
{
Title = T("Admin.Catalog.TransmitProduct.Fields.DriverNo").Text
},
but didnt work it.
Is enum has applied in nopcommerce datatable column property? if yes then in which form?
Or else how can I implement enum in datatable column property.
You can take a look at the src/Presentation/Nop.Web/Areas/Admin/Views/Log/List.cshtml file for an example usage of an Enum column:
new ColumnProperty(nameof(LogModel.LogLevel))
{
Title = T("Admin.System.Log.Fields.LogLevel").Text,
Width = "100"
},
Also, the src/Presentation/Nop.Web.Framework/Models/DataTables/ColumnProperty.cs file has a reference:
/// <summary>
/// Set the data source for the column from the rows data object / array.
/// See also "https://datatables.net/reference/option/columns.data"
/// </summary>
public string Data { get; set; }
According to your needs, you might also use the Render property in the .cshtml file and set it to a javascript function to render your desired html to the user: (there are different examples present if you search for Render in cshtml files)
Render = new RenderCustom("render_function_name")
// render_function_name should be a javascript function present in the same cshtml file
Related
I got a simple POJO class that i wish to display / update in a form
Using the BeanItem class and the binding of component data, i was able to quickly display the first attributes of may data class. However i've hit a wall for tow related attributes :
my class posses a set of available status, as a list of object 'AppStatus'. it also possess a current status, that is one of the status in the 'available' list.
I would like to display the list in the form as a combobox, with the current status selected.
I'we managed to associate the 'available' attribute with a combobox, but i can't seem to be able to fill this combobox when setting the data source (method setItemDataSource). How do i get the avalaible status list and the current status from my Item ?
I could always use a workaround and add a parameter to the method to get the source objet in addition to the BeanItem, but i would prefer to avoid this if the Item properties can give me my attribute.
Regards
Edit : shortened exemple, with code from Eric R.
class Status {
String id;
Sting label
+ setter /getter
}
class App {
String AppId;
String AppLabel
ArrayList<Status> availablestatus;
Status currentStatus
+setter/getter
}
in the form extension, in the createField of the fieldfactory i added the following lines
if ("status".equals(propertyId)) {
// create the combobox
ComboBox status = new ComboBox(
texts.getString("application.label.status"));
status.setItemCaptionMode(AbstractSelect.ITEM_CAPTION_MODE_PROPERTY);
status.setItemCaptionPropertyId("label");
status.setImmediate(true);
status.setNullSelectionAllowed(false);
IndexedContainer container = new IndexedContainer(
(Collection<ApplicationStatus>) item.getItemProperty(
"availableStatus").getValue());
status.setContainerDataSource(container);
status.setPropertyDataSource(item.getItemProperty("currentStatus"));
return status;
} else...
this didn't work, i do get a combobox, with the correct number of lines, but all empties.
i tried to use a beanContainer instead of a IndexedContainer
BeanContainer<String, ApplicationStatus> container =
new BeanContainer<String, ApplicationStatus>(ApplicationStatus.class);
container.addAll((Collection<ApplicationStatus>) item
.getItemProperty("availableStatus").
container.setBeanIdProperty("id");
the result is slightly better, since i do have the available values in the combobox.
only the currentValue is not selected...
I also tried to use a nestedbean property to get the id of the currentstatus, but the result is still not valid... i get a combobox, with the correct value selected, but i can not see others values anymore, since the combobox is readonly ?(even with setReadOnly(false);)
I suggest my way to resolve this. I don't think this is the nicest way, but it's works.
The beanItem class contains all you need.
I did the following in a simple project and it's work verry well :
ComboBox status = new ComboBox("ComboBox");
status.setImmediate(true);
status.setNullSelectionAllowed(false);
for(Status st : (Collection<Status>)item.getItemProperty("availableStatus").getValue()) {
status.addItem(st);
status.setItemCaption(st, st.getLabel());
}
status.setPropertyDataSource(item.getItemProperty("currentStatus"));
Hope it's works.
Regards Éric
From the vaadin demo site you can get this sample that show how to fill a combobox with countries. You could do the same i would guess (not sure I understand your problem 100%):
myForm.setFormFieldFactory(new MyFormFieldFactory ());
private class MyFormFieldFactory extends DefaultFieldFactory {
final ComboBox countries = new ComboBox("Country");
public MyFormFieldFactory () {
countries.setWidth(COMMON_FIELD_WIDTH);
countries.setContainerDataSource(ExampleUtil.getISO3166Container());
countries
.setItemCaptionPropertyId(ExampleUtil.iso3166_PROPERTY_NAME);
countries.setItemIconPropertyId(ExampleUtil.iso3166_PROPERTY_FLAG);
countries.setFilteringMode(ComboBox.FILTERINGMODE_STARTSWITH);
}
#Override
public Field createField(Item item, Object propertyId,
Component uiContext) {
Field f = (Field)item;
if ("countryCode".equals(propertyId)) {
// filtering ComboBox w/ country names
return countries;
}
return f;
}
}
I have build a searchmodel with a searchstring and decorated it with minlength. In my View I would like to display the requierements for the search string but how can I get to the decoration?
Model:
public class SearchModel
{
[StringLength(50,MinimumLength = 4)]
public string Searchname { get; set; }
}
Razor:
#model Project.Models.SearchModel
<p>
The search value has to be a min length of: ...
</p>
You could do this:
#(typeof(SearchModel).GetProperty("Searchname").GetCustomAttributes(true)
.OfType<StringLengthAttribute>().First().MinimumLength)
Though for the sake of MVC purity, you should probably avoid putting this logic into the view code. Either:
Make your Controller get this information and put it onto the Model itself as a separate property, or
Use a custom ModelMetadataProvider to make the information available via the model metadata.
You can get this value from validator attribute in client side.
$('#Searchname').attr('data-val-length-min')
Or you need this in server side in razor?
#{
var attr = typeof(NAMESPACE.SearchModel).GetProperty("Searchname").GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.StringLengthAttribute), true)[0];
var min = attr.GetType().GetProperty("MinimumLength").GetValue(attr, null);
}
.
.
.
<p>The search value has to be a min length of: #min</p>
I am using ASP.NET MVC 3 with razor. I am also using the latest version of Telerik MVC.
I have a grid on my view displaying a list of applications. Each application has a state. I need to write a helper method to display links in each row of the grid depending on each application's current state. If the state is 1 then I need to display an Edit link. The helper that I have looks like this:
public static string ActionLinks(this HtmlHelper helper, string grantApplicationId, string grantApplicationStateId)
{
List<TagBuilder> linkList = new List<TagBuilder>();
string actionLinks = string.Empty;
if (grantApplicationStateId == "1")
{
// Edit link
TagBuilder editLink = new TagBuilder("a");
editLink.MergeAttribute("href", "/GrantApplication/Edit/" + grantApplicationId);
editLink.InnerHtml = "Edit";
linkList.Add(editLink);
}
foreach (TagBuilder link in linkList)
{
actionLinks += link.ToString() + "<br>";
}
return actionLinks;
}
The grid column in my Telerik grid looks like this:
column.Bound(x => x.Id)
.ClientTemplate(#Html.ActionLinks("<#= Id #>", "<#= GrantApplicationStateType.Id #>"))
.Title("Actions");
My view model looks like:
public class GrantApplicationListViewModel
{
// Just partial properties
public GrantApplicationStateType GrantApplicationStateType { get; set; }
}
And GrantApplicationStateType looks like:
public class GrantApplicationStateType : IEntity
{
public int Id { get; set; }
public string Name { get; set; }
}
When the above helper method is called then the value of grantApplicationStateId is "<#= GrantApplicationStateType.Id #>". How would I get the value that was passed through? What I mean is, if the value is 1 that was passed through, how would I get 1 because currently it is "<#= GrantApplicationStateType.Id #>"?
UPDATE 2012-02-06
I tried Darin's link, used the exact same sample in my code, but changed the following:
column.ActionLink("Open", "Edit", "GrantApplication", item => new { id = item.Id, applicationStateId = item.GrantApplicationStateType.Id });
I need to pass through 2 values. I need to do a couple of if statements on the grant application state id, and then return the specific action links to the client. But it fails when looping through the values in:
if (memberExpression.Expression is ParameterExpression)
value = string.Format("<#= {0} #>", memberExpression.Member.Name);
else
value = GetValue(memberExpression);
The first parameter passed in goes through the first/true part of the if statement:
value = string.Format("<#= {0} #>", memberExpression.Member.Name);
..but the second parameter goes through the false part of the if:
value = GetValue(memberExpression);
What's the difference between the 2?
And then it fails at the GetValue method with the following message:
variable 'item' of type MyProject.ViewModels.GrantApplicationListViewModel' referenced from scope '', but it is not defined
I can't get this to work, and I looked for some more samples and couldn't find any.
You can't do this using a helper. In ASP.NET MVC helpers run on the server. Notice the ClientTemplate name in the Telerik grid? That is meant to run on the client.
What it does is that it simply uses <#= Id #> as a placeholder to a server side helper which will generate some HTML and on the client side, the Telerik grid will do a simple string replace in order to put the value which is only known on the client.
At the moment your server side ActionLinks helper is invoked, the Telerik grid cannot pass you the actual value which is known only on the client.
You may take a look at the following blog post for a nice extension.
I would like set a default value for a date picker field in a Document Type in Umbraco.
How can I do this?
This can be easily done using Events, on Document.New
http://our.umbraco.org/wiki/reference/api-cheatsheet/using-applicationbase-to-register-events/overview-of-all-events
Just create a new class (eg. UmbracoEvents.cs)
using System;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;
using Examine;
public class UmbracoEvents: ApplicationBase
{
/// <summary>Constructor</summary>
public UmbracoEvents()
{
Document.New += new Document.NewEventHandler(Document_New);
}
private void Document_New(Document sender, umbraco.cms.businesslogic.NewEventArgs e)
{
if (sender.ContentType.Alias == "News")
{
sender.getProperty("date").Value = DateTime.Today; // Set the date for a new News item to today
}
}
}
You could use the Standard Values or the Default Values for Umbraco package.
That can be achieved with sebastiaans first link. As it says on the page you just put in $date$ as the standard value. Then the package will insert current date when the user creates a document of this type.
I have an enum for one of the properties of my view-model. I want to display a drop-down list that contains all the values of the enum. I can get this to work with the following code.
What I'm wondering is whether there is a simple way to convert from an enum to an IEnumerable? I can do it manually as in the following example, but when I add a new enum value the code breaks. I imagine that I can do it via reflection as per this example, but but are there other ways to do this?
public enum Currencies
{
CAD, USD, EUR
}
public ViewModel
{
[Required]
public Currencies SelectedCurrency {get; set;}
public SelectList Currencies
{
List<Currencies> c = new List<Currencies>();
c.Add(Currencies.CAD);
c.Add(Currencies.USD);
c.Add(Currencies.EUR);
return new SelectList(c);
}
}
I'm using a helper that i found here to populate my SelectLists with a generic enum type, i did a little modification to add the selected value though, here's how it looks like :
public static SelectList ToSelectList<T>(this T enumeration, string selected)
{
var source = Enum.GetValues(typeof(T));
var items = new Dictionary<object, string>();
var displayAttributeType = typeof(DisplayAttribute);
foreach (var value in source)
{
FieldInfo field = value.GetType().GetField(value.ToString());
DisplayAttribute attrs = (DisplayAttribute)field.
GetCustomAttributes(displayAttributeType, false).FirstOrDefault()
items.Add(value, attrs != null ? attrs.GetName() : value.ToString());
}
return new SelectList(items, "Key", "Value", selected);
}
The nice thing about it is that it reads the DisplayAttribute as the title rather than the enum name. (if your enums contain spaces or you need localization then it makes your life much easier)
So you will need to add the Display attirubete to your enums like this :
public enum User_Status
{
[Display(Name = "Waiting Activation")]
Pending, // User Account Is Pending. Can Login / Can't participate
[Display(Name = "Activated" )]
Active, // User Account Is Active. Can Logon
[Display(Name = "Disabled" )]
Disabled, // User Account Is Diabled. Can't Login
}
and this is how you use them in your views.
<%: Html.DropDownList("ChangeStatus" , ListExtensions.ToSelectList(Model.statusType, user.Status))%>
Model.statusType is just an enum object of type User_Status.
That's it , no more SelectLists in your ViewModels. In my example I'm refrencing an enum in my ViewModel but you can Refrence the enum type directly in your view though. I'm just doing it to make everything clean and nice.
Hope that was helpful.
Look at Enum.GetNames(typeof(Currencies))
I am very late on this one but I just found a really cool way to do this with one line of code, if you are happy to add the Unconstrained Melody NuGet package (a nice, small library from Jon Skeet).
This solution is better because:
It ensures (with generic type constraints) that the value really is an enum value (due to Unconstrained Melody)
It avoids unnecessary boxing (due to Unconstrained Melody)
It caches all the descriptions to avoid using reflection on every call (due to Unconstrained Melody)
It is less code than the other solutions!
So, here are the steps to get this working:
In Package Manager Console, "Install-Package UnconstrainedMelody"
Add a property on your model like so:
//Replace "YourEnum" with the type of your enum
public IEnumerable<SelectListItem> AllItems
{
get
{
return Enums.GetValues<YourEnum>().Select(enumValue => new SelectListItem { Value = enumValue.ToString(), Text = enumValue.GetDescription() });
}
}
Now that you have the List of SelectListItem exposed on your model, you can use the #Html.DropDownList or #Html.DropDownListFor using this property as the source.
So many good answers - I thought I'sd add my solution - I am building the SelectList in the view (and not in the Controller):
In my c#:
namespace ControlChart.Models
//My Enum
public enum FilterType {
[Display(Name = "Reportable")]
Reportable = 0,
[Display(Name = "Non-Reportable")]
NonReportable,
[Display(Name = "All")]
All };
//My model:
public class ChartModel {
[DisplayName("Filter")]
public FilterType Filter { get; set; }
}
In my cshtml:
#using System.ComponentModel.DataAnnotations
#using ControlChart.Models
#model ChartMode
#*..........*#
#Html.DropDownListFor(x => x.Filter,
from v in (ControlChart.Models.FilterType[])(Enum.GetValues(typeof(ControlChart.Models.FilterType)))
select new SelectListItem() {
Text = ((DisplayAttribute)(typeof(FilterType).GetField(v.ToString()).GetCustomAttributes(typeof(DisplayAttribute), false).First())).Name,
Value = v.ToString(),
Selected = v == Model.Filter
})
HTH
Maybe is too late, but i think it could be useful for people with the same problem.
I've found here that now with MVC 5 it's included an EnumDropDownListFor html helper that makes for no longer necesary the use of custom helpers or other workarounds.
In this particular case, just add this:
#Html.EnumDropDownListFor(x => x.SelectedCurrency)
and that's all!
You can also translate or change the displayed text via data annotations and resources files:
Add the following data annotations to your enum:
public enum Currencies
{
[Display(Name="Currencies_CAD", ResourceType=typeof(Resources.Enums)]
CAD,
[Display(Name="Currencies_USD", ResourceType=typeof(Resources.Enums)]
USD,
[Display(Name="Currencies_EUR", ResourceType=typeof(Resources.Enums)]
EUR
}
Create the corresponding resources file.