A couple of days ago I read a blog post about a Font Awesome selection editor for EPiServer. It inspired me because I'm currently in a project where we need basically the same thing with two exceptions: 1. I want the editors to be able to search for icons since the list is quite heavy with more than 500 icons to browse through. 2. I don't want to have a XML file with all the icons, I just want to get them from the stylesheet by parsing it with javascript.
http://www.mogul.com/en/about-mogul/blog/font-awesome-dropdown-for-episerver-edit-mode
I created this as a protected module that contains the following components:
This is what it looks like if you search for an icon. If you leave the field empty and just click the arrow it will give you all icons in a scrollable list.
_FontAwesomeMixin.js
First of all I created a mixin to use in my editor. I call it _FontAwesomeMixin and it contains a method to create a memory store from the included Font Awesome stylesheet. Note that the stylesheet needs to be local to be able to access the property cssRules, we cannot use a cdn hosted version:
define([ "dojo/_base/declare", "dojo/store/Memory", 'xstyle/css!../styles/font-awesome.min.css' ], function ( declare, memorystore ) { return declare("geta-epi-cms.editors._FontAwesomeMixin", null, { _createMemoryStore: function () { var fontAwesomeStylesheet = this._getFontAwesomeStylesheet(); var memoryStoreData = []; if (fontAwesomeStylesheet != null) { for (var i = 0; i < fontAwesomeStylesheet.cssRules.length; i++) { var rule = fontAwesomeStylesheet.cssRules[i]; if (!rule.selectorText || rule.selectorText.indexOf("::before") == -1) { continue; } var selectorTexts = rule.selectorText.split(","); for (var j = 0; j < selectorTexts.length; j++) { var selectorText = this._trimString(selectorTexts[j]).substring(1).replace("::before", ""); var iconName = selectorText.substring(3); var label = '<i class="fa fa-lg fa-fw ' + selectorText + '"></i> ' + iconName; memoryStoreData.push({ id: selectorText, name: iconName, label: label }); } } memoryStoreData.sort(this._sortFunc); } return new memorystore({ data: memoryStoreData }); }, _getFontAwesomeStylesheet: function () { for (var i = 0; i < document.styleSheets.length; i++) { try { var sheetInfo = document.styleSheets[i]; if (sheetInfo.href.indexOf('font-awesome') > -1) { return sheetInfo; } } catch (e) { } } return null; }, _sortFunc: function(a, b) { if (a.id < b.id) { return -1; } if (a.id > b.id) { return 1; } return 0; }, _trimString: function (str) { return str.replace(/^\s+|\s+$/g, ''); } }); });
FontAwesomeAutoSuggestEditor.js
This is the actual editor that inherits from the mixin above and from EPiServer's AutoCompleteSelectionEditor. It's quite simple. The only thing it does is to call the _createMemoryStore and set two configuration variables defined in dijits _AutoCompleterMixin.
define([ "dojo/_base/declare", "geta-epi-cms/editors/_FontAwesomeMixin", "epi/shell/form/AutoCompleteSelectionEditor" ], function ( declare, _FontAwesomeMixin, AutoCompleteSelectionEditor ) { return declare("geta-epi-cms.editors.FontAwesomeAutoSuggestEditor", [_FontAwesomeMixin, AutoCompleteSelectionEditor], { labelAttr: "label", labelType: "html", postMixInProperties: function() { this.inherited(arguments); this.store = this._createMemoryStore(); } }); });
Property attribute
This is the code for the property attribute to use on content type properties:
[AttributeUsage(AttributeTargets.Property, AllowMultiple=false)] public class FontAwesomeSelectionAttribute : Attribute, IMetadataAware { public void OnMetadataCreated(ModelMetadata metadata) { var extendedMetaData = metadata as ExtendedMetadata; if (extendedMetaData == null) { return; } extendedMetaData.ClientEditingClass = "geta-epi-cms.editors.FontAwesomeAutoSuggestEditor"; extendedMetaData.CustomEditorSettings["uiWrapperType"] = UiWrapperType.Floating; } }
module.config
The configuration for my module looks like this:
<module productName="Geta EPi Cms UI" clientResourceRelativePath="" loadFromBin="false"> <dojo> <paths> <add name="geta-epi-cms" path="ClientResources/Scripts" /> </paths> </dojo> </module>
Example
To use this on a content type property, all that's needed is to decorate a string property with the FontAwesomeSelectionAttribute:
[FontAwesomeSelection] [Display(Name = "Icon", Order = 100)] public virtual string IconCssClass { get; set; }