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

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) {

Related

use angularjs http json result separately in scope

I used Angularjs $http and $scope to get data from sql server and display it successfully in scopes with no problem. But when I tried to display http json result from separated function in the same scope nothing happened.
All I wanted to know. If I want to get json object in a parameter and select slice from it before displaying, should I make http request every time to do so or can I separate scope away from http request in independent function as shown below.
<%--Angular--%>
<script src="../Scripts/angular.min.js"></script>
<script>
var jsonObj;
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope, $http) {
$http.get('../C_Angular.asmx/ShowSlider')
.then(function (response) {
jsonObj = response.data; // this part work well and retrieve data as expected by tracing C_Angular.asmx code
});
Select_From_Json = function (x, y) {
$scope.Categories = jsonObj.slice(x, y); // but this part don't work when I press Button1 to call Select_From_Json
};
});
</script>
When I press Button1 to call Select_From_Json fuction no displaying take place.
<input id="Button1" type="button" value="button" onclick="Select_From_Json(2, 4)" />
<div data-ng-app="myApp" data-ng-controller="myCtrl">
<div data-ng-repeat="Cat in Categories">
<div style="background-image: url('{{Cat.Cat_Pic}}');">
<span>{{Cat.Cat_Name}}</span>
</div>
</div>
</div>
Your button is outside the controllers scope. That is why the Select_From_Json is not executing properly.
Move the button inside the div where the controller is defined.
<div data-ng-app="myApp" data-ng-controller="myCtrl">
<input id="Button1" type="button" value="button" onclick="Select_From_Json(2, 4)" />
<div data-ng-repeat="Cat in Categories">
<div style="background-image: url('{{Cat.Cat_Pic}}');">
<span>{{Cat.Cat_Name}}</span>
</div>
</div>
</div>
You also should be using ng-click for executing functions from a controller like so:
<div data-ng-app="myApp" data-ng-controller="myCtrl">
<input id="Button1" type="button" value="button" ng-click="select_From_Json(2, 4)" />
<div data-ng-repeat="Cat in Categories">
<div style="background-image: url('{{Cat.Cat_Pic}}');">
<span>{{Cat.Cat_Name}}</span>
</div>
</div>
</div>
And in the controller itself:
$scope.select_From_Json = function(x, y){
$scope.Categories = jsonObj.slice(x, y);
}

Show a div with AngularJS

I am searching how to show a div with AngularJS. I read some topic on StackOverflow but when I try to apply them, it doesn't works for my case...
This is my HTML code :
<div id="myPanel" ng-controller="controllerDependance" ng-show="myvalue" class="ng-cloak">
Blablabla
</div>
<div id="DivWhereIsMyButton" class="clearfix" ng-controller="controllerBubble">
Another div where is my button
<div id="containerButton" ng-controller="controllerDependance">
<button class="btn btn-danger btn-lg pull-right"
ng-click="showAlert()">View dependances
</button>
</div>
</div>
This is the controller :
d3DemoApp.controller('controllerBubble', function () {
});
d3DemoApp.controller('controllerDependance', function ($scope) {
$scope.myvalue = false;
$scope.showAlert = function(){
$scope.myvalue = true;
};
});
I initially thought, it is controllerOther take the hand and cancel the controllerDiv but even if I separate the both, it doesn't works. The problem is I am obligated to put the both in two differents controllers.
I have two controllers, controllerDependance and controllerBubble. My div to show is in the controllerDependance. My button is in a div controllerBubble and I can't move it. So I would like to wrap it in a div controllerDependance.
I make a Plunker to show you the problem : https://plnkr.co/edit/z1ORNRzHbr7EVQfqHn6z?p=preview
Any idea ?
Thanks.
Put the div you want to show and hide inside the controller. It needs to be within the scope of the controller, otherwise your controller function cant see it. Also, consider what you are trying to accomplish with the nested controllers, I often find them unnecessary.
<div id="divButton" class="clearfix" ng-controller="controllerOther">
<div id="buttonToShowDiv" ng-controller="controllerDiv">
<button class="btn btn-danger btn-lg pull-right" ng-click="showAlert()">Show my div</button>
<div id="myDiv"ng-show="myvalue" class="ng-cloak">
Blablabla
</div>
</div>
</div>
I notice in your original example you are declaring ng-controller="controllerDependance" twice in the DOM. I have never tried this before, but I can imagine this will cause problems. From the angular documentation on controllers
When a Controller is attached to the DOM via the ng-controller directive, Angular will instantiate a new Controller object, using the specified Controller's constructor function. A new child scope will be created and made available as an injectable parameter to the Controller's constructor function as $scope
I imagine that this is what is causing you problems. You have to have the div you want to show/hide within the scope of your controller.
I got your plunkr working, you can see my version here: https://plnkr.co/edit/NXbsVFMNHR8twtL8hoE2?p=preview
The problem was stemming from you declaring the same controller twice, and more importantly, the div to show/hide was using ng-show with a value from your mainController. But your div was outside that controller. So ng-show cant see the value. The div has to be withing the scope of the controller
You are using two different controllers which have different $scopes therefore their values are not connected! To show or hide a div is really simple in angular:
<div id="divButton" class="clearfix" ng-controller="myController">
<div id="buttonToShowDiv">
<button class="btn btn-danger btn-lg pull-right" ng-click="showAlert()">Show my div</button>
</div>
<div id="myDiv" ng-show="myvalue" class="ng-cloak">
Blablabla
</div>
</div>
And the script side just almost the same:
d3DemoApp.controller('myController', function AppCtrl ($scope) {
$scope.myvalue = false;
$scope.showAlert = function(){
$scope.myvalue = true;
};
});
Since you question was how to show elements using angular, I took the liberty of using just one controller.
Create a factory that will return an object and let your controllers work with a reference to the same object:
var d3DemoApp = angular.module('app', [])
d3DemoApp.factory('MyValue', function () {
return { value: false };
});
d3DemoApp.controller('controllerBubble', function ($scope, MyValue) {
$scope.myvalue = MyValue;
});
d3DemoApp.controller('controllerDependance', function ($scope, MyValue) {
$scope.myvalue = MyValue;
$scope.showAlert = function(){
$scope.myvalue.value = true;
};
});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-app="app">
<div ng-controller="controllerBubble" class="clearfix">
<div id="myPanel" ng-controller="controllerDependance" ng-show="myvalue.value" class="ng-cloak">
Blablabla
</div>
</div>
<div id="DivWhereIsMyButton" class="clearfix" ng-controller="controllerBubble">
Another div where is my button
<div id="containerButton" ng-controller="controllerDependance">
<button class="btn btn-danger btn-lg pull-right" ng-click="showAlert()">View dependances</button>
</div>
</div>
</div>
</body>
</html>

