How do you call an AngularJS function from javascript? - javascript

I am trying to call the AngularJS method advanceSlide() from my Javascript after the if statement, however,this line:
angular.element(document.getElementById('FotoSpill')).scope().advanceSlide();
doesn't seem to be working. Here is the full code.
Javascript
window.onload = function() {
cast.receiver.logger.setLevelValue(0);
window.castReceiverManager = cast.receiver.CastReceiverManager.getInstance();
console.log('Starting Receiver Manager');
// handler for the CastMessageBus message event
window.messageBus.onMessage = function(event) {
console.log('Message [' + event.senderId + ']: ' + event.data);
// display the message from the sender
displayText(event.data);
if (event.data == "quit") {
angular.element(document.getElementById('FotoSpill')).scope().advanceSlide();
};
// inform all senders on the CastMessageBus of the incoming message event
// sender message listener will be invoked
window.messageBus.send(event.senderId, event.data);
}
ANGULARJS
var FotoSpill = angular.module('FotoSpill', []);
FotoSpill.config(['$routeProvider', '$locationProvider', function( $routeProvider, $locationProvider ) {$routeProvider.when('/tag/:tag');}]);
FotoSpill.controller('slideshow', function ( $scope, $http, $timeout, $route, $location ) {
// Set the API endpoint
var api = 'https://api.instagram.com/v1/locations/436022/media/recent?access_token=257058201.9af4692.3d68e63b114944a0be332da732923a23&callback=JSON_CALLBACK',
newReq, refreshApi;
var seconds = 1000;
$scope.fetchImages = function() {
$scope.loadingClass = 'loading';
$scope.imgCurrent = 0;
// if ( ! $route.current )
// $location.path( '/tag/' + $scope.tag );
// else if ( angular.isDefined( $route.current.params.tag ) )
// $scope.tag = $route.current.params.tag;
$http.jsonp(
api.replace( '%tag%', $scope.tag )
).success( function( data ) {
delete $scope.loadingClass;
$scope.images = data.data;
// Set the first image active
if ( data.data.length )
$scope.makeActiveSlide( $scope.imgCurrent );
// Cancel the previous update request
if ( refreshApi )
$timeout.cancel( refreshApi );
// Check for new images on every loop
if ( data.data.length )
refreshApi = $timeout( $scope.fetchImages, 60*seconds );
}).error( function() {
delete $scope.loadingClass;
refreshApi = $timeout( $scope.fetchImages, 2*seconds );
});
}
// Fetch images
$timeout( $scope.fetchImages );
$scope.advanceSlide = function() {
// Method 1
// Use a classname to highlight the current active slide
if ( angular.isDefined( $scope.images ) && $scope.images.length )
$scope.makeActiveSlide( $scope.imgCurrent + 1 );
$timeout( $scope.advanceSlide, 6*seconds ); //time between slide transition
}
}
).filter(
'escape', function () {
return function( input ) {
return escape( input );
}
}
);

you need to apply your changes
angular.element(document.getElementById('FotoSpill')).scope().$apply('$scope.advanceSlide()');
try that

Don't know how is your HTML, but it seems the problem is about the DOM selected, or say, jqLite selecter.
If you are using something like <div ng-controller="slideshow"></div>, you can use:
angular.element('[ng-controller=slideshow]').scope().$apply('advanceSlide()');
This code first try to find the correct DOM node regarding the scope you want to access with angular.element, then retrieve its scope through scope(), finally $apply a expression in the context of the scope.

Related

PhantomJS Getting Attribute

If I have this:
<video data-autostart="false" data-src="http://example.com/1.mp4">
I get the error below:
TypeError: undefined is not an object
Below is my JavaScript code:
var page = require( 'webpage' ).create();
var url = 'http://example.com/';
page.open(url, function( status ) {
if ( status === 'success' ) {
page.includeJs('https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js', function() {
var link = page.evaluate(function() {
return $( 'video[data-autostart="false"]' ).attr( 'data-src' );
});
console.log( link );
phantom.exit();
});
} else {
console.log( 'FAIL' );
}
});
What am I doing wrong and how can I resolve it?
You're doing almost everything right, but the element you're looking for apparently doesn't exist when you access it in the script.
Therefore the error, undefined is not an object. The element you try to access is undefined, doesn't exist.
You could check that an element is there before accessing it:
var link = page.evaluate(function() {
if($( 'video[data-autostart="false"]' ).length != 0)
{
return $( 'video[data-autostart="false"]' ).attr( 'data-src' );
}
else
{
return false;
}
});
if (link === false) {
console.log("Video not found!");
phantom.exit(1); // Error exit code
}
The complete working example:
var url = "http://html5demos.com/video";
var page = require( 'webpage' ).create();
page.open(url, function( status ) {
if ( status === 'success' ) {
page.includeJs('https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js', function() {
var link = page.evaluate(function() {
if($( 'video' ).length != 0)
{
return $( 'video' ).attr('preload');
}
});
console.log( link );
phantom.exit();
});
} else {
console.log( 'FAIL' );
}
});
Prints
metadata

Ckeditor not working with angular App

I am having issue with ckeditor4.When I run it independently its working fine.But when I trying to run it with my angular app its not working.Here is my sample code:
var initSample = ( function() {
var wysiwygareaAvailable = isWysiwygareaAvailable(),
isBBCodeBuiltIn = !!CKEDITOR.plugins.get( 'bbcode' );
return function() {
var editorElement = CKEDITOR.document.getById( 'editor' );
// :(((
if ( isBBCodeBuiltIn ) {
editorElement.setHtml(
'Hello world!\n\n' +
'I\'m an instance of [url=http://ckeditor.com]CKEditor[/url].'
);
}
// Depending on the wysiwygare plugin availability initialize classic or inline editor.
if ( wysiwygareaAvailable ) {
CKEDITOR.replace( 'editor' );
} else {
editorElement.setAttribute( 'contenteditable', 'true' );
CKEDITOR.inline( 'editor' );
// TODO we can consider displaying some info box that
// without wysiwygarea the classic editor may not work.
}
};
function isWysiwygareaAvailable() {
// If in development mode, then the wysiwygarea must be available.
// Split REV into two strings so builder does not replace it :D.
if ( CKEDITOR.revision == ( '%RE' + 'V%' ) ) {
return true;
}
return !!CKEDITOR.plugins.get( 'wysiwygarea' );
}
}
When I console after "isBBCodeBuiltIn = !!CKEDITOR.plugins.get( 'bbcode' )" line its consoling fine.But it is not entering inside return function() { }.Any suggestion?

How to retrieve the ajax data whose loading requires a mouse click with PhantomJS or other tools

I'm using PhantomJS to retrieve this page: Target Page Link. The contents I need are under the "行政公告" and "就業徵才公告" tabs. Because this page is written in Chinese, in case you cannot find the tabs, you can use "find" function of the browsers to find the "行政公告" and "就業徵才公告" tabs. Because the contents under the "行政公告" tab are the loaded as the default option, I can easily use the script below to retrieve the page:
var page = require('webpage').create();
var url = 'http://sa.ttu.edu.tw/bin/home.php';
page.open(url, function (status) {
var js = page.evaluate(function () {
return document;
});
console.log(js.all[0].outerHTML);
phantom.exit();
});
But the contents under the "就業徵才公告" tab are not loaded after I use the PhamtomJS to emulate the mouse click with the code below:
var page = require('webpage').create();
var url = 'http://sa.ttu.edu.tw/bin/home.php';
page.open(url, function (status) {
page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
// jQuery is loaded, now manipulate the DOM
$('#sm_adf63b93c89375a0bade42e5360b73274_1_Dyn_2_1').trigger('mouseover');
});
var js = page.evaluate(function () {
return document;
});
console.log(js.all[0].outerHTML);
phantom.exit();
});
This doesn't work as the contents under the "就業徵才公告" tab are not loaded. How should I do to retrieve the contents under the "就業徵才公告" tab?
Update:
After read a PhantomJS example, I refactored the code to below. It didn't work because the contents under the "就業徵才公告" tab are not loaded.
var page = require('webpage').create();
var address = 'http://sa.ttu.edu.tw/bin/home.php';
page.open(address, function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit();
} else {
window.setTimeout(function () {
var results = page.evaluate(function() {
$('#sm_adf63b93c89375a0bade42e5360b73274_1_Dyn_2_1').trigger('mouseover');
return document.documentElement.innerHTML;
});
console.log(results);
phantom.exit();
}, 5000);
}
});
If any way could solve this problem is welcomed. Not limited to PhamtoJS.
Tested this code, and it outputs the correct image with the desired tab selected. It wasn't so straightforward because of the underlying structure of the page. Hopefully you can use this as a bit of a learning exercise in processing the DOM.
// utility function to send mouseclick event to an element
function mouseclick( element ) {
// create a mouse click event
var event = document.createEvent( 'MouseEvents' );
event.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
// send click to element
element.dispatchEvent( event );
}
// final function called, output screenshot, exit
function after_clicked( page ) {
console.log( "+after_clicked()" );
page.render( "after_click.png" );
console.log( "Done" );
phantom.exit( 0 );
}
// middle function, click on desired tab
function click_div( page ) {
console.log( "+click_div()" );
var clicked = page.evaluate(
function ( mouseclick_fn ) {
// want the div with class "submenu"
var div = document.querySelector( "div.submenu" );
if ( ! div ) {
return false;
}
// want all the list elements in the div
var li_array = div.querySelectorAll( "li" );
if ( ! li_array ) {
return false;
}
// we want the 2nd list element
var li2 = li_array[1];
if ( ! li2 ) {
return false;
}
// want the anchor inside the 2nd list element
var anchor = li2.querySelector( "a" );
if ( ! anchor ) {
return false;
}
// must focus on anchor to trigger underlying javascript on page
anchor.focus();
// want the div within this anchor, so we can click on the div
var element = anchor.querySelector( "div" );
if ( ! element ) {
return false;
}
// click on this inner div
mouseclick_fn( element );
return true;
}, mouseclick
);
if ( ! clicked ) {
console.log( "Failed to find desired element" );
phantom.exit( 1 );
return;
}
console.log( "- clicked, waiting 5 seconds" );
window.setTimeout(
function () {
after_clicked( page );
},
5000
);
}
// first function, create page, load page
function main() {
console.log( "+main()" );
var page = require('webpage').create();
page.open(
"http://sa.ttu.edu.tw/bin/home.php",
function (status) {
if ( status !== 'success' ) {
console.log( "Failed" );
phantom.exit( 1 );
return;
}
console.log( "- page loaded, waiting 2 seconds..." );
window.setTimeout(
function () {
click_div( page );
},
2000
);
}
);
}
main();

