2

I'm looking for an AngularJS-friendly way to show an input box and select the text within the input. I've tried using the controller to add the logic, this is what I have so far:

HTML ComparisonCenterProfiles.html

<div id="saved-profiles" class="select-list" ng-cloak>
    <ul>
        <li ng-repeat="profile in profiles" ng-class="{'ellipsis': true, 'active': isActive(profile.CompSetId)}">
            <span class="save-disk" ng-click="saveActiveProfile()" ng-show="isActive(profile.CompSetId) && profile.IsDirty" style="cursor: pointer;"></span>

            <a href="javascript:;" ng-show="!forceRenameProfile || !isActive(profile.CompSetId)" ng-click="setActiveProfile(profile)">{{profile.CompSetName}}</a>

            <input type="text" ng-model="profile.CompSetName" ng-show="forceRenameProfile && isActive(profile.CompSetId)" ng-blur="saveActiveProfile()" />

        </li>
    </ul>
</div>

Javascript

angular
.module('app')
.directive('compProfiles', ['pageMethod', function (pageMethod) {
    return {
        restrict: 'E',
        require: '^compEditor',
        controller: ['$scope', function ($scope) {
            $scope.saveActiveProfile = function () {
                if ($scope.activeProfile.CompSetName.length < 3) {
                    showAlert('Error',
                                '<strong>' + $scope.activeProfile.CompSetName + '</strong> is not a valid profile name. Your profile name must have at least 3 characters.',
                                [
                                    {
                                        text: 'OK',
                                        click: function () {
                                            $scope.forceRenameProfile = true;
                                            hideAlert($(this));
                                        }
                                    }
                                ]);
                }
                else {
                    continueSavingProfile();
                    $scope.forceRenameProfile = false;
                }
            }
        }],
        templateUrl: 'Templates/ComparisonCenterProfiles.html'
    };
}]);

So at this point, I'm able to show the input box but have been unable to actually select the text within the input box in order to emphasize that the user needs to change the contents within the box.

Sidenote: I'm newer to AngularJS and, coming from a jQuery background, I of course tried using focus() and select() on the element to no avail.

Any ideas would be appreciated!

5
  • When validation fails, I show the textbox so that the user can edit the name of the profile... I need the application to also select the text inside the textbox when it becomes visible. Commented Jun 2, 2016 at 19:26
  • This answer talks about text selection. stackoverflow.com/questions/14995884/select-text-on-input-focus Commented Jun 2, 2016 at 19:58
  • Changed the topic name to add make it a bit more specific... I don't need the text to be selected on a click event; I need the text to be selected from the directive's controller .js file. Right now I can make the element visible but I can't select the text from the controller. Commented Jun 3, 2016 at 5:40
  • To select text, you must have a reference to your element in your directive. To do that you must implement a link function (docs.angularjs.org/guide/directive). This function will provide the html element (in your case the head node of your directive template, but you can find the input inside). After to have save the reference of the element in the directive you can call setSelectionRange on the element Commented Jun 3, 2016 at 6:27
  • Please don't prepend tags in topic titles. That's what tags are for. Lots of discussion in Meta if you're curious. meta.stackoverflow.com/questions/253028/… Commented Jun 3, 2016 at 13:40

2 Answers 2

1

You can get the input element from link directive. Add this function into directive:

link: function(scope, element) {
   var inputElement = element.find('input');
   scope.selectText = function() {
       inputElement.setSelectionRange(0, inputElement.value.length)
   }
}

And in your controller you can call selectText function :

scope.selectText();
Sign up to request clarification or add additional context in comments.

Comments

1

Thanks for your help Silvinus... I used a combination of your answer (using the link instead of the controller and using .setSelectionRange()) along with How to set focus on input field? post to come up with this final solution:

HTML

<input type="text" ng-show="forceRenameProfile && isActive(profile.CompSetId)" focus-me="forceRenameProfile && isActive(profile.CompSetId)" ng-model="profile.CompSetName" ng-blur="saveActiveProfile()" />

Javascript

.directive('focusMe', function ($timeout, $parse) {
        return {
            link: function (scope, element, attrs) {
                var model = $parse(attrs.focusMe);
                scope.$watch(model, function (value) {
                    if (value) {
                        $timeout(function () {
                            element[0].focus();
                            element[0].setSelectionRange(0, element[0].value.length);
                        });
                    }
                });
            }
        };
    });

This solution allowed me to use the same conditional for showing as for focusing and selecting.

Comments

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.