AngularJS and getting ng-click to work on dynamically loaded html - javascript

I wonder if i could get a little help here. I am trying to build a small image gallery using AngularJS and Laravel. So far everything is working out great. The problem I am having however is when I dynamically load one of my HTML files, the ng-click directive does not seem to work on the dynamic content. I have looked into this and came across the $compile option, but I cannot for the life of me see how I can implement it.
Any one have any idea of what I need to do? I have attached the code I am working with below:
Controller Code
App.controller('MyPhotos', function ($scope, $timeout, $http, $document, $modal, $log, $sce, $compile) {
$scope.loadAlbums = function () {
$scope.loading = "<div class='text-center'><strong>...Loading...</strong></div>";
$scope.isLoading = true;
$http({
method: 'GET',
url: '/my/photos/fetch/albums'
}).success(function (data) {
var htmlContent = $compile(data.albums)($scope);
$scope.galleryContent = $sce.trustAsHtml(data.albums);
$log.log(data.albums);
$scope.isLoading = false;
}).error(function (data, status, headers, config) {
//$scope.progress = data;
$scope.messages = 'There was a network error. Try again later.';
//$log.error(data);
$scope.isLoading = false;
});
};
Base Html Page
<div class="row">
<div class="col-md-12">
<ul class="list-inline">
<li>Your Photos</li>
<li>Your Albums</li>
</ul>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div ng-show="isLoading" class="text-center">
<img src="{{ Theme::asset()->url('img/loading_balls.gif') }}" />
</div>
<div class="photoContainer" data-ng-bind-html="galleryContent">
[[ galleryContent ]]
</div>
</div>
</div>
Dynamically loaded HTML
<div class="row">
<div class="col-md-3">
<img src="http://placehold.it/700x400" alt="" class="img-responsive" />
<span class="fa fa-plus"></span> Create album
</div>
#foreach($albums as $album)
<div class="col-md-3">
<img src="http://placehold.it/700x400" alt="" class="img-responsive" />
<a href="#" data-ng-click="loadAlbum({{ $album->id }})" title="{!! $album->title !!}"
data-album-id="{{ $album->id }}">{!! $album->title !!}
</a>
<p> </p>
</div>
#endforeach
The data-ng-click directive is not working when the content is loaded dynamically.
Thanks

You can do this similarly in a much simpler way, using ngInclude:
<div class="photoContainer" ng-include="'/my/photos/fetch/albums'">
<img src="{{ Theme::asset()->url('img/loading_balls.gif') }}" />
</div>
See https://docs.angularjs.org/api/ng/directive/ngInclude

Related

nested ng-repeat with json and rest api call back

I am trying to make a UI using list of product in a json(products.json) file on local and their availability in number from wp rest api call back in html(ionic) I have this:
Controller:
.controller('ShopCtrl', function($scope, $ionicActionSheet, BackendService, CartService, $http, $sce ) {
$scope.siteCategories = [];
$scope.cart = CartService.loadCart();
$scope.doRefresh = function(){
BackendService.getProducts()
.success(function(newItems) {
$scope.products = newItems;
console.log($scope.products);
})
.finally(function() {
// Stop the ion-refresher from spinning (not needed in this view)
$scope.$broadcast('scroll.refreshComplete');
});
};
$http.get("http://example.com/wp-json/wp/v2/categories/").then(
function(returnedData){
$scope.siteCategories = returnedData.data;
console.log($scope.siteCategories);
}, function(err){
console.log(err);
});
Template view:
<div ng-repeat = "product in products">
<div class="item item-image" style="position:relative;">
<img ng-src="{{product.image}}">
<div ng-repeat = "siteCategory in siteCategories">-->
<button class="button button-positive product-price" ng-click="addProduct(product)">
<p class="white-color product-price-price">post <b>{{siteCategory[$index].count}}</b></p>
</button>
</div>
</div>
<div class="item ui-gradient-deepblue">
<h2 class="title white-color sans-pro-light">{{product.title}} </h2>
</div>
<div class="item item-body">
{{product.description}}
</div>
</div>
so how can I achieve that? I tried to use nested ng-repeat but it didn't work out.

My ion-slide-box take a little to open from json

I have the ion-slide-box in the first view of my app, and it just open when i enter in other view and return to the first view, after that it work because i think the ion slide is in the cache. The images is loaded from JSON, someone knows what is wrong or what I need to do?
.controller('PlaylistsCtrl', function($scope, $http) {
$http.get("http://scabandblastofwheat2016.org/mobile/ImageSlide.json")
.success(function (response)
{
$scope.names = response;
});
})
<div id="slide">
<ion-slide-box style="width:80%; height:30%;" auto-play="true" show-pager="true">
<ion-slide ng-repeat="x in names|orderBy:'Name'">
<img style="width:100%;" ng-src="{{x.Name}}" alt="" />
</ion-slide>
</ion-slide-box>
</div>

Ionic: Why are my images not loading from my json file?

I'm trying to load images from my json file into my application but i cannot get it to work:
Here's my code:
js:
.controller('photoCtrl', function($scope, $ionicModal, $ionicBackdrop, $ionicScrollDelegate, $ionicSlideBoxDelegate, $http) {
$scope.images = [];
$scope.getImages = function() {
$http.get('https://api.myjson.com/bins/37ia6')
.success(function(data) {
$scope.images = data.images;
})
}
html:
<ion-view view-title="Gallery" align-title="center" ng-controller="photoCtrl" >
<ion-content ng-init="getImages()" class="center" class="has-header padding">
<!-- start Under6/7/8/9s Photos -->
<div class="item item-divider">
<i class="ion-images"></i> Under6/7/8/9s Photos
</div>
<a class="item item-list-detail">
<ion-scroll direction="x">
<img on-hold="onHold()" ng-repeat="image in images" ng-src="{{images.src}}" ng-click="showImages($index)" class="image-list-thumb" />
</ion-scroll>
</a>
</ion-content>
</ion-view>
I think the reason is in your JSON. What would you expect to happen when iterating over:
{"images":"http://cdn.caughtoffside.com/wp-content/uploads/2012/07/Marko-Marin.jpg"}
Probably your API should return an array of objects like
[{"src":"http://cdn.caughtoffside.com/.../Marko-Marin.jpg"},
{"src":"http://cdn.caughtoffside.com/.../Johnny-Blue.jpg"},
...
]
Iterating over an object usually looks different:
<div ng-repeat="(key, value) in myObj">
Try this:
<ion-scroll direction="x" ng-repeat="image in images">
<img on-hold="onHold()" ng-src="{{image.src}}" ng-click="showImages($index)" class="image-list-thumb" />
</ion-scroll>

Simple previous\next slider using angular

I have a web page which displays a list of items, the number of items can get quite big so I would like to display only 3 at a time and have next\previous buttons which let the user navigate between items.
I'm very new to Angular but I managed to retrieve all the items and display them on the UI but have no idea where to start to only display three and wire up the next and previous buttons to enable navigation.
Here's my code:
JS:
var app = angular.module('myApp', []);
app.controller('servicesController', function ($scope, $http) {
$http.get(url + "api/MapServiceAPI/GetServers")
.success(function (response) {
$scope.servers = response.Result;
});
});
HTML:
<div class="row top-space" ng-app="myApp" ng-controller="servicesController">
<div class="pull-left">
<img src="~/Content/Images/Service/PREVIOUS.png" />
<h4>PREVIOUS</h4>
</div>
<div class="pull-right">
<img src="~/Content/Images/Service/NEXT.png" />
<h4>NEXT</h4>
</div>
<ul class="col-md-3 text-center" ng-repeat="s in servers" ng-click="serviceClick(s.ServiceId)">
<li>
<div class="container">
<h4>{{ s.ServerName }}</h4>
</div>
<div class="container">
<img src="~/Content/Images/Server/SERVER.png" />
</div>
<div class="container">
<h5>{{ s.ServerDescription }}</h5>
</div>
</li>
</ul>
</div>
you can achieve using filters limitTo property
> <li ng-repeat="datalist in datalists | pagination: curPage * pageSize
> | limitTo: pageSize">
refere this jsfiddle which help you to understand better.
http://jsfiddle.net/dulcedilip/x7tg15v9/

How do I refresh my ng-repeat?

I have a controller (called "catalogueController") that manages my search box and my search page. I have the controller initially set the page to automatically call the search function defined in "catalogueController" when the app loads to pre-load my array of items (called Inventory) to be repeated via ng-repeat in the page.
The process runs like this:
1. I submit the search form.
2. "catalogueController" will send the search term to my factory (called "Search").
3. "Search" will have a function which will make a server call to query my database for that particular search.
4. The database will send the results of the search to the "Search" factory.
5. The "Search" factory will send the results to the "catalogueController" controller.
6. "catalogueController" will update the $scope.Inventory to be equal to the new result that I was received.
My problem is that ng-repeat does not refresh itself to display my new and updated $scope.Inventory array. $scope.Inventory definitely is updated (I have made sure of this through various console logs).
I have also tried to use $scope.$apply(). It did not work for me.
Thank you in advance for your help!
Here is my code:
HTML Template
<form role="search" class="navbar-form navbar-left" ng-controller="catalogueController" ng-submit="search(search_term)">
<div class="form-group">
<input type="text" placeholder="Search" class="form-control" ng-model="search_term">
</div>
<button type="submit" class="btn btn-default">Search</button>
</form>
<main ng-view></main>
catalogue.html partial
<div id="main" class="margin-top-50 clearfix container">
<div ng-repeat="items in inventory" class="row-fluid">
<div class="col-sm-6 col-md-3">
<div class="thumbnail"><img src="image.jpg" alt="..." class="col-md-12">
<div class="caption">
<h3>{{ items.itemName }}</h3>
<p>{{ items.description }}</p>
<p>Buy <a href="#" role="button" class="btn btn-default">More Info</a></p>
</div>
</div>
</div>
</div>
"app.js" Angular App
var myApp = angular.module('qcbApp', ['ngRoute', 'ngCookies', 'appControllers']);
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/login', {
templateUrl: 'html/partials/login.html',
controller: 'registrationController'
}).
when('/sign-up', {
templateUrl: 'html/partials/sign-up.html',
controller: 'registrationController'
}).
when('/catalogue', {
templateUrl: 'html/partials/catalogue.html',
controller: 'catalogueController'
}).
when('/', {
templateUrl: 'html/partials/qcbhome.html'
}).
otherwise({
redirectTo: '/'
});
}]);
"catalogueController" Controller
myApp.controller('catalogueController', ['$scope', 'Search', function($scope, Search) {
var time = 0;
var searchCatalogue = function(search) {
$scope.inventory = null;
console.log("Controller -- "+search);
Search.searchCatalogue(search)
.then(function(results) {
console.log(results);
$scope.inventory = results;
});
};
if(time == 0)
{
searchCatalogue('');
time++;
}
$scope.search = function(term) {
searchCatalogue(term);
}
}]);
"Search" Factory
myApp.factory('Search', ['$http', '$q', function($http, $q) {
function searchCatalogue(term) {
var deferred = $q.defer();
console.log("Factory -- "+term);
$http.post('/catalogue_data', {term: term}, {headers: {'Content-Type': 'application/json'}})
.success(function(result) {
console.log(result[0].SKU);
deferred.resolve(result);
console.log("Factory results -- "+result);
});
return deferred.promise;
}
return {
searchCatalogue: searchCatalogue
}; //return
}]);
I think the problem is the ng-repeat can not access the inventory in scope. You have to create a div which contains both the form and the ng-repeat.
The html should be:
<div ng-controller="catalogueController">
<!-- Move the controller from the form to parent div -->
<form role="search" class="navbar-form navbar-left" ng-submit="search(search_term)">
<div class="form-group">
<input type="text" placeholder="Search" class="form-control" ng-model="search_term">
</div>
<button type="submit" class="btn btn-default">Search</button>
</form>
<div id="main" class="margin-top-50 clearfix container">
<div ng-repeat="items in inventory" class="row-fluid">
<div class="col-sm-6 col-md-3">
<div class="thumbnail"><img src="image.jpg" alt="..." class="col-md-12">
<div class="caption">
<h3>{{ items.itemName }}</h3>
<p>{{ items.description }}</p>
<p>Buy <a href="#" role="button" class="btn btn-default">More Info</a></p>
</div>
</div>
</div>
</div>
</div>
I've seen the situation a few times where when you are updating a property directly on the $scope object there are interesting problems around databinding to that value (such as inventory). However if you databind to an object property of an object then the databinding works as expected. So for example use a property on $scope. I believe this is a copy by value vs copy by reference issue.
Update all your inventory references as follows
$scope.data.inventory = result;
Also don't forget to update your inventory reference in the html template:
<div ng-repeat="items in data.inventory" class="row-fluid">
Update: I made this plunk to figure it out - http://plnkr.co/edit/0ZLagR?p=preview
I think the primary problem is you have the controller specified twice. I removed it from the form and it started working.

Categories