Jwplayer - Error: jwplayer(...).setup is not a function - angularjs

I have to show jwplayer in a popup, for popups I am using ngDialog(angular), code for ngDialog is below:
$scope.showVideoPlayerPopup = function(video_path)
{
$scope.ngDialog = ngDialog;
ngDialog.open({
animation: true,
scope:$scope,
template:'<div id="video_popup"></div>',
plain: true,
//className: 'ngdialog-theme-default',
closeByDocument: true
//backdrop : 'static'
});
playVideo(video_path);
}
play video function called above contains code for jwplayer, which is below:
<script>
function playVideo(video_path)
{
jwplayer("video_popup").setup({
file: video_path,
width: "600px",
height: "600px",
stretching: "bestfit",
});
}
</script>
when I use the same jwplayer code for simple html code which is without popup it works fine but I try to put my html in popup it gives me below error:
Error: jwplayer(...).setup is not a function
update
Files I have included:
<script src="https://content.jwplatform.com/libraries/qAkRysIB.js"></script>

Ensure the jwplayer src is included (you likely already did but in case not:)
Update 11/2021
see the section Cloud-hosted on the documentation page Add a player library. This will require obtaining a JWPlayer account.
From your Player Downloads & Keys page, scroll down to the Cloud Hosted Player Libraries section.
In the Cloud Hosted Player Libraries section, select a Player Title from the dropdown menu.
Copy the Cloud Player Library Url.
Within the <head> of your page, copy and paste the URL to the player library.
<script src="{cloud_hosted_player_library_url}"></script>
Ensure that the panel has loaded before calling the setup function. One way to do this is to register an event listener for ngDialog.opened from the ngDialog (see the Events section of the ngDialog readme):
$scope.$on('ngDialog.opened', function (e, $dialog) {
playVideo();
});

Yes...because your div tag with id "current_video_path" has to be there in DOM before jwplayer(...).setup script can work...May be you can add some delay using $timeout or setTimeout so it will have enough time to render div in popup before this script can wrok..

Related

Render plaintext using Angular route, ui-view

I am using Angular 1.3, creating views using ui-router and ui-view.
I have added the ui-view on index.html file, which has Menu, footer and in the middle ui-view for main content.
I have created whole application using states with $stateProvider.state('state_name')
Now I want to create a page with plain text, no html tags, just plaintext. But the problem is when I create route for that, it includes header and footer, which is correct behavior of Angular. But how can I create a view with no menu, footer included, just plain text which I will add in view file, with route. Any solution?
You can have a service that changes is bond to the main controller. The first answer to this question explains how this can be achived.
I've made a modified Plnkr example for your specific use case here
app.factory('Page', function(){
var visible = true;
return {
visible: function() { return visible; },
setVisible: function(state) { visible = state}
};
});
The factory called Page provides access to a visible variable for both the main controllers and the controllers inside the ng-views.
The aim is to change this visible variable in the controller in order to change the visibility of the main components outside of the ng-view.
function MainCtrl($scope, Page) {
$scope.Page = Page;
}
To this end we have a binding in the main controller that can access the page service.
<html ng-app="myApp" ng-controller="MainCtrl">
<body>
<h1 ng-hide="Page.visible()">Page Header</h1>
<ul>
<li>test1
<li>test2
</ul>
</html>
And in the html, we define that the ng-if is controlled by this visible variable in the MainContorllers Page.
function Test1Ctrl($scope, Page) {
Page.setVisible(false);
}
Finally, we can call the change visibility function from the other views in order to change the visibility of the headers and footers in the Main View.

Theater.js not working on page loaded with Angular ui route

I am trying to make Theater.JS work with Angular application.
If Div in which TheaterJS is supposed to insert dynamically typed contents is on the index page, it works perfectly fine.
But if I keep the same div on the page which is loaded using ui-view (or using ng-view for that matter), TheaterJs throws following exception
Uncaught TypeError: Cannot set property 'innerHTML' of null
I understand its happening because TheaterJs is loaded before main.html page is loaded through ui-view. But I am not sure how to handle this scenario.
Here is the plnkr demo with the example. The TheaterJS works when div is on index page but fails to work when the div is on main.html which is loaded dynamically using ui-view.
In my project, I want to use TheaterJS on a page loaded using ui-view.
By placing the script include into the <head> and moving the call to new TheaterJS() into a directive, you are able to use it in your partials.
Here is a plunker showing your working template:
http://plnkr.co/edit/JAbSmNOAZtUMkc976sh8?p=preview
Directive:
app.directive("theaterDirective", function() {
return {
link: function () {
var theater = new TheaterJS();
theater.describe("text", {speed: .7, accuracy: .7}, "#text");
theater.write("text:It now works in template partials", 600);
theater.write("text:It is no longer restricted to the Index page", 600);
theater.write(function () { theater.play(true); });
}
}
})
HTML partial:
<h1>This is main.html page content</h1>
<h1 theater-directive id="text"><noscript></noscript></h1>

