uCssClassNamePicker Property Editor for Umbraco 7

Written by @marcemarc on Sunday, 12 January 2014
CropperCapture[326].jpg

Well if you've used the old uCssClassNameDropdown package in Umbraco 4/6 you'll be aware that bundled with the basic ability to create a dropdown data type from the values scrounged from the css stylesheet classnames that I also included a few usercontrols hard wired to work with font-awesome and bootstrap icons, and instead of the dropdown with lots of meaningless icon names the editor could actually see which icon to pick, and if we're honest it's probably this functionality that makes the whole thing a worthwhile endeavour rather than the basic dropdown thing, and I'm painfully aware of the dissappointed people have felt installing uCssClassNameDropdown for Umbraco 7 and the general constructive feedback has been "where are the *#?&!*+ icons ?"

So I could probably have rushed together a hardcoded font-awesome one relatively quickly, but times they-are-a-changin and there are lots of icons-as-a-font libraries out there, and I didn't really want to give the impression that uCssClassNameDropdown is just a font-awesome thing,  (even if in that is all people use it with) and I didn't want to keep updating a hardcoded thing everytime a new font-icon thing was invented The only thing that seems to differ in these libraries is the pattern of the <i class="icon icon-classname ... 

...So uCssClassNameIconPicker, is kind of the same as uCssClassNameDropdown except you can now set the 'Icon Pattern html' in the property editors configuration, that will render the necessary markup to display a version of the picked item

Some description

(where {0} represents the matched classname) eg:

{
 label: "Icon Pattern",
 description: "Html pattern to display icon, eg <i class='icon icon-{0}'></i>",
key: "iconPattern",
 view: "TextString"
}

Loading the stylesheet

For the Controller I needed to make sure that in order to render the icons from the stylesheet that the stylesheet was available inside the umbraco backend. to do this with Umbraco 7 I added the 'assetsService' to the controller function:

function ($scope, $http, assetsService) {

and then in the function which retrieves the classnames from the stylesheet added:

// load the supplied css stylesheet using the umbraco assetsService
assetsService.loadCss(cssPath);

Rendering the Icon

I created a helper method called 'renderIconPattern' to slot the matched classname into the specified iconpattern:

$scope.renderIconPattern = function (currentClassName) {
 return $scope.iconpattern.replace("{0}", currentClassName)
}

In the view (as per the old usercontrols) The basic dropdown is there as a fallback, but above this the icons are rendered in a list:

<li ng-repeat="ccn in classnames">repeating stuff here</li>

to render the icon, I made a call to my helper method using ng-bind-html (because the pattern contains raw html and I didnt't want it encoded) eg.

<li ng-repeat="ccn in classnames"><span ng-bind-html="renderIconPattern(ccn)"></span><span>{{ccn}}</span></li>

Setting the value

This got me a list of lovely icons, but the editor needs to be able to select them, with the old control I'd used jquery to bind to the click event, to set the dropdown value, which was then used as the saved value; but here all we need to do is set model.value, and magically the dropdown will change and the correct selectedvalue will be saved.

$scope.setSelectedClass = function (selectedClassName) {
$scope.model.value = selectedClassName;
}

and in my view added a link with an ng-click attribute set to the new method:

<li ng-repeat="ccn in classnames">
<a ng-click="setSelectedClass(ccn)"><span ng-bind-html="renderIconPattern(ccn)"></span><span>{{ccn}}</span></a>
</li>

Highlighting the selected icon

Determing if an icon is the selected one, again achieved by a helper method in the controller:

$scope.getSelectedClass = function (currentClassName, selectedClassName) {
 if (currentClassName == selectedClassName) {
 return "selected";
 }
 else {
return "";
 }
 }

and in the view, we use ng-class

<li ng-repeat="ccn in classnames" ng-class="getSelectedClass(ccn,model.value)" id="iconHolder-{{ccn}}">
<a ng-click="setSelectedClass(ccn)"><span ng-bind-html="renderIconPattern(ccn)"></span><span>{{ccn}}</span></a> </li>

Some description

it's starting to make a bit of sense to me but...

.. the thing that is not quite right which has bugged me and prevented me uploading this to Our, or blogging about anything and taken more time the rest of the control is the scrolling. It's fine if a user scrolls and selects an icon; but if they use the dropdown the icon doesn't scroll and they can't see which icon is selected.

Angular has an $anchorScroll service which looks neat, but requires you to set the $location in order to scroll to a position, and that was mucking up Umbraco 7's routes, it may be the way to resolve it but in the end I just used animate, to sort of fake a scroll, and this sort of makes it usable, but it isn't perfect, and I've noticed that if the control is on another tab, and the edtior switches to that tab, they won't see the selected icon; so as a temporary workaround, the selected icon will appear next to the dropdown; and I'll think about it a bit more.

The interesting angular part of this, is I set up a 'watch' on the model.value so whenever it changes I can run code, and I have a function called 'goToIcon' which animates to the selected icon.

$scope.$watch('model.value', function (newValue, oldValue) {
$scope.goToIcon(newValue);
});

 This version can be download as version 7.0 from our.umbraco.org