ng-repeat conflics with jQuery function call - javascript

I combined AngularJS and MaterializeCSS and use ng-repeat to render images. MaterializeCSS includes the jQuery-based materiabox function to execute an animation to open a modal for each element with the materialbox class.
The modal can't be opened by clicking. If I display a single image without ng-repeat it works fine.
Here is my code:
HTML:
<div class="container" ng-controller="MainCtrl">
<span class="col m6 l4">
<li ng-repeat="url in imageUrls">
<img class="materialboxed" ng-src="{{ url }}">
</li>
</span>
</div>
Javascript:
var app = angular.module("app", []);
app.controller("MainCtrl", function($scope) {
$scope.imageUrls = ["https://d13yacurqjgara.cloudfront.net/users/179234/screenshots/1958409/screen_shot_2015-03-04_at_14.58.59.png", "https://d13yacurqjgara.cloudfront.net/users/5276/screenshots/1958408/booze_cruise_icon_kendrickkidd.jpg"];
});
// Code from MaterializeCSS
$(document).ready(function(){
$('.materialboxed').materialbox();
});

Hi i had the same problem , the solution is put the jquery code into a angularjs directive , some like:
Javascript
yourApp.directive('theNameOfYourDirective', function() {
return {
// Restrict it to be an attribute in this case
restrict: 'A',
// responsible for registering DOM listeners as well as updating the DOM
link: function() {
$('.materialboxed').materialbox();
}
};
});
and for the html code ,put the name of the directive like a attr of the tag:
HTML
<div class="container" ng-controller="MainCtrl">
<span class="col m6 l4">
<li ng-repeat="url in imageUrls" theNameOfYourDirective>
<img class="materialboxed" ng-src="{{ url }}">
</li>
</span>
this works for me, greetings
reference : https://amitgharat.wordpress.com/2013/02/03/an-approach-to-use-jquery-plugins-with-angularjs/

Related

Change div content dynamically on ng-click AngularJS

I want to display some data and tables in the content div which depends on which category you choose on the left hand side navigation.
So if I change the category also the displayed content of the content div should change.
Here is my code on Plunkr.
But it seems that not even this simple example is working.
So I have two Questions:
1.) How can I fix this example code to run ?
But more important:
2.) Is there a better way to change the content div when you change the category ?
I removed 'this' elements from code and also changed ng-view to ng-show.
<div>
<div ng-show="showApple">{{content}}</div>
<div ng-show="showBanana">{{content}}</div>
<div ng-show="showOrange">{{content}}</div>
</div>
There was something wrong with that you named your div class "content" so I removed that also.
I am sure it isn't a perfect solution but now it works.
link to plnkr
To be honest your best bet is to use $states/views. With a data-ui-view on the content div and a data-ui-sref link on the button on your menu, you can easily switch out content. Take a look at the ui-router page to get a better understanding of it. With templates for each 'view' that your menu will click to, your code will not just be much easier to manage, but probably more understandable.
You can use ng-include to show your contents but you have to keep them in seperate files e.g contentForApple, contentForBanana and contentForOrange.
Here I can show you a little change in your div
<div class="content">
<div ng-show="MainCtrl.showApple" ng-include ="'contentForApple.html'"></div>
<div ng-show="MainCtrl.showBanana" ng-include = "'contentForBanana.html'"></div>
<div ng-show="MainCtrl.showOrange" ng-include = "'contentForOrange.html'"></div>
</div>
Hope this help you. Take one json array for category and data and get details of json data which index is clicked
<!DOCTYPE html>
<html>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app="myApp" ng-controller="MyController">
<div class="container">
<div class="row">
<div class="col-lg-3">
<ANY ng-repeat="x in category" ng-click="getData($index)">
{{x.category}}<br>
</ANY>
</div>
<div class="col-lg-6">
{{data}}
</div>
</div>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('MyController', function ($scope)
{
$scope.data = '';
$scope.category = [{category:'Apple',data:'Apple Data'},{category:'Banana',data:'Banana Data'},{category:'Orange',data:'Orange Data'}];
$scope.getData = function(index)
{
$scope.data = $scope.category[index]['data'];
}
});
</script>
</body>
</html>
I did it with simple ngif
1) Keep an Index of Page which needs to be is loaded now
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.pageIndex = 0;
/*
* Updates current Page index
*/
$scope.changeIndex= function(indexToChange){
$scope.pageIndex = indexToChange;
}
});
2) Load content based on selected index
<body ng-controller="MainCtrl">
<div class="mainframe">
<div class="navigation">
<ul class="list-group">
<li class="list-group-item" ng-click="changeIndex(0)">Home<span class="status-icon"></span></li>
<li class="list-group-item" ng-click="changeIndex(1)">Sign Up<span class="status-icon"></span></li>
<li class="list-group-item" ng-click="changeIndex(2)">About<span class="status-icon"></span></li>
</ul>
</div>
<div class="content">
<div ng-if="pageIndex == 0" ng-include ="'Home.html'"></div>
<div ng-if="pageIndex == 1" ng-include = "'SignUp.html'"></div>
<div ng-if="pageIndex == 2" ng-include = "'About.html'"></div>
</div>
</div>
Final Result:
https://embed.plnkr.co/ic0eY2vwiOnChN2ahrEt/

