Loading Owl Carousel 2 with AngularJS dynamic content - javascript

I can't load owl carousel in a angularjs dynamic content.
I use this (edited) html:
<div id="Galeria" owlcarousel class="youplay-carousel gallery-popup">
<a class="angled-img" href="http://www.youtube.com/watch?v={{video}}" ng-repeat="video in juego.Galerias.Videos">
<div class="img">
<img src="http://img.youtube.com/vi/{{video}}/maxresdefault.jpg" alt="">
</div>
<i class="fa fa-play icon"></i>
</a>
<a class="angled-img" href="/img/galerias/{{imagen}}" ng-repeat="imagen in juego.Galerias.Imagenes">
<div class="img">
<img src="/img/galerias/{{imagen}}" alt="">
</div>
<i class="fa fa-search-plus icon"></i>
</a>
</div>
and this (edited) directive to my app:
app.directive('owlcarousel', function() {
var linker = function(scope, element, attr) {
var loadCarousel = function() {
console.log(element);
element.owlCarousel({
loop: !0,
stagePadding: 70,
nav: !0,
autoplay: 0 ? !0 : !1,
autoplayTimeout: 0,
autoplaySpeed: 600,
autoplayHoverPause: !0,
navText: ["", ""],
responsive: {
0: {
items: 1
},
500: {
items: 2
},
992: {
items: 3
},
1200: {
items: 4
}
}
});
}
scope.$watch("juego.Galerias.Videos", function(value) {
loadCarousel(element);
});
scope.$watch("juego.Galerias.Imagenes", function(value) {
loadCarousel(element);
})
}
return {
restrict: "A",
link: linker
}
});
But i can't load the carousel every time i load new content. I try to bind jquery event, call function in controller...etc.
PD: I use ng-routes and load html dinamically.

You can pass models to directive scope, and then do scope.$watch and reinit owlCarousel with reinit method. It is just an idea, if you could specify plunkr or fiddle it would be easier to help.

Related

Angular-intro.js not working

While going from step-to-step i have applied ng-if condition on step... how to continue if any of if condition fails in angular-intro.js??
<a ng-intro-options="IntroOptions" ng-intro-method="CallMe"
ng-intro-oncomplete="CompletedEvent" ng-intro-onexit="ExitEvent"
ng-intro-onchange="ChangeEvent" ng-intro-onbeforechange="BeforeChangeEvent"
ng-intro-autostart="false" ng-click="CallMe();">
<span class="pull-right">
<i class="fa fa-question fa-md" aria-hidden="true" title="Help"></i>
</span>
</a>
<div id="step1">welcome</div>
<div ng-if="admin" id="step2">hello nice to meet you Admin</div>
<div id="step3">list of tasks for the day {{user}}</div>
and in my controller:
$scope.IntroOptions = {
steps:[
{
element: '#step1',
intro: 'Search data from current list. Advanced Search helps you find data with respective columns.',
position: 'bottom'
},
{
element: '#step2',
intro: 'Click on Add icon to add new Channel.',
position: 'left'
},
{
element: '#step3',
intro: 'List of all channels.',
position: 'top'
}
],
showStepNumbers: false,
showBullets: false,
exitOnOverlayClick: true,
exitOnEsc:true,
nextLabel: '<strong>NEXT!</strong>',
prevLabel: '<span style="color:green">Previous</span>',
skipLabel: 'Exit',
doneLabel: 'Thanks'
};
Its working perfectly when ng-if condition is 'admin'.But when if condition fails its ending with step1 how can I continue with step3 directly if ng-if condition fails.

ui-grid is blank when opening a bootstrap accordion a few seconds after the page loads?