Build an Ionic App with Wistia Player API not working on iOs.

So I am building an Ionic / AngularJS app using Wistia player API. I finial tried and everything work right on browser test mode. But when compile onto iOs, it just show white screen. Here is the detail:
View - HTML page:
<!-- Wistia Embed -->
<div id="{{ 'wistia_' + mediaHashId }}" class="wistia_embed" style="width:398px;height:224px;" ng-if="mediaHashId"></div>
Controller:
$timeout(function() {
var wistiaEmbed = Wistia.embed($scope.mediaHashId, {
videoFoam: true,
playerColor: "3B97D3"
});
wistiaEmbed.bind("end", function () {
alert ("Video is finished");
});
}, 100);
So it load perfectly onto Chrome.
But when I compile it onto xcode and run it on my phone. It just show a white screen (with no JS error!)
SECOND OPTION: iframe - since iframe load okay on iOs (http://wistia.com/doc/player-api#using_iframes_and_the_player_api).
The second option is attach wistiaApi onto an iframe. But the code does not work.
View - HTML page:
<div class="video-container">
<iframe id="wistia_player" ng-src="{{ mediaHashId | wistiaEmbedUrl }}" allowtransparency="true" frameborder="0" scrolling="no" class="wistia_embed" name="wistia_embed" width="640" height="360"></iframe>
</div>
Controller:
$timeout(function() {
var wistiaEmbed = document.getElementById("wistia_player").wistiaApi;
console.log (wistiaEmbed);
wistiaEmbed.bind("end", function () {
alert ("Video is finished");
});
}, 100);
The wistiaEmbed console log an undefined.
And error log:
TypeError: Cannot read property 'bind' of undefined
at lesson-detail-ctrl.js:46
at ionic.bundle.js:24922
at completeOutstandingRequest (ionic.bundle.js:13604)
at ionic.bundle.js:13984
So clearly .wistiaApi does not work...
I do include this in my index.html:
I will love a AngularJS library like this https://github.com/brandly/angular-youtube-embed with Wistia Player...but no luck...
Wow, I've found the problem. This is actually a very common problem when building ionic apps on iOs and/or Android. When you include <script> tags in your index.html, always put the full http://.... instead of using just //.
In my case, I included the Wistia API via their official documentation like:
<script src="//fast.wistia.com/assets/external/E-v1.js"></script>
It works on browsers because browsers are smart. Devices are not as smart as browsers so by including the http like so:
<script src="https://fast.wistia.com/assets/external/E-v1.js"></script>
Solves it!

extjs panel html add javascript function don't work

in my extjs app, i create a panel, i also add jquery to one page, however when i click the test section in this page, this page don't render test alert, it seems extjs panel forbid the jquery function. is there any solution to load both html and js to panel content.
relative code below:
var feedback=Ext.create('Ext.panel.Panel', {
title: 'Hello',
layout: 'fit',
autoScroll: true,
bodyStyle:{"background-color":"#fed"},
html: '<div id="test">test</div>',
});
....
$("#test").click(function(){
alert('test')
})
By experience, mixing jquery selector and Extjs element can be pain to manage together. I would suggest to use Ext js selector to do what you're trying to achieve in jquery, since it's pretty basic. However, if you still want to use jquery, using on() function could help, the object is maybe not rendered yet when your jquery code is reached.
$("#test").on('click', function(){
alert('test')
})

Cordova + Angularjs + Device Ready

I am developing a mobile application using Cordova and AngularJS. How do I restrict bootstrapping of AngluarJS before Cordova device ready. Basically I don't want to use any of AngularJS controllers before device ready.
Manually bootstrap your Angular app:
Remove your ng-app attribute from your HTML code, so Angular doesn't start itself.
Add something like this to you JavaScript code:
document.addEventListener("deviceready", function() {
// retrieve the DOM element that had the ng-app attribute
var domElement = document.getElementById(...) / document.querySelector(...);
angular.bootstrap(domElement, ["angularAppName"]);
}, false);
Angular documentation for bootstrapping apps.
I'm using the following solution, which allows AngularJS to be bootstrapped when running with Cordova as well as when running directly in a browser, which is where much of my development takes place. You have to remove the ng-app directive from your main index.html page since that's what the manual bootstrapping is replacing.
UPDATE: I've since switched to the following method, which I think is cleaner. It works for Ionic as well as vanilla Cordova/PhoneGap. It should be the last bit of JavaScript to run - perhaps inside a script tag before the /body tag.
angular.element(document).ready(function () {
if (window.cordova) {
console.log("Running in Cordova, will bootstrap AngularJS once 'deviceready' event fires.");
document.addEventListener('deviceready', function () {
console.log("Deviceready event has fired, bootstrapping AngularJS.");
angular.bootstrap(document.body, ['app']);
}, false);
} else {
console.log("Running in browser, bootstrapping AngularJS now.");
angular.bootstrap(document.body, ['app']);
}
});
Here's the older solution I used:
// This is a function that bootstraps AngularJS, which is called from later code
function bootstrapAngular() {
console.log("Bootstrapping AngularJS");
// This assumes your app is named "app" and is on the body tag: <body ng-app="app">
// Change the selector from "body" to whatever you need
var domElement = document.querySelector('body');
// Change the application name from "app" if needed
angular.bootstrap(domElement, ['app']);
}
// This is my preferred Cordova detection method, as it doesn't require updating.
if (document.URL.indexOf( 'http://' ) === -1
&& document.URL.indexOf( 'https://' ) === -1) {
console.log("URL: Running in Cordova/PhoneGap");
document.addEventListener("deviceready", bootstrapAngular, false);
} else {
console.log("URL: Running in browser");
bootstrapAngular();
}
If you run into problems with the http/https detection method, due to, perhaps, loading a Cordova app into the phone from the web, you could use the following method instead:
function bootstrapAngular() {
console.log("Bootstrapping AngularJS");
// This assumes your app is named "app" and is on the body tag: <body ng-app="app">
// Change the selector from "body" to whatever you need
var domElement = document.querySelector('body');
// Change the application name from "app" if needed
angular.bootstrap(domElement, ['app']);
}
// This method of user agent detection also works, though it means you might have to maintain this UA list
if (navigator.userAgent.match(/(iOS|iPhone|iPod|iPad|Android|BlackBerry)/)) {
console.log("UA: Running in Cordova/PhoneGap");
document.addEventListener("deviceready", bootstrapAngular, false);
} else {
console.log("UA: Running in browser");
bootstrapAngular();
}
Note that you still need the same bootstrapAngular function from the first example.
Why manually bootstrap AngularJS with Cordova/PhoneGap/Ionic?
Some people getting here might not know why you would want to do this in the first place. The issue is that you could have AngularJS code that relies on Cordova/PhoneGap/Ionic plugins, and those plugins won't be ready until after AngularJS has started because Cordova takes longer to get up and running on a device than the plain old Javascript code for AngularJS does.
So in those cases we have to wait until Cordova/PhoneGap/Ionic is ready before starting up (bootstrapping) AngularJS so that Angular will have everything it needs to run.
For example, say you are using the NG-Persist Angular module, which makes use of local storage for saving data on a browser, iOS Keychain plugin when running on iOS, and the cordova-plugin-file when running on Android. If your Angular app tries to load/save something right off the bat, NG-Persist's check on window.device.platform (from the device plugin) will fail because the mobile code hasn't completed startup yet, and you'll get nothing but a white page instead of your pretty app.
If you are using Ionic, this solution works for browsers and devices. Credit to romgar on this thread.
window.ionic.Platform.ready(function() {
angular.bootstrap(document, ['<your_main_app']);
});
Still need to remove ng-app from your DOM element.
This solution became more robust when I used:
angular.element(document).ready(function () {
var domElement = document.getElementById('appElement');
angular.bootstrap(domElement, ["angularAppName"]);
});
UPDATE
My suggestion was to put the above within the appropriate deviceready function, e.g.:
document.addEventListener("deviceready", function() {
angular.element(document).ready(function () {
var domElement = document.getElementById('appElement');
angular.bootstrap(domElement, ["angularAppName"]);
});
}, false);
On using the solution from TheHippo:
document.addEventListener("deviceready", function() {
// retrieve the DOM element that had the ng-app attribute
var domElement = document.getElementById(...) / document.querySelector(...);
angular.bootstrap(domElement, ["angularAppName"]);
}, false);
It doesn't work in the browser because "cordova.js" gets resolved by the Cordova or Phonegap building process and is not available in your localhost or emulated testing environment.
Thus the "deviceready" event is never fired. You can simply fire it manually in your browsers console.
var customDeviceReadyEvent = new Event('deviceready');
document.dispatchEvent(customDeviceReadyEvent);
Also make sure, that the bootstrap of angular gets triggered after setting all of you angular modules/controllers/factories/directives etc.
In most cases you probably don't need to block loading your angular app until after deviceready (mind that it can take several seconds for deviceready to fire if you have a lot of plugins).
Instead you can use something like this lib (https://github.com/arnesson/angular-cordova) which solves the deviceready issues for you by automatically buffering calls and then execute them after deviceready has been fired.

Resources