jquery data returns 'undefined'

I'm trying to store some data in DOM Elements ($.cache) on my plugin but I am facing some problem as mentioned below...
$(_buelement).data('yazi') returns undefined on metodlar.gizle but it works on metodlar.goster where I store the data.
In my plugin metodlar.goster initiates on onMounseIn and metodlar.gizle onMouseOut.
$.fn.balon = function( metod, girdi ) {
var _bu = this;
var metodlar = {
goster : function( ) {
return _bu.each(function ( ) {
var _buelement = $(this);
s.pozisyonAl(_buelement);
s.balon.fadeIn(300);
$.data(_buelement,{'balon' : s.balon,'yazi':'heyho'});
})
},
gizle : function( ) {
return _bu.each(function ( ) {
var _buelement = $(this);
$(_buelement).data('yazi');
})
}
}
});
Finally I ran some debug and found out the metodlar.gizle is just works fine but data is still undefined.
Here's Fiddle Link : http://jsfiddle.net/4FfWz/4/
Try changing the way you store the data in goster:
_buelement.data({'balon' : s.balon,'yazi':'heyho'});
Try this:
gizle : function( ) {
return _bu.each(function ( ) {
var _buelement = $(this);
_buelement.data('yazi');
})
}

jQuery unbind event from whole array