So I'm currently attempting to dynamically create accordions which expand to a ui-grid containing some data. The issue is that if I do not expand the accordions within a few seconds of the page loading the ui-grid is blank. The outline of where the table should be exists but there is no data being displayed. I say being displayed because the data itself is in the html. It seems like its hidden by the accordion? When I resize the browser window the data appears though. Sorry if this is not detailed enough or I missed obvious debugging steps, I'm new to js/angular and to html. Below is my HTML code
<div ng-controller="TestController as test">
<script type="text/ng-template" id="group-template.html">
<div class="panel-heading">
<h4 class="panel-title" style="color:#fa39c3">
<a href tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" uib-accordion-transclude="heading">
<span uib-accordion-header ng-class="{'text-muted': isDisabled}">
TEST
</span>
</a>
</h4>
</div>
<div class="panel-collapse collapse" uib-collapse="!isOpen">
<div class="panel-body" style="text-align: right" ng-transclude></div>
</div>
</script>
<uib-accordion close-others="oneAtATime">
<div ng-repeat="model in myData" track by $index>
<div uib-accordion-group class="panel-default" is-open="isOpen">
<uib-accordion-heading>
Test Model {{$index}} <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': isOpen, 'glyphicon-chevron-right': !isOpen}"></i>
</uib-accordion-heading>
<div id="grid[$index]" ui-grid="gridOptions[$index]" ui-grid-edit class="grid" style="clear:both"></div>
<br />
<strong>Last Cell Edited:</strong>{{msg[$index]}}<br />
<button>Commit Changes</button>
</div>
</div>
</uib-accordion>
and my angular
(function () {
var app = angular
.module('testApp', ['ui.grid', 'ui.grid.edit', 'ui.bootstrap', 'ngAnimate'])
.controller('TestController', TestController);
TestController.$inject = ['$scope', 'uiGridConstants'];
function TestController ($scope, uiGridConstants) {
$scope.oneAtATime = false;
$scope.myData = myData;
$scope.msg = [];
$scope.gridOptions = [];
$scope.getGridOptions = function (index) {
$scope.gridOptions[index] ={
showColumnFooter: true,
columnDefs: [
{ field: 'ticker', enableCellEdit: false, width: '33%' },
{ field: 'current_w', aggregationType: uiGridConstants.aggregationTypes.sum, enableCellEdit: false, width: '33%' },
{ field: 'new_w', aggregationType: uiGridConstants.aggregationTypes.sum, width: '33%' }
],
data: myData[index],
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
gridApi.edit.on.afterCellEdit($scope, function (rowEntity, colDef, newValue, oldValue) {
$scope.msg[index] = 'Edited Ticker:' + rowEntity.ticker + ' Column:' + colDef.name + ' newValue:' + newValue + ' oldValue:' + oldValue;
$scope.$apply();
})
}
}
};
for (i = 0; i < Object.keys($scope.myData).length; i++) {
$scope.getGridOptions(i);
console.log($scope.gridOptions[i]);
};
console.log($scope.gridOptions[1]);
};
var myData = [
[{ ticker: 'TICKER', current_w: 5, new_w: 4, },
{ ticker: 'TICKER 2', current_w: 3, new_w: 2, },
{ ticker: 'TICKER 3', current_w: 7, new_w: 0, }],
[{ ticker: 'TICKER', current_w: 5, new_w: 4, },
{ ticker: 'TICKER 2', current_w: 3, new_w: 2, },
{ ticker: 'TICKER 3', current_w: 7, new_w: 5, }]
];
})();
I would take a stab at this and say that you may want to add a ng-if="isOpen" to the ui-grid. So something like below should fix your problem.
<div id="grid[$index]" ui-grid="gridOptions[$index]" ui-grid-edit class="grid" style="clear:both" ng-if="isOpen"></div>
I was having issues with my grid displaying as well, and ensuring that the grid only appears when it is absolutely ready fixed the problem. The ui-grid documentation goes over this concept of a hidden grid at http://ui-grid.info/docs/#/tutorial/108_hidden_grids. They also have a plnkr that you can follow at http://plnkr.co/edit/LtpFnDUTofuxitb4Vh9x?p=preview. I hope this helps!

fire directive after ng-repeat is finished

