Saturday, March 5, 2016

Legends of Angular

I have a knack for having to do things at work that are not as easy as they seem.  It's truly unbelievable how often I say "That should be very straightforward" and it turns into some sort of nightmare coding scenario.  Lucky for you (and me, since this is my repository for such information) I'm really good at what I do so I'm able to figure these things out.  Hence the title of the blog.  But I digress.  Well, not really because in order to digress I'd have to be on topic first and since I haven't gotten that far yet, I haven't digressed.  But now I have.

To the point!  We use a lot of <fieldset>s at work, which means we have a lot of <legend>s, too.  We had a (seemingly simple) task to change the text of a <legend> based on some other value.  No prob, Bob!  We'll just do this:
<fieldset>
    <legend>{{LegendText}}</legend>
</fieldset>
So that's what I did.  The end.  No, not really.

It turns out my {{LegendText}} wasn't updating like I thought it would.  Long story short, I had to write a directive to allow me to bind my value to my <legend>.  Yup, seriously.  It gets better, though.  In our specific instance we already had some code that overwrote the <legend> to make it the toggle control for the <fieldset> so I had to duplicate that inside my directive.  It ended up being pretty simple, so here it is:
angularApp.directive('legend', [
    function() {
        return {
            restrict: 'E', // only activate on element attribute
            require: '?ngModel', // get a hold of NgModelController
            link: function(scope, element, attrs, ngModel) {
                if (!ngModel) return; // do nothing if no ng-model

                // Specify how UI should be updated
                ngModel.$render = function() {
                    $(element).html("<span class='icon icon-select-arrow-dn'></span> " + ngModel.$viewValue).css("cursor", "pointer");
                    $(element).off("click");
                    $(element).on("click", function () {
                        toggleFieldsetContent($(element));
                    });
                };
            }
        };
    }
]);
You'll just have to accept that toggleFieldsetContent is defined somewhere else and I'm not going to show it to you.

Also, you should note that this isn't necessarily the best way to do this.  It's a way to do it and it worked for me in a pinch.  I may come back to it and clean it up one day and I may not remember to update this blog post when I do.  So there.

No comments:

Post a Comment