View Source functionality using AngularJS

The feature I'm trying to implement is a toggle view source button so the user can view the source of a given element then copy the text.
Using the ngRoute module, my views are coming through ng-view:
<div id="code" ng-view=""></div>
I would like the HTML to be output to:
<div id="html-text-output"></div>
I've tried using the $sanitize function but I'm not sure it is appropriate for my solution. Below is the code currently in my controller:
angular.module('App')
.controller('outputHtmlCtrl', function ($scope, $element, $sanitize) {
$scope.isOutputToggled = true;
var sanatizedHtml = $sanitize($('#email-frame-code').html());
$scope.toggleHtmlOutput = function() {
$scope.isOutputToggled = $scope.isOutputToggled === false ? true: false;
$('#html-text-output').append("<div>"+"'"+sanatizedHtml+"'"+"</div>");
}
});
My markup is below:
<div id="email-frame-code__container" ng-controller="outputHtmlCtrl">
<div class="browser-header">
<span class="browser-header__icon" ng-click="toggleHtmlOutput()"></span>
</div>
<div id="email-frame-code" ng-class="{closed: isOutputToggled}">
<div id="html-text-output"></div>
<div id="code" ng-view=""></div>
</div>
</div>
My end goal for this is like the 'Fancy Version' here: https://css-tricks.com/examples/ViewSourceButton/
But on a target element, not the whole page.

angular expression working inside a script tag

