2014-10-15 07:10:01 +08:00
using System ;
using System.Collections.Generic ;
using System.Globalization ;
using System.Linq ;
using System.Web.Mvc ;
using Orchard.DynamicForms.Elements ;
using Orchard.Environment.Extensions ;
using Orchard.Forms.Services ;
using Orchard.Layouts.Framework.Display ;
using Orchard.Layouts.Framework.Drivers ;
2015-06-29 19:01:58 +08:00
using Orchard.Layouts.Helpers ;
2014-10-15 07:10:01 +08:00
using Orchard.Taxonomies.Services ;
2014-10-17 11:12:49 +08:00
using Orchard.Tokens ;
2014-10-15 07:10:01 +08:00
using DescribeContext = Orchard . Forms . Services . DescribeContext ;
namespace Orchard.DynamicForms.Drivers {
[OrchardFeature("Orchard.DynamicForms.Taxonomies")]
2015-02-20 05:14:55 +08:00
public class TaxonomyElementDriver : FormsElementDriver < Taxonomy > {
2014-10-15 07:10:01 +08:00
private readonly ITaxonomyService _taxonomyService ;
2014-10-17 11:12:49 +08:00
private readonly ITokenizer _tokenizer ;
2014-10-15 07:10:01 +08:00
2015-02-20 05:14:55 +08:00
public TaxonomyElementDriver ( IFormManager formManager , ITaxonomyService taxonomyService , ITokenizer tokenizer )
2014-10-15 07:10:01 +08:00
: base ( formManager ) {
_taxonomyService = taxonomyService ;
2014-10-17 11:12:49 +08:00
_tokenizer = tokenizer ;
2014-10-15 07:10:01 +08:00
}
2015-02-28 06:05:36 +08:00
protected override EditorResult OnBuildEditor ( Taxonomy element , ElementEditorContext context ) {
var autoLabelEditor = BuildForm ( context , "AutoLabel" ) ;
var enumerationEditor = BuildForm ( context , "TaxonomyForm" ) ;
var checkBoxValidation = BuildForm ( context , "TaxonomyValidation" , "Validation:10" ) ;
return Editor ( context , autoLabelEditor , enumerationEditor , checkBoxValidation ) ;
2014-10-15 07:10:01 +08:00
}
protected override void DescribeForm ( DescribeContext context ) {
context . Form ( "TaxonomyForm" , factory = > {
var shape = ( dynamic ) factory ;
var form = shape . Fieldset (
Id : "TaxonomyForm" ,
_OptionLabel : shape . Textbox (
Id : "OptionLabel" ,
Name : "OptionLabel" ,
Title : "Option Label" ,
Description : T ( "Optionally specify a label for the first option. If no label is specified, no empty option will be rendered." ) ) ,
_Taxonomy : shape . SelectList (
Id : "TaxonomyId" ,
Name : "TaxonomyId" ,
Title : "Taxonomy" ,
Description : T ( "Select the taxonomy to use as a source for the list." ) ) ,
_SortOrder : shape . SelectList (
Id : "SortOrder" ,
Name : "SortOrder" ,
Title : "Sort Order" ,
Description : T ( "The sort order to use when presenting the term values." ) ) ,
2014-10-17 11:12:49 +08:00
_TextExpression : shape . Textbox (
Id : "TextExpression" ,
Name : "TextExpression" ,
Title : "Text Expression" ,
Value : "{Content.DisplayText}" ,
Description : T ( "Specify the expression to get the display text of each option." ) ,
Classes : new [ ] { "text" , "large" , "tokenized" } ) ,
_ValueExpression : shape . Textbox (
Id : "ValueExpression" ,
Name : "ValueExpression" ,
Title : "Value Expression" ,
Value : "{Content.Id}" ,
Description : T ( "Specify the expression to get the value of each option." ) ,
Classes : new [ ] { "text" , "large" , "tokenized" } ) ,
2014-10-15 07:10:01 +08:00
_InputType : shape . SelectList (
Id : "InputType" ,
Name : "InputType" ,
Title : "Input Type" ,
Description : T ( "The control to render when presenting the list of options." ) ) ) ;
// Taxonomy
var taxonomies = _taxonomyService . GetTaxonomies ( ) ;
foreach ( var taxonomy in taxonomies ) {
form . _Taxonomy . Items . Add ( new SelectListItem { Text = taxonomy . Name , Value = taxonomy . Id . ToString ( CultureInfo . InvariantCulture ) } ) ;
}
// Sort Order
form . _SortOrder . Items . Add ( new SelectListItem { Text = T ( "None" ) . Text , Value = "" } ) ;
form . _SortOrder . Items . Add ( new SelectListItem { Text = T ( "Ascending" ) . Text , Value = "Asc" } ) ;
form . _SortOrder . Items . Add ( new SelectListItem { Text = T ( "Descending" ) . Text , Value = "Desc" } ) ;
// Input Type
form . _InputType . Items . Add ( new SelectListItem { Text = T ( "Select List" ) . Text , Value = "SelectList" } ) ;
form . _InputType . Items . Add ( new SelectListItem { Text = T ( "Multi Select List" ) . Text , Value = "MultiSelectList" } ) ;
form . _InputType . Items . Add ( new SelectListItem { Text = T ( "Radio List" ) . Text , Value = "RadioList" } ) ;
form . _InputType . Items . Add ( new SelectListItem { Text = T ( "Check List" ) . Text , Value = "CheckList" } ) ;
return form ;
} ) ;
2015-02-28 06:05:36 +08:00
context . Form ( "TaxonomyValidation" , factory = > {
var shape = ( dynamic ) factory ;
var form = shape . Fieldset (
Id : "TaxonomyValidation" ,
_IsRequired : shape . Checkbox (
Id : "Required" ,
Name : "Required" ,
Title : "Required" ,
Value : "true" ,
Description : T ( "Tick this checkbox to make at least one option required." ) ) ,
_CustomValidationMessage : shape . Textbox (
Id : "CustomValidationMessage" ,
Name : "CustomValidationMessage" ,
Title : "Custom Validation Message" ,
Classes : new [ ] { "text" , "large" , "tokenized" } ,
Description : T ( "Optionally provide a custom validation message." ) ) ,
_ShowValidationMessage : shape . Checkbox (
Id : "ShowValidationMessage" ,
Name : "ShowValidationMessage" ,
Title : "Show Validation Message" ,
Value : "true" ,
Description : T ( "Autogenerate a validation message when a validation error occurs for the current field. Alternatively, to control the placement of the validation message you can use the ValidationMessage element instead." ) ) ) ;
return form ;
} ) ;
2014-10-15 07:10:01 +08:00
}
protected override void OnDisplaying ( Taxonomy element , ElementDisplayContext context ) {
var taxonomyId = element . TaxonomyId ;
var typeName = element . GetType ( ) . Name ;
var displayType = context . DisplayType ;
2015-06-29 19:01:58 +08:00
var tokenData = context . GetTokenData ( ) ;
2014-10-15 07:10:01 +08:00
2015-06-29 19:01:58 +08:00
context . ElementShape . ProcessedName = _tokenizer . Replace ( element . Name , tokenData ) ;
2015-12-04 19:14:21 +08:00
context . ElementShape . ProcessedLabel = _tokenizer . Replace ( element . Label , tokenData , new ReplaceOptions { Encoding = ReplaceOptions . NoEncode } ) ;
2015-06-29 19:01:58 +08:00
context . ElementShape . TermOptions = GetTermOptions ( element , context . DisplayType , taxonomyId , tokenData ) . ToArray ( ) ;
2015-02-20 05:14:55 +08:00
context . ElementShape . Metadata . Alternates . Add ( String . Format ( "Elements_{0}__{1}" , typeName , element . InputType ) ) ;
2015-02-28 06:05:36 +08:00
context . ElementShape . Metadata . Alternates . Add ( String . Format ( "Elements_{0}_{1}__{2}" , typeName , displayType , element . InputType ) ) ;
2014-10-15 07:10:01 +08:00
}
2015-06-29 19:01:58 +08:00
private IEnumerable < SelectListItem > GetTermOptions ( Taxonomy element , string displayType , int? taxonomyId , IDictionary < string , object > tokenData ) {
2014-10-15 07:10:01 +08:00
var optionLabel = element . OptionLabel ;
2015-06-27 23:31:08 +08:00
var runtimeValues = GetRuntimeValues ( element ) ;
2014-10-15 07:10:01 +08:00
if ( ! String . IsNullOrWhiteSpace ( optionLabel ) ) {
2015-09-11 12:19:52 +08:00
yield return new SelectListItem { Text = displayType ! = "Design" ? _tokenizer . Replace ( optionLabel , tokenData ) : optionLabel , Value = string . Empty } ;
2014-10-15 07:10:01 +08:00
}
if ( taxonomyId = = null )
yield break ;
var terms = _taxonomyService . GetTerms ( taxonomyId . Value ) ;
2014-10-17 11:12:49 +08:00
var valueExpression = ! String . IsNullOrWhiteSpace ( element . ValueExpression ) ? element . ValueExpression : "{Content.Id}" ;
var textExpression = ! String . IsNullOrWhiteSpace ( element . TextExpression ) ? element . TextExpression : "{Content.DisplayText}" ;
var projection = terms . Select ( x = > {
var data = new { Content = x } ;
var value = _tokenizer . Replace ( valueExpression , data ) ;
var text = _tokenizer . Replace ( textExpression , data ) ;
return new SelectListItem {
Text = text ,
2015-06-27 23:31:08 +08:00
Value = value ,
Selected = runtimeValues . Contains ( value , StringComparer . OrdinalIgnoreCase )
2014-10-17 11:12:49 +08:00
} ;
} ) ;
2014-10-15 07:10:01 +08:00
switch ( element . SortOrder ) {
case "Asc" :
projection = projection . OrderBy ( x = > x . Text ) ;
break ;
case "Desc" :
projection = projection . OrderByDescending ( x = > x . Text ) ;
break ;
}
foreach ( var item in projection ) {
yield return item ;
}
}
2015-06-27 23:31:08 +08:00
private IEnumerable < string > GetRuntimeValues ( Taxonomy element ) {
var runtimeValue = element . RuntimeValue ;
return runtimeValue ! = null ? runtimeValue . Split ( new [ ] { ',' , ';' } , StringSplitOptions . RemoveEmptyEntries ) : Enumerable . Empty < string > ( ) ;
}
2014-10-15 07:10:01 +08:00
}
}