How can I show images on load with Angularjs?

I am trying to hide an image until it is loaded, and then use the onload method to call a jQuery function that shows it. I use the angular ng-repeat property $index to assign a unique ID to each image div. The $index property works, since all my images have ID's like img0, img1, and so on. My problem is that onload is not passing the angular variable, which contains the unique div ID, to my function. Are angular variables unable to be used inside the onload method? If not, how can I make it so?
<div class="hello" ng-repeat="artist in artists" ng-hide="!artiste">
<div class="paintings" id="img{({$index})}" style="display:none;">
<a href="{({ artist.fields.link })}">
<img src="{({ artist.fields.link })}" onload="showImageDiv(img{({$index})})" />
</a>
<h3> {({ artist.fields.title })} </h3>
</div>
</div>
<script>
function showImageDiv(imageDivId){ // never receives imageDivId
$('#' + imageDivId).show();
};
</script>
It doesn't work this way - attribute onload is not a directive, so its value is not parsed by angular. You could use a custom directive though, for example (assuming there is a "myModule" module defined):
angular.module("myModule").directive("showOnLoad", function() {
return {
link: function(scope, element) {
element.on("load", function() {
scope.$apply(function() {
scope.artist.visible = true;
});
});
}
};
});
It would set the artist.visible field value to true after the load event. This should work after some changes to the markup:
<div class="paintings" ng-show="artist.visible">
<a href="{{ artist.fields.link }}">
<img ng-src="{{ artist.fields.link }}" show-on-load /></a>
<h3> {{ artist.fields.title }} </h3>
</div>
You should use ng-init instead. Replace
onload="showImageDiv(img{({$index})})"
with
ng-init="showImageDiv($index)"
And since you are using angular, make use of your controller. Inside your controller, write this:
$scope.showImageDiv = function(index){
jQuery('#img'+index).show();
}
Update :
You can also make use of ng-show, instead of jQuery:
<img src="{({ artist.fields.link })}" ng-init="showImageDiv($index)" ng-show="img[$index]" />
And in controller:
$scope.img=[];
$scope.showdiv = function(index){
$scope.img[index] = true;
}

ng-repeat conflics with jQuery function call

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/

AngularJS - change parent scope from directive?

