HTML code converted to directive, jQuery cannot find the elements anymore

208 views
Skip to first unread message

Jan Willem Hennink

unread,
Sep 25, 2014, 5:03:26 AM9/25/14
to ang...@googlegroups.com

Hi,

I have a block of code (bootstrap dropdown) which I want to convert into a directive:


<div class="btn-group btn-block">

<button type="button" class="btn btn-default dropdown-toggle btn-block" data-toggle="dropdown">

<span class="selection">Choose Language</span>&nbsp;<span class="caret"></span>

</button>

<ul class="dropdown-menu languagedropdown" role="menu">

<li ng-repeat="language in languages"><a href="#">{{language.LangName}}</a></li>

</ul>

</div>


I want it to be shown like this:

<languageSelect></languageSelect>

 Or maybe even better:

<selectDropdown data=language></selectDropdown>

I have the following challenge though, which I am still unable to solve:

First of all, since the dropdown is not a tipical select / option dropdown, I use the following jQuery to derive the selected value:

 $(".languagedropdown li a").click(function(){
angular
.element($('body')).scope().filterLanguage($(this).text());

angular.element($('body')).scope().$apply();

$('.m-item').removeClass('m-active');

$('.m-scooch').scooch('reset');

var text = $(this).text() == "All" ? "Choose Language" : $(this).text();

$(this).parents(".btn-group").find('.selection').text(text);

});


Second, I call the filterLanguage() function in my directive since I want to change the “all” value to filter = “”.

Code in my Controller:

$scope.filterLanguage = function(filterValue) {

$scope.selectedLanguageFunction = (filterValue == "All") ? "" : filterValue;
}

The issue I am having is as follows:

Once I convert to html codeblock to a controller, my jQuery (second code block) is not working anymore, since the jQuery cannot find the DOM elements anymore.

What I guess is that the jQuery needs to be:

  • Modified, or
  • Added to the directive, or
  • Converted to Angular code

But all my attempt are failing.

Is there anybody who can help me out with a good code example of the directive? (eg. How to fix the jQuery thing?)

Sander Elias

unread,
Sep 25, 2014, 5:12:11 AM9/25/14
to ang...@googlegroups.com
Hi Jan Willem, (Dutch?)

You need to convert to AngularJS all the way, it will make your life much easier.
If you build a plunk/fiddle/jsbin out of your problem, I will take a shot at fixing it.

BTW, do yourself a favor, while learning angular, ditch jQuery. You will get
the hang of AngularJS much quicker that way.

Regards
Sander

Jan Willem Hennink

unread,
Sep 25, 2014, 5:18:16 AM9/25/14
to ang...@googlegroups.com
Hi Sander!

Dutch indeed ;-) But let's stick to English for the sake of Information Sharing ;-)

I will make a fiddle to demonstate my challenge, really appreciate your help!

Jan Willem

Op donderdag 25 september 2014 11:12:11 UTC+2 schreef Sander Elias:

Sander Elias

unread,
Sep 25, 2014, 5:27:19 AM9/25/14
to ang...@googlegroups.com
Totally unrelated!

Dutch indeed ;-) But let's stick to English for the sake of Information Sharing ;-)
Whe should meet at the next DutchAngultJS meeting (1 Okt, next Wednesday)


Jan Willem Hennink

unread,
Sep 25, 2014, 6:04:29 AM9/25/14
to ang...@googlegroups.com
Hi Sander, see my fiddle: http://jsfiddle.net/Ljwchzfu/

Trying to make it as small as possible, but quite challenging ;-)

Op donderdag 25 september 2014 11:27:19 UTC+2 schreef Sander Elias:

Sander Elias

unread,
Sep 25, 2014, 6:25:34 AM9/25/14
to ang...@googlegroups.com
Hi Jan Willem,

I dropped the jQuery and the bootstrap JS from your sample, and added a simple switch.
the page now works, and it's loading a lot less JS!

Regards
Sander

Jan Willem

unread,
Sep 25, 2014, 6:42:34 AM9/25/14
to ang...@googlegroups.com
Hi Sander, thnx alot!

But two things I was aiming at, are not fixed ;-)

I used jQuery to display the chosen value on the button, and I was trying to move the button in the html to a directive.. 

Besides, I do need the boorstrap.js for all the other elements on my side ;-)

Could you help me out with the directive?

I'm trying to see if I can attend on next Wednesday ;-)

Verstuurd vanaf mijn iPhone
--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/uMiDC8FD8rA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Sander Elias

unread,
Sep 25, 2014, 7:07:05 AM9/25/14
to ang...@googlegroups.com
Hi Jan Willem,

