I want to implement print functionality in Android app, I'm using AngularJS. I have tried the below code, but it works only on browser, it doesn't work on Android.
AngularJS:
$scope.print = function (divName) {
var w = window.open();
w.document.write($('#' + divName).html());
w.print();
w.close();
}
Html:
<img ng-click="print('print');" class="card-img-top image-responsive" src="./plugins/images/print.png" alt="Card image cap">
<div id="print" style="display:none;">
<style>
#page {
size: auto;
margin: 7mm;
}
#media all {
.page-break {
display: none;
}
}
#media print {
.page-break {
display: block;
page-break-before: always;
}
}
</style>
<div class="row">
</div>
</div>
Update:
I have tried the solution provided by #VicJordan, But it gives the below error.
ReferenceError: cordova is not defined at ChildScope.$scope.print
(MyJs.js:37) at fn (eval at compile (angular.js:15500),
:4:149) at callback (angular.js:27285) at ChildScope.$eval
(angular.js:18372) at ChildScope.$apply (angular.js:18472) at
HTMLImageElement. (angular.js:27290) at
HTMLImageElement.dispatch (jquery.min.js:3) at
HTMLImageElement.r.handle (jquery.min.js:3)
Package.json
{
"name": "helloworld",
"displayName": "HelloCordova",
"version": "1.0.0",
"description": "A sample Apache Cordova application that responds to the deviceready event.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Apache Cordova Team",
"license": "Apache-2.0",
"dependencies": {
"cordova-android": "^7.0.0",
"cordova-browser": "^5.0.3",
"cordova-plugin-device-orientation": "^1.0.7",
"cordova-plugin-printer": "^0.7.3",
"cordova-plugin-whitelist": "^1.3.3"
},
"cordova": {
"plugins": {
"cordova-plugin-whitelist": {},
"cordova-plugin-device-orientation": {},
"cordova-plugin-printer": {}
},
"platforms": [
"browser",
"android"
]
}
}
Update2
MyJS.js
app.controller('ReciepieController', ['$scope', '$http', '$rootScope', '$state', '$window', '$uibModal', function ($scope, $http, $rootScope, $state, $window, $uibModal) {
$("#header").show();
$rootScope.back = true;
$rootScope.enableback = true;
$scope.toggleText = "See More...";
$scope.toggle = 0;
$scope.print = function (divName) {
console.log('2222222222222222222');
//Enter the page location.
var page = document.getElementById(divName).innerHTML;
cordova.plugins.printer.print(page, 'Document.html', function () {
alert('printing finished or canceled')
});
}
$scope.change = function () {
if ($scope.toggle == 0) {
$scope.toggleText = "See Less...";
$scope.toggle = 1;
}
else if ($scope.toggle == 1) {
$scope.toggleText = "See More...";
$scope.toggle = 0;
}
}
var recipe = null;
var categorylist = [];
$scope.GetRecipe = function (paginate) {
if (paginate == "next") {
if ($rootScope.RecipeIndex < categorylist.length - 1) {
$rootScope.RecipeIndex = $rootScope.RecipeIndex + 1;
$scope.IsNext = true;
$scope.IsPrevious = true;
if ($rootScope.RecipeIndex == categorylist.length - 1) { $scope.IsNext = false; }
}
}
else if (paginate == "previous") {
if ($rootScope.RecipeIndex < $rootScope.RecipeList.length) {
$rootScope.RecipeIndex = $rootScope.RecipeIndex - 1;
$scope.IsNext = true;
$scope.IsPrevious = true;
}
}
if ($rootScope.RecipeIndex == -1) {
$rootScope.RecipeIndex = 0;
}
if ($rootScope.RecipeIndex == 0 || $rootScope.RecipeIndex == -1) { $scope.IsPrevious = false; }
recipe = categorylist[$rootScope.RecipeIndex];
$scope.Ingredient = recipe.recipeIngredients.split('\n');
$scope.Method = recipe.recipeMethod.split('\n');
$scope.Image = recipe.imageName;
$scope.Name = recipe.recipeTitle;
$scope.Description = recipe.recipeDescription;
$scope.Prep = recipe.preparationTime;
$scope.Cook = recipe.cookingTime;
$scope.Serves = recipe.servings;
$scope.QrCode = recipe.QrCode;
$rootScope.IsBack = false;
$rootScope.IsTitle = false;
}
$scope.share = function () {
var modalInstance = $uibModal.open({
animation: true,
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
templateUrl: 'QrCode.html',
controller: 'ReciepieController',
controllerAs: '$ctrl',
size: 'sm',
backdrop: 'static', /* this prevent user interaction with the background */
keyboard: false
});
}
function NextRecipe() {
alert();
}
}]);
I also had the same issue.
Try to do it using cordova-plugin-printer plugin. It will solve your problem. From your code it looks you want to print div by id. Below are various usage of above plugin:
Print the whole HTML page:
var page = location.href;
cordova.plugins.printer.print(page, 'Document.html');
Print the content from one part of the page:
var page = document.getElementById('legal-notice');
cordova.plugins.printer.print(page, 'Document.html');
Print some custom content:
var page = '<h1>Hello Document</h1>';
cordova.plugins.printer.print(page, 'Document.html');
For more options, check out the documentation : https://github.com/katzer/cordova-plugin-printer#usage
It works for me in javascript
var dowloadurl = "/.../sample.pdf" // Here your file location
window.cordova.plugins.FileOpener.openFile(
dowloadurl,
onSuccessFileOpen,
onErrorFileOpen
);
var onSuccessFileOpen = function (data) {
alert('onSuccessFileOpen');
};
function onErrorFileOpen(err) {
alert('message: ' + err);
}
Related
I have developed app via HTML5, JS, CSS, PHP and MySQL by help of phonegap builder. I have used admob plugin successfully in my app, but when I add keystore to my app on phonegap builder, there were no ads in my certificated app. Below is my config.xml plugin code
<plugin name="cordova-plugin-admobpro" spec ="~2.35.3" source="npm" >
<variable name="PLAY_SERVICES_VERSION" value="16.0.0" />
</plugin>
Below is JS codes. Everything is ok when I open apk without keystore.
var admobid = {};
if( /(android)/i.test(navigator.userAgent) ) {
admobid = { // for Android
banner: 'ca-app-pub-3620418953743637/6097985822',
interstitial: 'ca-app-pub-3620418953743637/2453242527',
rewardvideo: 'ca-app-pub-3620418953743637/6437036798'
};
}
function initApp() {
var oyunSonu = localStorage.getItem("oyunSonu");
$('#reklamKont').fadeIn();
if(oyunSonu != "1"){
$('#reklamKont').fadeOut();
}
AdMob.prepareInterstitial({
adId: admobid.interstitial,
autoShow: false
});
AdMob.prepareRewardVideoAd({
adId:admobid.rewardvideo,
autoShow: false,
});
}
document.addEventListener('deviceready', initApp, false);
//////////////////////////////////////////////////////////////////
function odulReklamFNC(){
if(odulTusAktif == 1)
{
AdMob.showRewardVideoAd();
odulTusAktif = 0;
}
}
var odulTusAktif;
document.addEventListener('onAdLoaded',function(data){
if(data.adType == 'interstitial'){
var oyunSonu = localStorage.getItem("oyunSonu");
if(oyunSonu == "1"){
localStorage.setItem('oyunSonu', '0');
$('#reklamKont').fadeOut();
AdMob.showInterstitial();
}
}
if(data.adType == 'rewardvideo'){
odulTusAktif = 1;
if(odulBTNGoster == 1){
$('#odulBTN').fadeIn();
}
}
//
});
document.addEventListener('onAdPresent', function(data){
if(data.adType == 'rewardvideo'){
var uyeCookie = localStorage.getItem("uyeID");
$.ajax({
type: "GET",
url: websitePHP + "odulVer.php",
data: {
id : uyeCookie
},
beforeSend: function(){
$("#phpKont").fadeIn();
},
success: function(gelenVeri){
$("#phpKont").fadeOut();
$('#odulBilgi').html(gelenVeri);
$("#gunlukPrim").fadeOut();
$("#odulBildiri").fadeIn();
document.getElementById('satinAlSES').currentTime = 0;
document.getElementById('satinAlSES').play();
odulBTNGoster = 0;
girisAnaFNC();
top10FNC();
}
})
//$('#rumuz').html(data.rewardType);
//$('#elmas').html(data.rewardAmount);
}
});
document.addEventListener('onAdFailLoaded',function(data){
if(data.adType == 'interstitial'){
localStorage.setItem('oyunSonu', '0');
$('#reklamKont').fadeOut();
}
if(data.adType == 'rewardvideo'){
}
});
document.addEventListener('onAdDismiss',function(data){
if(data.adType == 'rewardvideo'){
if(odulBTNGoster != 0){
window.open('baslangic.html','_self');
}
}
});
How can I fixed this problem. I have also worried about that it will happen when I upload my app to google play services.
Thanks.
I Making a chess app with react native, i sending & receiving my request with websocket,
when i run my app in ios every thing is ok,but when i run my app in android the web socket not open and return " Expected HTTP 101 response but was '403 Forbidden' ".
my create game code :
createGame() {
const { playConfig } = this.props;
fetch('https://en.lichess.org/setup/ai', {
method: 'POST',
headers: {
Accept: 'application/vnd.lichess.v2+json',
'Content-Type': 'application/json',
},
body: playConfig,
})
.then(res => res.json())
.then(this.onGameCreated);
}
onGameCreated = res => {
const { game } = this.state;
const socketUrl = res.url.socket;
const clientId = Math.random().toString(36).substring(2);
clearInterval(this.interval);
this.wsReady = false;
let url = `wss://socket.lichess.org${socketUrl}?sri=${clientId}&mobile=1`;
this.ws = new WebSocket(
url,
);
this.ws.onmessage = e => {
// a message was received
console.log(`received: ${e.data}`);
const data = JSON.parse(e.data);
let moveData;
let victor;
if (data.t === 'move' && data.v > game.history().length) {
moveData = data.d;
} else if (data.t === 'end') {
victor = data.d;
} else if (data.t === 'b') {
// b for batch
const first = data.d[0];
if (first) {
if (first.d.status && first.d.status.name === 'mate') {
moveData = first.d;
}
if (first.t === 'end') {
victor = first.d;
}
if (first.d.winner) {
victor = first.d.winner;
}
}
}
if (victor) {
dongSound.play();
this.setState({
victor,
});
this.ws = null;
} else if (moveData) {
const { uci, clock } = moveData;
const castle = moveData.castle;
let from = uci.substring(0, 2);
let to = uci.substring(2, 4);
if (castle && castle.king) {
from = castle.king[0];
to = castle.king[1];
}
this.board.movePiece(to, from);
if (clock) {
this.latestClock = clock;
}
}
};
this.ws.onerror = e => {
// an error occurred
console.log(e.message);
};
this.ws.onopen = () => {
this.wsReady = true;
dongSound.play();
this.setState({
initialized: true,
userColor: res.player.color === 'white' ? 'w' : 'b',
});
console.log('ws open');
// ping every second
this.interval = setInterval(
() => {
this.sendMessage({
t: 'p',
v: game.history().length,
});
},
1000,
);
};
};
any one has idea?
thank you in advance
Looks like you don't have permission to open a socket on this webserver.
I don't think the problem is in your Java code but the webserver configuration.
I am developing an ionic app. I am using cordova's FileTransfer plugin to download pdf file. I am able to download the file to my internal memory,but not able to display single progress bar for downloaidng.
What is the best way of displaying progress for downloading.
Controller
var url = 'http://someurl.com/api/pdf_download/' + id;
// Android
var targetPath = 'file:///storage/sdcard0/' + id + '.pdf';
var trustHosts = true;
var options = {};
$cordovaFileTransfer.download(url, targetPath, options, trustHosts)
.then(function(result) {
console.log(result);
}, function() {
var alertPopup = $ionicPopup.alert({
title: 'No internet access',
buttons: [{
text: 'OK',
type: 'button-assertive'
}]
});
alertPopup.then(function() {});
}, function(progress) {
$timeout(function() {
$scope.downloadProgress = (progress.loaded / progress.total) * 100;
})
console.log('progress--->', $scope.downloadProgress);
});
I have used cordovaToast plugin for this feature.Here is the example for showing pdf download progress
html
<ion-view >
<div class="bar bar-subheader bar-positive" style="padding:0px;height: 8px;" >
<progress id="progressbar" max="100" value="{{ downloadProgress }}" class="progress"> </progress>
</div>
<ion-content>
</ion-content>
</ion-view>
css
.progress {
margin: 0 px;
height: 8 px;
background - color: #F1292B!important;
border - radius: 2 px;
box - shadow: 0 2 px 5 px rgba(0, 0, 0, 0.25) inset;
}
js
if (window.cordova) {
var url = '{{base_url}}/pdf_download/' + id;
// Android
var targetPath = 'file:///storage/sdcard0/' + 'fpl_' + id + '.pdf';
var trustHosts = true;
var options = {};
$cordovaFileTransfer.download(url, targetPath, options, trustHosts)
.then(function(result) {
$cordovaToast
.show('File downloaded successfully..', 'short', 'center')
.then(function() {
// success
}, function() {
// error
});
console.log(result);
}, function() {
var alertPopup = $ionicPopup.alert({
title: 'No internet access',
buttons: [{
text: 'OK',
type: 'button-assertive'
}]
});
alertPopup.then(function() {});
}, function(progress) {
var dnldpgs = progress.loaded.toString().substring(0, 2);
$scope.downloadProgress = parseInt(dnldpgs);
});
}
As benka already answered to my question, you should use the <progress> html element.
The full answer can be found over here -> https://stackoverflow.com/a/25553044/3671726
Cordova error message in logcat:
D/chromium(24894): Unknown chromium error: 0
D/CordovaLog(24894): file:///android_asset/www/index.html: Line 2 : Uncaught TypeError: object is not a function
E/Web Console(24894): Uncaught TypeError: object is not a function at file:///android_asset/www/index.html:2
I did not find an android_asset folder. My best bet is myapp-debug.apk/assets/www/index.html, but where should there be an issue in line 2?
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="apple-mobile-web-app-capable" content="yes" />
<link rel="apple-touch-icon" href="resources/icons/myApp-ico.png">
<title>myApp</title>
<script type="text/javascript" src="cordova.js"></script>
<style type="text/css">
/**
* Example of an initial loading indicator.
* It is recommended to keep this as minimal as possible to provide instant feedback
* while other resources are still being loaded for the first time
*/
html, body {
height: 100%;
background-color: #1985D0
}
#appLoadingIndicator {
position: absolute;
top: 50%;
margin-top: -15px;
text-align: center;
width: 100%;
height: 30px;
-webkit-animation-name: appLoadingIndicator;
-webkit-animation-duration: 0.5s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: linear;
}
#appLoadingIndicator > * {
background-color: #FFFFFF;
display: inline-block;
height: 30px;
-webkit-border-radius: 15px;
margin: 0 5px;
width: 30px;
opacity: 0.8;
}
#-webkit-keyframes appLoadingIndicator{
0% {
opacity: 0.8
}
50% {
opacity: 0
}
100% {
opacity: 0.8
}
}
</style>
<!-- The line below must be kept intact for Sencha Command to build your application -->
<script type="text/javascript">
/**
* Sencha Blink - Testing
* #author Jacky Nguyen <jacky#sencha.com>
*/
(function(global) {
var head = global.document.head,
Ext = global.Ext;
if (typeof Ext == 'undefined') {
global.Ext = Ext = {};
}
function write(content) {
document.write(content);
}
function addMeta(name, content) {
var meta = document.createElement('meta');
meta.setAttribute('name', name);
meta.setAttribute('content', content);
head.appendChild(meta);
}
Ext.blink = function(options) {
var scripts = options.js || [],
styleSheets = options.css || [],
i, ln, path, platform, theme;
if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
var msViewportStyle = document.createElement("style");
msViewportStyle.appendChild(
document.createTextNode(
"#media screen and (orientation: portrait) {" +
"#-ms-viewport {width: 320px !important;}" +
"}" +
"#media screen and (orientation: landscape) {" +
"#-ms-viewport {width: 560px !important;}" +
"}"
)
);
document.getElementsByTagName("head")[0].appendChild(msViewportStyle);
}
addMeta('viewport', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no');
addMeta('apple-mobile-web-app-capable', 'yes');
addMeta('apple-touch-fullscreen', 'yes');
Ext.microloaded = true;
var filterPlatform = window.Ext.filterPlatform = function(platform) {
var profileMatch = false,
ua = navigator.userAgent,
j, jln, exclude;
platform = [].concat(platform);
function isPhone(ua) {
var isMobile = /Mobile(\/|\s)/.test(ua);
// Either:
// - iOS but not iPad
// - Android 2
// - Android with "Mobile" in the UA
return /(iPhone|iPod)/.test(ua) ||
(!/(Silk)/.test(ua) && (/(Android)/.test(ua) && (/(Android 2)/.test(ua) || isMobile))) ||
(/(BlackBerry|BB)/.test(ua) && isMobile) ||
/(Windows Phone)/.test(ua);
}
function isTablet(ua) {
return !isPhone(ua) && (/iPad/.test(ua) || /Android|Silk/.test(ua) || /(RIM Tablet OS)/.test(ua) ||
(/MSIE 10/.test(ua) && /; Touch/.test(ua)));
}
// Check if the ?platform parameter is set in the URL
var paramsString = window.location.search.substr(1),
paramsArray = paramsString.split("&"),
params = {},
testPlatform, i;
for (i = 0; i < paramsArray.length; i++) {
var tmpArray = paramsArray[i].split("=");
params[tmpArray[0]] = tmpArray[1];
}
testPlatform = params.platform;
if (testPlatform) {
return platform.indexOf(testPlatform) != -1;
}
for (j = 0, jln = platform.length; j < jln; j++) {
switch (platform[j]) {
case 'phone':
profileMatch = isPhone(ua);
break;
case 'tablet':
profileMatch = isTablet(ua);
break;
case 'desktop':
profileMatch = !isPhone(ua) && !isTablet(ua);
break;
case 'ios':
profileMatch = /(iPad|iPhone|iPod)/.test(ua);
break;
case 'android':
profileMatch = /(Android|Silk)/.test(ua);
break;
case 'blackberry':
profileMatch = /(BlackBerry|BB)/.test(ua);
break;
case 'safari':
profileMatch = /Safari/.test(ua) && !(/(BlackBerry|BB)/.test(ua));
break;
case 'chrome':
profileMatch = /Chrome/.test(ua);
break;
case 'ie10':
profileMatch = /MSIE 10/.test(ua);
break;
case 'windows':
profileMatch = /MSIE 10/.test(ua) || /Trident/.test(ua);
break;
case 'tizen':
profileMatch = /Tizen/.test(ua);
break;
case 'firefox':
profileMatch = /Firefox/.test(ua);
}
if (profileMatch) {
return true;
}
}
return false;
};
for (i = 0,ln = styleSheets.length; i < ln; i++) {
path = styleSheets[i];
if (typeof path != 'string') {
platform = path.platform;
exclude = path.exclude;
theme = path.theme;
path = path.path;
}
if (platform) {
if (!filterPlatform(platform) || filterPlatform(exclude)) {
continue;
}
Ext.theme = {
name: theme || 'Default'
};
}
write('<link rel="stylesheet" href="'+path+'">');
}
for (i = 0,ln = scripts.length; i < ln; i++) {
path = scripts[i];
if (typeof path != 'string') {
platform = path.platform;
exclude = path.exclude;
path = path.path;
}
if (platform) {
if (!filterPlatform(platform) || filterPlatform(exclude)) {
continue;
}
}
write('<script src="'+path+'"></'+'script>');
}
}
})(this);
if(document.URL.indexOf('file://')==0) {
oldBlink = Ext.blink;
Ext.blink = function(options) {
document.addEventListener("deviceready", function() {
oldBlink(options);
}, false);
}
}
</script>
</head>
<body>
<div id="appLoadingIndicator">
<div></div>
<div></div>
<div></div>
</div>
</body>
</html>
Could it be that "Line 2" does refer to something different entirely? If yes, what does it refer to?
Prettify this ugly line of code and try again to get a useful error message.
<script type="text/javascript">
(function(e) {
var c = e.document.head,
b = e.Ext;
if (typeof b == "undefined") {
e.Ext = b = {}
}
function d(f) {
document.write(f)
}
function a(f, g) {
var h = document.createElement("meta");
h.setAttribute("name", f);
h.setAttribute("content", g);
c.appendChild(h)
}
b.blink = function(p) {
var j = p.js || [],
n = p.css || [],
l, m, o, g, k;
if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
var h = document.createElement("style");
h.appendChild(document.createTextNode("#media screen and (orientation: portrait) {#-ms-viewport {width: 320px !important;}}#media screen and (orientation: landscape) {#-ms-viewport {width: 560px !important;}}"));
document.getElementsByTagName("head")[0].appendChild(h)
}
a("viewport", "width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no");
a("apple-mobile-web-app-capable", "yes");
a("apple-touch-fullscreen", "yes");
b.microloaded = true;
var f = window.Ext.filterPlatform = function(u) {
var D = false,
r = navigator.userAgent,
w, A, s;
u = [].concat(u);
function z(E) {
var i = /Mobile(\/|\s)/.test(E);
return /(iPhone|iPod)/.test(E) || (!/(Silk)/.test(E) && (/(Android)/.test(E) && (/(Android 2)/.test(E) || i))) || (/(BlackBerry|BB)/.test(E) && i) || /(Windows Phone)/.test(E)
}
function y(i) {
return !z(i) && (/iPad/.test(i) || /Android|Silk/.test(i) || /(RIM Tablet OS)/.test(i) || (/MSIE 10/.test(i) && /; Touch/.test(i)))
}
var q = window.location.search.substr(1),
t = q.split("&"),
v = {},
B, x;
for (x = 0; x < t.length; x++) {
var C = t[x].split("=");
v[C[0]] = C[1]
}
B = v.platform;
if (B) {
return u.indexOf(B) != -1
}
for (w = 0, A = u.length; w < A; w++) {
switch (u[w]) {
case "phone":
D = z(r);
break;
case "tablet":
D = y(r);
break;
case "desktop":
D = !z(r) && !y(r);
break;
case "ios":
D = /(iPad|iPhone|iPod)/.test(r);
break;
case "android":
D = /(Android|Silk)/.test(r);
break;
case "blackberry":
D = /(BlackBerry|BB)/.test(r);
break;
case "safari":
D = /Safari/.test(r) && !(/(BlackBerry|BB)/.test(r));
break;
case "chrome":
D = /Chrome/.test(r);
break;
case "ie10":
D = /MSIE 10/.test(r);
break;
case "windows":
D = /MSIE 10/.test(r) || /Trident/.test(r);
break;
case "tizen":
D = /Tizen/.test(r);
break;
case "firefox":
D = /Firefox/.test(r)
}
if (D) {
return true
}
}
return false
};
for (l = 0, m = n.length; l < m; l++) {
o = n[l];
if (typeof o != "string") {
g = o.platform;
exclude = o.exclude;
k = o.theme;
o = o.path
}
if (g) {
if (!f(g) || f(exclude)) {
continue
}
b.theme = {
name: k || "Default"
}
}
d('<link rel="stylesheet" href="' + o + '">')
}
for (l = 0, m = j.length; l < m; l++) {
o = j[l];
if (typeof o != "string") {
g = o.platform;
exclude = o.exclude;
o = o.path
}
if (g) {
if (!f(g) || f(exclude)) {
continue
}
}
d('<script src="' + o + '"><\/script>')
}
}
})(this);
if (document.URL.indexOf("file://") == 0) {
oldBlink = Ext.blink;
Ext.blink = function(a) {
document.addEventListener("deviceready", function() {
oldBlink(a)
}, false)
}
}
Ext.blink({
id: "8b19cfab-9dd1-44d0-892e-28f50a42aecd",
js: [{
path: "lzstring.js",
update: "full",
version: "1.0.0"
}, {
path: "microloader-enhancement.js",
update: "full",
version: "1.0.0"
}, {
path: "app.js",
update: "full",
version: "1.1.11"
}],
css: [{
path: "resources/css/app.css",
update: "full",
theme: "Default"
}, {
path: "resources/css/sch.css",
update: "full"
}, {
path: "resources/css/myApp.css",
update: "full"
}]
});
</script>
The webviewis just trying to make you understand that you're trying to call functions from the object Ext (like Ext.blink) but did not include any js library that would include that object.
You need to copy extjs somewhere in jour www folder and then add the missing <script type="text/javascript" src="somewhere/extjs.js"></script> line.
Next time, put your js in a separate file, you should get more accurate error messages.
I found the error to be caused by a script that is added to index.html by code from another javascript, using Ext.Loader.injectScriptElement, which roughly translates to the following JS:
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
For some reason yet to be determined, the "object is not a function" error inside the referenced script is thrown inside Cordova WebView, but not inside Chrome. Once I found the line where it is thrown and corrected it, no more error is thrown.
For some other reason yet to be determined, it is thrown as an "error in index.html:2", whereas the error could also have read "error in locale-de.js:72".
Don't ask how I found it, this tiny little problem just required a whole week of debugging...
I am trying to implement Videogular in my AngularJS App. The out of the box example works nicely, no issue. But I am unable to ask the player manually to play a different file, instead of the running audio.
Here is my HTML.
<div ng-controller="HomeCtrl as controller" class="videogular-container" ng-model="sharedProperty">
sharedProperty.data = {{sharedProperty.data}}
<button ng-click="SetValue('http://example.com/myfile.mp3')" type="button" class="btn btn-default">Change Audio</button>
<videogular vg-theme="controller.config.theme.url" class="videogular-container audio">
<vg-media vg-src="controller.config.sources"></vg-media>
<vg-controls>
<vg-play-pause-button></vg-play-pause-button>
<vg-time-display>{{ currentTime | date:'mm:ss' }}</vg-time-display>
<vg-scrub-bar>
<vg-scrub-bar-current-time></vg-scrub-bar-current-time>
</vg-scrub-bar>
<vg-time-display>{{ timeLeft | date:'mm:ss' }}</vg-time-display>
<vg-volume>
<vg-mute-button></vg-mute-button>
</vg-volume>
</vg-controls>
</videogular>
</div>
And this is the controller code:
app.controller('HomeCtrl', ["$sce","$scope", "$window", "sharedProperties",
function($sce, $scope, $window, sharedProperties) {
$scope.sharedProperty = sharedProperties.getProperty();
$scope.SetValue = function (msg)
{
$window.alert( $scope.sharedProperty.data );
$scope.setProperty = sharedProperties.setProperty;
$scope.setProperty(msg);
$window.alert( $scope.sharedProperty.data );
}
$window.alert( $scope.sharedProperty.data );
this.config = {
sources: [{
src: $sce.trustAsResourceUrl( $scope.sharedProperty.data ),
type: "audio/mpeg"
}, {
src: $sce.trustAsResourceUrl("http://static.videogular.com/assets/audios/videogular.ogg"),
type: "audio/ogg"
}],
theme: {
url: "http://www.videogular.com/styles/themes/default/latest/videogular.css"
}
};
}
]
);
The Service code is given here:
app.service('sharedProperties', function () {
var property = {
data: "http://example.com/firstaudio.mp3"
};
return {
getProperty:function () {
return property;
},
setProperty:function (value) {
property.data = value;
}
};
});
When I click on Set Value button, I am able to change the value of sharedProperty.data successfully but I don't know how to ask the player to stop the current audio and play the new file instead.
I'm the creator of Videogular.
If you have set a binding with:
<vg-media vg-src="controller.config.sources"></vg-media>
You only need to change your controller.config.sources and that's all:
app.controller('HomeCtrl', ["$sce","$scope", "$window", "sharedProperties",
function($sce, $scope, $window, sharedProperties) {
$scope.sharedProperty = sharedProperties.getProperty();
$scope.SetValue = function (msg)
{
$window.alert( $scope.sharedProperty.data );
$scope.setProperty = sharedProperties.setProperty;
$scope.setProperty(msg);
$window.alert( $scope.sharedProperty.data );
}
$scope.changeSource = function (source) {
// source should be an array of objects with src and type
this.config.sources = source;
}
$window.alert( $scope.sharedProperty.data );
this.config = {
sources: [{
src: $sce.trustAsResourceUrl( $scope.sharedProperty.data ),
type: "audio/mpeg"
}, {
src: $sce.trustAsResourceUrl("http://static.videogular.com/assets/audios/videogular.ogg"),
type: "audio/ogg"
}],
theme: {
url: "http://www.videogular.com/styles/themes/default/latest/videogular.css"
}
};
}
]);
You have an example here:
https://github.com/2fdevs/videogular/blob/master/app/scripts/controllers/main.js#L102