I'm building my first Angular app, but am having a bit of trouble getting something to work. I have a video container that will be hidden until $scope.video.show = true; I'm trying to set this value when I click on a link. I'm trying to make that happen in a directive. Any help would be appreciated.
html:
<div ng-controller="AppCtrl">
<div ng-cloak
ng-class="{'show':video.show, 'hide':!video.show}">
// youtube iframe content, for example
</div>
<div>
<ul>
<li>
<h3>Video Headline 1</h3>
<button type="button"
video-show
data-video-id="jR4lLJu_-wE">PLAY NOW 〉</button>
</li>
<li>
<h3>Video Headline 2</h3>
<button type="button"
video-show
data-video-id="sd0f9as8df7">PLAY NOW 〉</button>
</li>
</ul>
</div>
</div>
javascript:
var thisViewModel = angular.module("savings-video", [])
.controller('SavingsVideoController', function($scope) {
$scope.video = {
show : false,
videoId : ""
};
};
thisViewModel.directive("videoShow", function(){
return{
restrict: 'A',
link: function(scope , element){
element.bind("click", function(e){
var $this = angular.element(element);
$this.closest('li').siblings().addClass('hide'); // hide the other one
$this.closest('li').removeClass('hide'); // keep me open
scope.video.show = true; // doesn't work.
// what is the best way to do this?
});
}
}
});
I see a few things you can improve.
Checkout ngShow/ngHide and ngIf; they'll give you toggle-ability more easily than trying to do it from scratch.
Think in angular. Rather than trying to use logic to modify the DOM on your own, simply setup your rules using angular directives, and let the framework do the rest for you.
For example, it seems like this is more what you want.
<div ng-controller="AppCtrl">
<div ng-cloak ng-show='video.show">
// youtube iframe content, for example
</div>
<div>
<ul ng-switch="video.videoId">
<my-video my-video-id="jR4ABCD" my-headline="Video Headline 1" ng-switch-when="myVideoId" my-video-manager="video" />
<my-video my-video-id="al1jd89" my-headline="Video Headline 2" ng-switch-when="myVideoId" my-video-manager="video"/>
</ul>
</div>
</div>
What I changed is making your iframe show conditionally with ngShow, and using ngSwitch to control which video appears (the appearing video is based on the $scope's video.videoId). Then, I turned your <li>s into a directive called my-video, which ends up looking like this
thisViewModel.directive("my-video", function(){
return{
restrict: 'E',
replace: true,
scope: {
myVideoId = "=",
myHeadline = "=",
myVideoManager = "="
},
template = '<li><h3>{{myHeadline}}</h3><button type="button" ng-click="play()">PLAY NOW 〉</button></li>',
link: function(scope , element){
scope.play = function(){
myVideoManager.show = true;
/*whatever you want here, using scope.myVideoId*/
}
}
}
});
This directive does exactly what your old HTML did, but brings it into the angular framework so you can access the properties you're looking for. By using the raw angular directives, I eliminate the need for any manual UI logic; I don't need to access element at all anymore, and both my HTML and JavaScript are cleaner. There's certainly room for improvement here, even, but I would say that this is closer to the right track.
It takes practice to get more familiar with, but following the guidelines in the SO link above will help.
EDIT
Sorry, think I missed a requirement the first time around. If you want both videos to show when none are selected, don't use ng-switch; just set up some manual ng-shows.
<div>
<ul>
<my-video my-video-id="jR4ABCD" my-headline="Video Headline 1" ng-show="myVideoId == video.videoId" my-video-manager="video" />
<my-video my-video-id="al1jd89" my-headline="Video Headline 2" ng-show="myVideoId == video.videoId" my-video-manager="video"/>
</ul>
</div>
Since ng-switch is really just a shortcut for ng-show anyways, it amounts to the same thing; the logic just got moved into the ng-show attribute instead.
Also, if you have an array of videos, checkout out ng-repeat; it will let you repeat your video tag multiple times automatically, instead of by hand.
<ul>
<my-video ng-repeat='aVideo in myVideoArray' my-video-id='aVideo.videoId' my-headline...(and so on)>
</ul>
Well your controller names don't match up. Try changing AppCtrl to SavingsVideoController.
You only need a very simple solution.
HTML
<div ng-controller="AppCtrl">
<div ng-cloak ng-show="view.show">
<!-- Use ng-show is more convenient -->
</div>
<div>
<ul>
<li>
<h3>Video Headline 1</h3>
<button type="button"
ng-click="view.show = true"
data-video-id="jR4lLJu_-wE">PLAY NOW 〉</button>
<!-- You don't need an extra directive to change view.show -->
</li>
<li>
<h3>Video Headline 2</h3>
<button type="button"
ng-click="view.show = true"
data-video-id="sd0f9as8df7">PLAY NOW 〉</button>
</li>
</ul>
</div>
</div>
JS
var thisViewModel = angular.module("savings-video", [])
.controller('SavingsVideoController', function($scope) {
$scope.video = {
show : false,
videoId : ""
};
};
// No need to create another directive

Categories

Resources