I am using owl carousel,for which data is coming from a ajax call. after ajax ng-repeat with populated the html content.
So i want to fire the directive which makes the owl carousel, after this all is done. How to do that.
One way i can think of using onFinishedRender directive, but this is not working.
directive :
directives.directive('onFinishRender',['$timeout', '$parse', function ($timeout, $parse) {
return {
restrict: 'A',
link: function (scope, element, attr) {
if (scope.$last === true) {
$timeout(function () {
scope.$emit('ngRepeatFinished');
if(!!attr.onFinishRender){
$parse(attr.onFinishRender);
}
});
}
}
}
}]);
controller:-
pastWorkService.getAllPastWork()
.success(function(data) {
var len = data.length;
$scope.pastWorkData1 = data.slice(0, len/2);
$scope.pastWorkData2 = data.slice(len/2, len - 1);
$scope.owlCarouselPastWork1 = function(){
$('.owl-carousel2').owlCarousel({
items: 4,
loop:true,
slideSpeed : 1000,
autoPlay: 3000,
itemsDesktop: [1199, 4],
itemsDesktopSmall: [980, 3],
itemsTablet: [768, 3],
itemsTabletSmall: false,
itemsMobile: [479, 1],
navigation: false
});
};
$scope.owlCarouselPastWork = function(){
$('.owl-carousel1').owlCarousel({
items: 4,
loop:true,
slideSpeed : 1000,
autoPlay: 3000,
itemsDesktop: [1199, 4],
itemsDesktopSmall: [980, 3],
itemsTablet: [768, 3],
itemsTabletSmall: false,
itemsMobile: [479, 1],
navigation: false
});
};
});
html:-
<div class="owl-carousel1" role="listbox" >
<div class="item" ng-repeat="p in pastWorkData1" on-finish-render="owlCarouselPastWork1()">
<img src="{{p.mainImage}}" alt="completed-projects" />
<div class="panel-footer">{{p.apartmentName}}</div>
</div>
</div>
<!-- second row goes here as owl carousel can contain 1 row -->
<div class="owl-carousel2" role="listbox" >
<div class="item" ng-repeat="p in pastWorkData2" on-finish-render="owlCarouselPastWork1()">
<img src="{{p.mainImage}}" alt="completed-projects" />
<div class="panel-footer">{{p.apartmentName}}</div>
</div>
</div>
Since you simply want to call a function after the last repeated item is rendered, here is one approach you could use:
html
<div class="owl-carousel1" role="listbox" >
<div class="item" ng-repeat="p in pastWorkData1">
<img src="{{p.mainImage}}" alt="completed-projects" />
<div class="panel-footer">{{p.apartmentName}}</div>
<span ng-if="$last" on-finish-render function-to-call="owlCarouselPastWork()"></span>
</div>
</div>
<!-- second row goes here as owl carousel can contain 1 row -->
<div class="owl-carousel2" role="listbox" >
<div class="item" ng-repeat="p in pastWorkData2">
<img src="{{p.mainImage}}" alt="completed-projects" />
<div class="panel-footer">{{p.apartmentName}}</div>
<span ng-if="$last" on-finish-render function-to-call="owlCarouselPastWork1()"></span>
</div>
</div>
directive
.directive('onFinishRender', function($timeout) {
return {
restrict: 'A',
scope: {
functionToCall: '&'
},
link: function(scope, elem, attrs) {
$timeout(function() {
scope.functionToCall();
});
}
}
})
Here is an extremely simple and contrived example to illustrate this idea. You could probably even rework this to have the function in the directive and you would simply pass the class identifier you want to call it on.

Pairing angular js directives with jQuery

