1

I've been searching around for a solution on this one and have been stumped. I'm kind of new to AngularJS so I don't know all of the good tricks it's got yet. I have a multi-part form that is HTTP GETed at the end using ng-href. Here's the code snippet that submits everything.

<a ng-href="#/report/{{ctrl.model}}" ng-click="ctrl.createReport()">Finish</a>

now I'm faced with adding validations to this form, and I want to prevent the link from being followed if the validation fails. Validation logic is contained in a controller function, the function will return true or false base on the result of the validation.

Unfortunately, this piece of code is a part of a large implementation developed by someone else. I just want to add the validation part without having to modify too much logic within the code.

Is there any way to put a condition on ng-href? So that when Finish is clicked, the browser will only follow the URL if validation passes. Otherwise, is there anyway to perform the same GET programmatically within the controller? I've looked at using $http.get() and $window.location.href. The former seem to be AJAX which does not redirect the browser to the name URL. The latter, I don't know how to expand the ctrl.model into a proper GET string.

Any thoughts, ideas, suggestion would be greatly appreciated. Thanks!!!

Solution Used

HTML:

<a data-ng-click="ctrl.createReport()">Finish</a>

JS:

if (validate()) {
    $location.path('/report/' + angular.toJson(self.model, false));
}

3 Answers 3

2

remove the ng-href all together. and use the $location service.

function createReport(){
    if(myForm.$valid){
        $location.path('/report'+model);
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Hi Kent, thanks for the response. I had tried that originally, I thought that would be the most straight forward and simple code. However, $location service will not convert the "model" into a JSON string properly in the URL. Here's what I get when I use your approach: http://localhost/TestApp/#/report/%5Bobject%20Object%5D
Ok, I was able to get the proper json string by using the angular.toJson() function. Works now, thanks!
Sorry I didn't realize that model was an object.
1

Unfortunately, this piece of code is a part of a large implementation developed by someone else. I just want to add the validation part without having to modify too much logic within the code.

I have a hack for you. This directive eats the click if the expression returns false. So, the href is never followed by the browser. Also prevents the execution of ng-click.

javascript

module.directive('eatClickIf', ['$parse', '$rootScope',
  function($parse, $rootScope) {
    return {
      // this ensure eatClickIf be compiled before ngClick and ngHref
      priority: 100,
      restrict: 'A',
      compile: function($element, attr) {
        var fn = $parse(attr.eatClickIf);
        return {
          pre: function link(scope, element) {
            var eventName = 'click';
            element.on(eventName, function(event) {
              var callback = function() {
                if (fn(scope, {$event: event})) {
                  // prevents ng-click to be executed
                  event.stopImmediatePropagation();
                  // prevents href 
                  event.preventDefault();
                  return false;
                }
              };
              if ($rootScope.$$phase) {
                scope.$evalAsync(callback);
              } else {
                scope.$apply(callback);
              }
            });
          },
          post: function() {}
        }
      }
    }
  }
]);

html

<a ng-href="#/report/{{ctrl.model}}" 
   ng-click="ctrl.createReport()" 
   eat-click-if="!ctrl.modelIsValid()">Finish</a>

1 Comment

oneway, I found a more simple way for achieving what I needed. But it's good to know that there is a way to intercept and prevent a click. May come handy in another case. Thanks!
0

I will suggest you to remove the ng-href value and change path from js condition using $location

<a ng-href="" ng-click="ctrl.createReport()">Finish</a>

Inject $location sservice and do:

$location.path('/newValue')

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.