1

I am working to create a directive which will, on focus of an input field, display a set of buttons used to increment or decrement the value in the input. In this case Imperial units (1/8",1/4",1/2").

The first issue I am running into is that when a button is pressed, the focus comes off of the input and so the buttons are hidden via the directive.

The second issue is I am unsure of exactly how to access the ngModel in order to properly add (or remove) the value of the button pressed. The main reason for having the directive around the input instead of directly on the input is for formatting where I want the buttons to be placed but if that can be done when tied to the input that would certainly make this directive significantly less hard to make work correctly.

Here is the code I have setup thus far:

Form input:

 <measurements>
    <label>
      <span>Length</span>
      <i ng-show="form.length.$dirty && form.length.$error.required" class="error-icon"></i>
      <input type="number" name="length" ng-model="form.length" required placeholder="Length">
    </label>
  </measurements>

The directive currently:

angular.module('directive.measurements', [])
    .directive('measurements', [function() {
            return {
                restrict: 'EA',
                transclude: true, 
                templateUrl: 'measurements.html',
                scope: {
                },
                link: function(scope, element, attrs, ctrls) {
                    scope.focused = false;
                    var input = element.find('input');
                    input.on('focus', function(event) {
                        scope.focused = true;
                        scope.$apply();
                    });
                    input.on('blur', function(event) {
                        scope.focused = false;
                        scope.$apply();
                    });
                    scope.add = function(amt){

                    };
                }
            }
        }]);

Finally the template 'measurements.html':

<div>
  <span ng-show="focused">
    <button class="button button-small" ng-click="add(.125)">+1/8</button>
    <button class="button button-small" ng-click="add(.25)">+1/4</button> 
    <button class="button button-small" ng-click="add(.5)">+1/2</button>
  </span>
  <span ng-transclude>
  </span>
</div>

EDIT After playing around a little bit with the focusing issue I came up with changing the 'blur' event to the following, whether this is best or not I am not sure, but it does work:

if (event.relatedTarget === null) {
  input[0].focus();
} else {
  scope.focused = false;
  scope.$apply();
}

Edit 2 Here is the plunker: http://plnkr.co/edit/6eUgRhUSA8yI1s42j9JD?p=preview

3
  • can you create a demo plunker or jsfiddle for us to play with? Commented Apr 11, 2014 at 14:52
  • Added plunker example Commented Apr 11, 2014 at 15:19
  • It looks like your directive depends on the <input> tag inside your <measurement> tags. Why not include the <input> tag directly in the directive's template? Why nest other content within the directive? The directive should be self-reliant. Commented Apr 11, 2014 at 15:44

1 Answer 1

1
+50

HERE is an improvement of your plnkr to make the directive working.

Regarding your issues:

  1. Losing focus is handled by comparing event.targetElement with buttons from your template.
  2. Adding value is achieved with ngModelCtrl.$setViewValue (ngModelCtrl is obtained with require).
small comment

I would not use transclusion at all -- instead would use the directive directly on the input element itself.

Give me a shout if more help needed.

UPDATE

How could this be achieved without transclusion?

In the most straightforward way you can use something like THAT or do it dynamically (look: HERE). Basically you make use of $compile service to manually add the buttons' panel to DOM.

Sign up to request clarification or add additional context in comments.

7 Comments

How could this be achieved without transclusion? I was thinking about avoiding it but couldn't figure out how to add/remove the buttons? This is a more contrived example of my actual code, which is a page full of these with other validation items as well.
Ooohh yea i just figured with so many on the page the compile of all of those would slow the page down quite a bit, but that would certainly encapsulate it quite nicely.
Thought about the performance and therefore proposed the dynamic compilation. For sure, it will be faster than your initial approach with transclusion.
Scratch my last comment didn't know what you meant by dynamically until i read the second plunkr code. Thanks for the help!
Great, glad that could help :-)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.