0

I have the JQuery following code in my client app design which I am trying to convert to AngularJS directive as shown below, but for some reason the on click event is not responding (nothing happens when I click on boxes) so can someone help me please by telling me what exactly I am doing wrong and how to fix it? Thanks

Original JQuery code:

$("html").on("click", '.boxes .col .ten', function(e){
e.stopPropagation();
var numBoxes = $('.boxes .col .ten.active').length;

if($(this).hasClass('active'))
{
    $(this).removeClass('active');
    $(this).find('input[type="checkbox"]').val('0');
    return false;
}   
else 
{
    if(numBoxes <10)
    {
        $(this).addClass('active');
        $(this).find('input[type="checkbox"]').val('1');
        return false;
    }   
}
});

Directive:

 .directive('BoxesDirective', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {

    element.bind("click", '.boxes .col .ten', function(e){
    e.stopPropagation();
    var numBoxes = $('.boxes .col .ten.active').length;

    if($(this).hasClass('active'))
    {
        $(this).removeClass('active');
        $(this).find('input[type="checkbox"]').val('0');
        return false;
    }   
    else 
    {
        if(numBoxes <10)
        {
            $(this).addClass('active');
            $(this).find('input[type="checkbox"]').val('1');
            return false;
        }   
    }
});



    }
};
});

HTML:

    <div class="labelTarget" boxes-directive>
      <div class="boxes">
        <div class="col">
          <div class="col ten active">
            $5
            <input id="5" name="5" type="checkbox" value="5">
          </div>
          <div class="col ten">
            $10
            <input id="10" name="10" type="checkbox" value="10">
          </div>
          <div class="col ten">
            $20
            <input id="20" name="20" type="checkbox" value="20">
          </div>
          <div class="col ten">
            $50
            <input id="50" name="50" type="checkbox" value="50">
          </div>
          <div class="col ten">
            $75
            <input id="75" name="75" type="checkbox" value="75">
          </div>
        </div>
        <div class="col">
          <div class="col ten active">
            $100
            <input id="100" name="100" type="checkbox" value="100">
          </div>
          <div class="col ten">
            $200
            <input id="200" name="200" type="checkbox" value="200">
          </div>
          <div class="col ten">
            $500
            <input id="500" name="500" type="checkbox" value="500">
          </div>
          <div class="col ten">
            $750
            <input id="750" name="750" type="checkbox" value="750">
          </div>
          <div class="col ten">
            $1000
            <input id="1000" name="1000" type="checkbox" value="1000">
          </div>
        </div>
      </div>
    </div>
  </div>
3
  • Maybe a silly question since I didn't try if it works anyway, but shouldn't the casing of the directive be .directive('boxesDirective', function() { Commented Apr 20, 2014 at 17:26
  • @JoachimIsaksson Please ignore my previous comment, yet it makes a difference having it as boxesDirective instead of BoxesDirective, but what if the directive name consist of w words, example SolidBoxesDirective shall the first word only be in small then each additional word have first character in caps? Commented Apr 20, 2014 at 18:16
  • 1
    An uppercase letter indicates where a dash goes in the attribute name (if an attribute directive), so solidBoxesDirective should give the attribute name solid-boxes-directive. I honestly don't know what attribute name it expects if the first letter is uppercase :) Commented Apr 20, 2014 at 18:28

3 Answers 3

1

First of all, I'd recommend not using JQuery to do all of the class manipulation. Look at ng-class instead.

However, to answer the question. You are binding to the click event of the element, and Angular needs to know about a state change on the scope. To let Angular know, use a $scope.$apply() at the end of the event.

If you switch to ng-click and ng-class your code will look a lot cleaner though. :)

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

1 Comment

Thanks for your help, I've tried adding $scope.$apply(); to the end of the event but it is still not working :( If there is a chance you can please show me an example on applying the JQuery code in my question using ng-click ng-class that will be really great? Thanks
1

After examining your code, you had 2 errors:

  1. as Joachim Isaksson said, you need to lower-case you directive, for example: boxesDirective
  2. since you are using JQuery in your directive, you need to wrap your element with $ sign.

Example:

var app=angular.module('App', []);
 app.directive('boxesDirective', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            console.log("s");
    $(element).bind("click", '.boxes .col .ten', function(e){
    e.stopPropagation();
    var numBoxes = $('.boxes .col .ten.active').length;

    if($(this).hasClass('active'))
    {
        $(this).removeClass('active');
        $(this).find('input[type="checkbox"]').val('0');
        return false;
    }   
    else 
    {
        if(numBoxes <10)
        {
            $(this).addClass('active');
            $(this).find('input[type="checkbox"]').val('1');
            return false;
        }   
    }
});



    }
};
});

Live example: http://jsfiddle.net/choroshin/dxwbb/1/

6 Comments

not exactly, it's jqlite, you an call it a mini version on jquery : docs.angularjs.org/api/ng/function/angular.element
The OP uses jQuery. If angular detects jQuery then that is used instead of jqLite.
you can try it yourself, remove the $ sign and you can see that your code will get an error, just open your console window.
Because in your fiddle jQuery is included after angular. The first sentence of the link you posted: If jQuery is available, angular.element is an alias for the jQuery function
in any case, in fiddle you can see that after I lower-case the directive name, the directive is initialized
|
0

In your jQuery code you use $("html").on("click", but in the directive you suddenly switched to element.bind("click".

.on() and .bind() are not the same. You need to use element.on() in the directive.

And as @Joachim Isaksson pointed out it should be .directive('boxesDirective'.

3 Comments

Changing to boxesDirective didn't make any change. I see no harm in switching from $("html") to a sub element? Please correct me if I am wrong. Tried using .on same thing didn't work
@MChan If you use .bind then $(this)would be the labelTarget div.
Just tried moving the attribute to a parent div and it works now. Thanks

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.