How do I get an angular expression working inside a script tag... I am pretty new to this and need help?
Here is an example of my java script code:
<script id="modal-2.html" type="text/ng-template">
<div class="modal transparent">
<div class="card">
<i class="icon ion-ios7-close close-modal" ng-click="closeModal(2)"></i>
<div class="item item-divider">
{{card.title}}
</div>
<div class="item item-text-wrap">
{{card.details}}
</div>
</div>
</div>
</script>
Here is an example of my array:
.controller('TodoCtrl', function($scope, $ionicPopup, $timeout, $ionicModal, $ionicSideMenuDelegate) {
$scope.cardss =
{id:1, title:'Frank', src:'img/Frank.png',details:'This will be the products description!'},
{id:2, title:'Generali', src:'img/Generali.png',details:'This will be the products description!'},
{id:3, title:'John Lewis', src:'img/JohnLewis.png',details:'This will be the products description!'},
];
There is nothing special wrt use of AngularJS expressions inside partial templates.
As already said your model is actually array - so you'll have to iterate through the items using ng-repeat like this:
<ul>
<li ng-repeat="card in cards">
Card id: {{card.id}}
Card title: {{card.title}}
Card details: {{card.details}}
</li>
</ul>
Please see working JSFiddle example.
Here is an example how you can use your template:
<div ng-include src="'modal-2.html'"></div>
or use it with a button:
<button ng-click="currentTpl='modal-2.html'">Show Modal</button>
<div ng-include src="currentTpl"></div>
The expression in the template then works as is usual.
Here is an example.

AngularJS: Load dialog for ng-repeat with large number of items

I am trying to come up with a way to display a load dialog while the items in ng-repeat are being rendered. The use case is as follows:
User clicks a toggle switch to display a list of items
A directive is shown that contains an ng-repeat of items
The list of items show up almost instantly on a PC. But on a mobile device it takes a few seconds for the list to show up. This can cause the user to tap the toggle switch multiple times resulting in the list being hidden and shown.
Here's my HTML mark-up:
<div jqm-theme="b">
<div style="" jqm-theme="a" jqm-textinput ng-model="projectFilter"
placeholder="Filter Project Areas...">
</div>
<div style="height:12px;"></div>
<ul jqm-listview style="padding-top: 12px;">
<project-display title="My Project Areas" filter="projectFilter" projects="myProjects"
select-project="selectProject" show="true">
</project-display>
<li jqm-li-entry jqm-theme="b" class="ui-icon-alt">
<div class="ui-grid-a">
<div class="ui-block-a">
<a class="projTitle">Toggle All Projects</a>
</div>
<div class="ui-block-b" style="text-align:right;">
<div jqm-flip mini="true" jqm-theme="d" ng-model="allSwitch.value"
on-label="On" on-value="1" off-label="Off" off-value="0"
default-value="0" ng-click="toggleAllProj()">
</div>
</div>
</div>
</li>
<project-display title="All Project Areas" filter="projectFilter" projects="projects"
select-project="selectProject" show="allSwitch.value">
</project-display>
</ul>
</div>
Here's the directive:
angular.module('myApp').directive('projectDisplay', ['$location', function($location) {
return {
restrict: 'E',
scope: {
title: '#',
filter: '=',
projects: '=',
selectProject: '=',
show: '='
},
templateUrl: 'template/directives/project-display.html'
};
}]);
Here's the directive's template:
<div ng-show="show">
<span style="margin-left:13px" jqm-li-divider>{{title}} ({{projects.length}})</span>
<ul jqm-listview style="padding-top: 12px;">
<li jqm-li-link jqm-theme="a" style="margin-left:13px" class="ui-icon-alt" ng-click="selectProject(project)"
ng-repeat="project in projects | filter: filter">
<a>{{project.title}}</a>
</li>
</ul>
</div>
I am using Angular JQM's $loadDialog which can be shown and hidden by explicitly calling the separate methods or it can also display until a promise is resolved.
Is there a way to monitor when all items within an ng-repeat have been rendered? I appreciate any help on this matter.
Thanks

Process generated DOM code using jquery after $http Angular.js

I have the next problem:
Im trying to access and modify the dom generated html by angular after I make a request using $http method.
Example:
function Player($scope, $http) {
var $player = $(".player");
var _this = this;
var playing = false;
console.log('pepe');
// Getting Songs
$http.get('http://www.undert.com/components/player/js/songs.json').success(function (data) {
$scope.songs = data.songs;
console.log($player.find('li').length);
});
}
and the HTML is:
<div class="player" ng-controller="Player">
<ul class="playlist">
<li ng-repeat="song in songs">
<div class="album-art">
<div ng-show="!song.image">
<img src="http://undert.com/components/player/img/album_default.jpg" alt="{song.band}" />
</div>
<div ng-show="song.image">
<img src="http://undert.com/artists/{song.namespace}/images/albums/{song.image}" alt="{song.album}" />
</div>
</div> <a class="reproduction"></a>
<a class="close"></a>
<span class="title">{song.title}</span>
<span class="artist">{song.artist}</span>
<audio src="http://undert.com/artists/{song.namespace}/music/{song.song}"></audio>
</li>
</ul>
<div class="buttons">
<div class="play"></div>
<div class="prev"></div>
<div class="next"></div>
</div>
</div>
But when I try to read my generated code inside
<li ng-repeat="song in songs">
using jquery I cant (It doesnt exists yet, but im trying to do that inside "success" callback on $http method).
This work perfectly when I dont use $http and make the jsqon hardcoded inside my Player function.
thanks
I suggest you use $timeout like this:
$timeout(function(){ console.log($player.find('li').length); });
This will basically make your call happen only once Angular has finished generating the new DOM structure. Also $timeout has to be injected in the controller just like $http so your controller declaration should lokk like:
function Player($scope, $http, $timeout) {

Categories

Resources