updated the fiddle a bit: http://jsfiddle.net/yp0o9qzt/1/

There are already very good bootstrap directives available, or as an alternative
Is there an reason you want to write your own?

Regards
Sander

Jan Willem Hennink

unread,
Sep 25, 2014, 7:27:54 AM9/25/14
to ang...@googlegroups.com
Hi Sander, updated the cation a bit from my part as well :-)


But, how can I run the jQueries:

$('.m-item').removeClass('m-active');\
$('.m-scooch').scooch('reset'); <- this one is not working now, since it uses a local version of scooch.js, which is on my server.. 

Jan Willem

Op donderdag 25 september 2014 13:07:05 UTC+2 schreef Sander Elias:

Jan Willem Hennink

unread,
Sep 25, 2014, 7:33:26 AM9/25/14
to ang...@googlegroups.com
And thnx for the link to the controller! 

I will use them for sure! But I was aiming at making custom directives of the dropdown, so that I could make something like: 
<selectDropdown data=language></selectDropdown>

and 
<selectDropdown data=genre></selectDropdown>


Op donderdag 25 september 2014 13:27:54 UTC+2 schreef Jan Willem Hennink:

Sander Elias

unread,
Sep 25, 2014, 7:44:50 AM9/25/14
to ang...@googlegroups.com

Hi Jan Willem

Well, you first have to loose the jQuery habit before you will be able to make well-function directives ;)
This one is not that hard, and mostly an template directive, so you might give it a go.

You don’t need the $('.m-item').removeClass('m-active'); at all, you have ng-class="{'m-active':$first}" in your template, and that takes care of that.

I have no clue what the $('.m-scooch').scooch('reset') does, so I can’t tell you anything about that. If you want me to help you, you have to educate me a bit
about it.

Regards
Sander

Jan Willem Hennink

unread,
Sep 25, 2014, 10:34:30 AM9/25/14
to ang...@googlegroups.com
Hi Sander!

Okay! so here goes the education ;-))

see the following fiddle: http://jsfiddle.net/yp0o9qzt/4/

first of all, I need to instanciate scooch to get a working (scrollable) carousel. I do this by the following code: $('.m-scooch').scooch() inside the document.ready()
I think the instanciation does not need to be implemented in de directive of the dropdown though.

Secondly, I use $('.m-item').removeClass('m-active') because of the following:
To demonstrate: Please load the fiddle, and go to the third thumbnail (second outlander thumbnail).
Now change the dropdown to "english". You see that the m-active class stays active on the second outlander movie.

Thirdly, I made a jQuery prototype extension in de scooch.js, that will allow the carousel to reset, to if I change the filter, the carousel needs to be reset to its beginning position.

I do this with the following code, inside the scooch.js:
Scooch.prototype.reset = function() { this.initElements(this.element); this.initOffsets(); this.initAnimation(); this.move(1); };

And i run this code by $('.m-scooch').scooch('reset');

Hope this explenation is sufficient ;-)


Op donderdag 25 september 2014 13:44:50 UTC+2 schreef Sander Elias:

Sander Elias

unread,
Sep 25, 2014, 11:23:19 AM9/25/14
to ang...@googlegroups.com
HI Jan Willem,

first of all, I need to instanciate scooch to get a working (scrollable) carousel. I do this by the following code: $('.m-scooch').scooch() inside the document.ready()
I think the instanciation does not need to be implemented in de directive of the dropdown though.
Hmm, I think you need to build an scooch directive first.
 

Secondly, I use $('.m-item').removeClass('m-active') because of the following:
To demonstrate: Please load the fiddle, and go to the third thumbnail (second outlander thumbnail).
Now change the dropdown to "english". You see that the m-active class stays active on the second outlander movie.
That is actually correct, as that is the last selected thumbnail. It looks like your scooch thingie is setting the m-active class by itself. 
so this is a small interference between your plugin, and the way you let angular display it's content! If you do indeed reset the thing
this will brush this issue under the carpet ;)
 

Thirdly, I made a jQuery prototype extension in de scooch.js, that will allow the carousel to reset, to if I change the filter, the carousel needs to be reset to its beginning position.
See my previous point.

As I don't know your experience as an angular (or JS) developer, it's hard to give you advise about this.
Depending on your needs it's a few lines of code, to a few hundred lines of code. I don't have enough spare
time available to build a ready to run solution for you. 

There are a couple of things that need to be done.
 1. wrap your scooch thing into a (couple of) directive(s)
 2. create a drop-down directive.
 3. build the interaction logic for those 2 (which might be yet another directive, or a service/factory)

I hope this clarifies things a bit for you,

With kind regards
Sander

Jan Willem Hennink

