For one of our mobile application projects being built using Ionic we needed to implement two types of show / hide toggle features.
1. In the hide state, a couple of lines of product description would be displayed along with ellipsis. In the show state, the full description would need to be displayed.
2. In the hide state, a div and it’s contents needed to be hidden. In the show state, the div and it’s contents should be made visible
For #1 we found this Angular Read More Directive that seemed to do the job.
For #2 we thought a simple JQuery show / hide toggling CSS
display would work. While the concept of using the .show() / .hide() methods of Jquery are completely fine, there were a couple of obstacles we faced with it’s implementation.
JQuery and JQuery Lite
Ionic comes bundled with AngularJS which in turn comes bundled with Jquery Lite.
If jQuery is available, angular.element is an alias for the jQuery function. If jQuery is not available, angular.element delegates to Angular’s built-in subset of jQuery, called “jQuery lite” or “jqLite.”
If you want full JQuery capabilities, you need to include it separately. While according to mhartington from the Ionic Team, using JQuery with Ionic is complete fine, he has mentioned somewhere else that there can be issues loading JQuery after Angular. In the same Github issue it was conceded that there was a problem and certain versions of JQuery have caused issues with certain versions of Ionic.
Even after including JQuery, the show / hide feature within the JQuery.ready() method will not work if the DOM elements that need to be bound on the click events are not available on load of the application. An example of this would be implementing the show / hide feature via the JQuery click() event handler within each
JQuery event handlers are bound at runtime. What is needed is event delegation that can be achieved via directives. A Stackoverflow post “jQuery not working with ng-repeat results” had an accepted response that worked for us as well.
The last issue we faced was with implementing the Angular Read More directive within a dynamic list. The reason for this is that the directive needs to be bound without a user input like a click. Since the data is dynamically bound using ng-bind or ng-bind-html, and we need the directive to do it’s job afterwards, we need to employ scope.$watch on $attr.ngBind. We found this solution via this Stackoverflow post “AngularJS – Run custom directive after ng-bind-html“. It is also important to play with the “priority” attribute of the directive to ensure correct sequencing of events.
- ng-bind has a priority of 0
- ng-repeat has a priority of 1000