What's the best way to manipulate a template of a ng directive with jQuery? When I try to animate or toggle classes that are inside a directive's template, nothing happens. For instance:
HTML:
<div class="projects">
<h2>Projects</h2>
<div class="row">
<div class="col-lg-12">
<div class="row" ng-controller="ProjectsController">
<div class="project-boxes" ng-repeat="project in projects">
<projects-info info="project"></projects-info>
</div>
</div>
</div>
</div>
</div>
Directive's template:
<div class="prjcontainer">
<img class="boximg" ng-src="{{ info.img }}">
<p> {{ info.description }}</p>
</div>
Script
$(document).ready(function(){
$('.boximg').hover(
function() {
$(this).stop().animate({
width: '300px',
height: '300px'}, 500);
},
function() {
$(this).stop().animate({
width: '100px',
height: '100px' }, 500);
});
Directive code:
app.directive('projectsInfo', function() {
return {
restrict: 'E',
scope: {
info: '='
},
templateUrl: 'components/projects/projects-template/projectsInfo.html'
};
});
My main goal is to have a info viewer like how on the Netflix site when you hover over a show, the picture gets bigger and text displays on the inside.
Thanks!

Ion-slide-box using button instead of swiping

I am trying to use a button in order to navigate through the slides however it does not work. I have done this so far:
HTML:
<ion-slide-box>
<ion-slide>
<button ng-click="slide()">Next</button>
</ion-slide>
<ion-slide>
This is the next slide
</ion-slide>
</ion-slide-box>
JS:
function controllerClass($scope, $ionicSlideBoxDelegate) {
$scope.slide = function() {
$ionicSlideBoxDelegate.next();
console.log("Click");
}
}
It shows the log "Click" but I don't know what is wrong with the slider itself.
I could really use help.
I have made a small demo for you
Plunker
HTML
<div class="button-bar">
<a ng-repeat="button in buttons" ng-class="{'active': $index === current}" ng-click="slide($index)" class="button button-stable">{{ button.name }}</a>
</div>
<ion-slide-box on-slide-changed="slideHasChanged($index)" slide-interval="1000" does-continue="true">
<ion-slide>
<div class="box" style="text-align:center;">
First slide
</div>
</ion-slide>
<ion-slide>
<ion-slide>
<div class="box" style="text-align:center;">
Second slide
</div>
</ion-slide>
</ion-slide>
</ion-slide-box>
Contoller
$scope.buttons = [{
name: '1'
}, {
name: '2'
}];
$scope.slide = function($index) {
$scope.current = $index;
$ionicSlideBoxDelegate.slide($index);
}
If you need any additional feature.Please let me know?
import { Component,ViewChild } from '#angular/core';
import { Slides } from 'ionic-angular';
#Component({ selector: 'page-calender', templateUrl: 'calender.html' })
export class CalenderPage {
#ViewChild(Slides) slides: Slides;
constructor() {}
gotoNextSlide() { this.slides.slideNext(); }
gotoPrevSlide() { this.slides.slidePrev(); }
}
Kind of a late answer, but I've been struggling with this component for a while.
You can also call the slider methods directly, when initialized, just store the slider object inside your controller and then use it:
The HTML:
<ion-slides
options="ctrl.slideOptions"
slider="ctrl.slider"
style="margin: -13px 0 0; height: 19.1em;">
<ion-slide-page
ng-repeat="b in ctrl.slideCollection"
ng-click="transCtrl.selectSlide(b)">
<!-- slide content here -->
</ion-slide-page>
<div class="swiper-button-next icon ion-chevron-right" ng-click="ctrl.slideNext($event)"></div>
<div class="swiper-button-prev icon ion-chevron-left" ng-click="ctrl.slidePrev($event)"></div>
</ion-slides>
And the JS:
ctrl.slideOptions = {
loop: true,
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
pagination: false,
effect: 'coverflow',
coverflow: {
rotate: 50,
stretch: 0,
depth: 100,
modifier: 1,
slideShadows : false
}
};
$scope.$on("$ionicSlides.sliderInitialized", function(event, data){
// data.slider is the instance of Swiper
ctrl.slider = data.slider;
ctrl.activeIndex = 0;
});
$scope.$on("$ionicSlides.slideChangeStart", function(event, data){
console.log('Slide change is beginning');
});
$scope.$on("$ionicSlides.slideChangeEnd", function(event, data){
// note: the indexes are 0-based
ctrl.activeIndex = data.slider.activeIndex;
ctrl.previousIndex = data.slider.previousIndex;
});
ctrl.slideNext = function($event) {
ctrl.slider.onClickNext($event);
}
ctrl.slidePrev = function($event) {
ctrl.slider.onClickPrev($event);
}
The ng-click part is not always necessary, but if things do not work as expected it's nice to have a workaround.
I also have a tweak for the CSS buttons:
.swiper-button-next, .swiper-button-prev {
background: none;
}
Use it if you like Ionic icons better than the swiper ones (ugly blue caret...)

Categories