unread,
Sep 26, 2014, 9:15:34 AM9/26/14
to ang...@googlegroups.com
Hi Sander,

Many thnx for your extensive feedback!

I just marked myself as attended for the Angular event in Amsterdam.
Hope we can meet!

(by the way, I cannot find a lot of information on the site regarding the event, is it free? It starts at 18.00 right?)

Jan Willem

Op donderdag 25 september 2014 17:23:19 UTC+2 schreef Sander Elias:

Sander Elias

unread,
Sep 26, 2014, 9:48:49 AM9/26/14
to ang...@googlegroups.com
Hi Jan Willem,

Yes, you are right, it will start at 18:00. Food is included. We will have a introduction and a workshop with
angular 2.0. We have talked the stuff trough, and it will be very informative/awesome ;)

Besides the official agenda, there will be room for networking and socializing. 

Regards
Sander

Jan Willem Hennink

unread,
Sep 26, 2014, 9:51:01 AM9/26/14
to ang...@googlegroups.com
Nice!! really looking forward to it!

--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/uMiDC8FD8rA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.



--
JW Hennink
Madurastraat 47-I
1094GE Amsterdam
06 230 66 490

Jan Willem Hennink

unread,
Sep 27, 2014, 4:10:35 AM9/27/14
to ang...@googlegroups.com
Hi Sander, 

I'm working on the directives, which is progressing quite alright I must say, but I'm having difficulty with the following:

I made a directive attribute from my carousel, and use the following code:

IFE.directive('carousel', function() {
   return {
       restrict: 'A',
       link: function(scope, element, attr){
           
           scope.$watch('selectedLanguageFunction', function(){
               //alert('veranderd!');
               element.scooch('reset');
           })
           
       }
   };
});

So what I want to accomplish, is that the carousel re-initializes itself, once the filter value has changed. 
(btw. Using the alert function demonstrated that the function is triggered at the right time).

But I get the following error in my console.log:

TypeError: undefined is not a function

Strange thing is that before I changed to a directive, the jQuery function:

    $(".languagedropdown li a").click(function(){

      //$('.m-scooch').scooch('reset');

    });

did work.

Can you help me out on this one?



Op vrijdag 26 september 2014 15:51:01 UTC+2 schreef Jan Willem Hennink:
Nice!! really looking forward to it!
2014-09-26 15:48 GMT+02:00 Sander Elias <sande...@gmail.com>:
Hi Jan Willem,

Yes, you are right, it will start at 18:00. Food is included. We will have a introduction and a workshop with
angular 2.0. We have talked the stuff trough, and it will be very informative/awesome ;)

Besides the official agenda, there will be room for networking and socializing. 

Regards
Sander

--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/uMiDC8FD8rA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+unsubscribe@googlegroups.com.

To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Jan Willem Hennink

unread,
Sep 27, 2014, 4:17:56 AM9/27/14
to ang...@googlegroups.com
By the way, if I change to order of my scr scripts in the head, I suppress the error, but get the following:

    <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
    <script src="js/scooch.js"></script>


    at Error (native)
    at HTMLDivElement.<anonymous> (http://127.0.0.1/v4/js/customjquery.js:9:44)
    at HTMLDivElement.n.event.dispatch (https://code.jquery.com/jquery-2.1.1.min.js:3:6404)
    at HTMLDivElement.r.handle (https://code.jquery.com/jquery-2.1.1.min.js:3:3179)
    at Object.n.event.trigger (https://code.jquery.com/jquery-2.1.1.min.js:3:5512)
    at HTMLDivElement.<anonymous> (https://code.jquery.com/jquery-2.1.1.min.js:3:11480)
    at Function.n.extend.each (https://code.jquery.com/jquery-2.1.1.min.js:2:2880


Op zaterdag 27 september 2014 10:10:35 UTC+2 schreef Jan Willem Hennink:

Jan Willem Hennink

unread,
Sep 27, 2014, 4:26:16 AM9/27/14
to ang...@googlegroups.com
I fixed it, I called $apply() somewhere where I shouldn't ;-)

Op zaterdag 27 september 2014 10:17:56 UTC+2 schreef Jan Willem Hennink:

Sander Elias

unread,
Sep 27, 2014, 4:55:19 AM9/27/14
to ang...@googlegroups.com

Hi Jan Willem,

I see you are on the right path. You are building directives that are directly solving your current issues. That is great.
But I’ll give you this thought:

scope.$watch('selectedLanguageFunction', function(){
    element.scooch('reset');
})

What will happen if you want to reuse your carousel in a setting where there is a different trigger then selectedLanguageFunction?

Regards
Sander

Reply all
Reply to author
Forward
0 new messages