Hi does anybody know how is jquery unbind function woking?I have a jquery powered photogallery where I am binding some stuff on load event(change image and so on)..But when the user is quickly walking through the gallery I want to unbind "older" events and than bind load event only on the last image. Otherwise the user will see every image he walked through for a tiny moment and I only want to show the last one..(performance, UX,..)I store every loaded(not exactly loaded, too every requested) image in an array, so everytime I call my loadImage function I call jQuery(myArrayWithImages).unbind("load.backgroundImagesLoader")
but it seems it does not work, the load events are still there (its a bit weird, I cant find it in debugger, but I see it:))
Is there any way to unbind the events from whole array, or from whole js instance, except do it through foreach?
Here is some code snippet..It is whole loadImage function..
function loadImage(index , showLoading, callback){
if(backgroundImages==undefined) backgroundImages=Array();
//if(backgroundImages[window.location.hash][index]==undefined)backgroundImages[window.location.hash][index] = Array();
jQuery("#galleryEl .sig_thumb a").each( function( pos , el ) {
var wh_bg_b = getVierwportSize();
if(index == pos){
var bg_img_path_b = jQuery(el).attr('href');
var size = 'max';
if ( bg_img_path_b != undefined ) {
if ( (wh_bg_b[0] < 1281) && (wh_bg_b[1] < 801) ) {
size = 'min';
bg_img_path_b = bg_img_path_b.substring( 0, bg_img_path_b.lastIndexOf("/") ) + "/1280/" + bg_img_path_b.substring( bg_img_path_b.lastIndexOf("/")+1 );
} else if ( (wh_bg_b[0] < 1441) && (wh_bg_b[1] < 901) ) {
size = 'med';
bg_img_path_b = bg_img_path_b.substring( 0, bg_img_path_b.lastIndexOf("/") ) + "/1440/" + bg_img_path_b.substring( bg_img_path_b.lastIndexOf("/")+1 );
}
}
console.log("test");
if(backgroundImages[bg_img_path_b]!=undefined){
if(backgroundImages[bg_img_path_b].loaded=="true"){
//console.log(index+" "+backgroundImages[window.location.hash][index][size]['loaded']);
if(typeof callback=='function'){
callback.call(this, bg_img_path_b);
} }
else if(backgroundImages[bg_img_path_b].loaded=="loading"){
jQuery(backgroundImages).unbind('load.backgroundImages');
jQuery(backgroundImages[bg_img_path_b]).bind('load.backgroundImages',function(){
backgroundImages[bg_img_path_b].loaded="true";
if(typeof callback=='function'){
callback.call(this, bg_img_path_b);
//console.log("loaded "+index);
}
});
}
}
else{
backgroundImages[bg_img_path_b]=new Image();
backgroundImages[bg_img_path_b].src = bg_img_path_b;
backgroundImages[bg_img_path_b].loaded="loading";
jQuery(backgroundImages).unbind('load.backgroundImages');
jQuery(backgroundImages[bg_img_path_b]).bind('load.backgroundImages',function(){
backgroundImages[bg_img_path_b].loaded="true";
if(typeof callback=='function'){
callback.call(this, bg_img_path_b);
//console.log("loaded "+index);
}
});
}
console.log(backgroundImages[bg_img_path_b]);
//console.log(size);
//console.log(backgroundImages);
}
} );
}
You need to unbind not like
jQuery(myArrayWithImages).unbind("load.backgroundImagesLoader")
but
jQuery(myArrayWithImages).unbind(load.backgroundImagesLoader).
Just read manual, you can use namespaces:
$('#foo').bind('click.myEvents', handler);
and
$('#foo').unbind('click.myEvents');

Categories