I'm developing an app using Worklight 5.0.6. The app is targeted at tablets (iOS, Android and Windows). The app works fine on iOS and Android, but I'm having trouble getting it to run properly on Windows 8. The app crashes when I click on a link. Here's part of the error message:
"HTML1701: Unable to add dynamic content ' <link/><table></table><a href='/a'>a</a><input type='checkbox'/>'. A script attempted to inject dynamic content or elements previously modified dynamically that might be unsafe. For example, using the innerHTML property to add script or malformed HTML will generate this exception. Use the toStaticHTML method to filter dynamic content or explicitly create elements and attributes with a method such as createElement. For more information, see http://go.microsoft.com/fwlink/?LinkID=247104."
The app is supposed to inject a html fragment when a link is clicked. I'm using the following the following functions to inject html into an element:
function loadPartial(path, elementId)
{
$.get(path, function (data) {
$(elementId).html(data).trigger("create");
$("#my-navbar > ul").removeClass("ui-grid-a");
if (!hideDuringFocus)
{
$("[data-role=header]").fixedtoolbar({ hideDuringFocus: "" });
$("[data-role=footer]").fixedtoolbar({ hideDuringFocus: "" });
}
});
}
function loadPartialWithFunction(path, elementId, aFunction)
{
$.get(path, function (data) {
$(elementId).html(data).trigger("create");
$("#my-navbar > ul").removeClass("ui-grid-a");
if (!hideDuringFocus)
{
$("[data-role=header]").fixedtoolbar({ hideDuringFocus: "" });
$("[data-role=footer]").fixedtoolbar({ hideDuringFocus: "" });
}
aFunction();
});
}
Is there a mistake I made in the code? Any help would be appreciated. Please let me know if more information or source code is needed.
The issue has been resolved, thanks. I have to wrap the code with MSApp.execUnsafeLocalFunction so it'll look this:
function loadPartialWithFunction(path, elementId, aFunction)
{
$.get(path, function (data) {
MSApp.execUnsafeLocalFunction(function(){
$(elementId).html(data).trigger("create");
$("#my-navbar > ul").removeClass("ui-grid-a");
if (!hideDuringFocus)
{
$("[data-role=header]").fixedtoolbar({ hideDuringFocus: "" });
$("[data-role=footer]").fixedtoolbar({ hideDuringFocus: "" });
}
aFunction();
});
});
}
This is an issue with jQuery on Win8 Metro. Metro apps have dynamic content restrictions, that need to be bypassed first. Here is a stack overflow question with lots of answers for this issue:
Using jQuery with Windows 8 Metro JavaScript App causes security error
Related
WKWebview and Phonegap Build: Is communication between index.js and WKWebView even possible?
I'm using Phonegap Build to generate my mobile device executables. I'm opening a webview and loading a page off our website. While using UIWebView I had no problem coding index.js on the mobile device to listen for a loadstop event and call executescript to execute javascript on the web page in the webview and return the results to index.js where I could do whatever I needed.
But UIWebView is dog-slow, so for iOS I've been trying to get WKWebView to work via the cordova-plugin-wkwebview-engine plug-in.
I can get the WKWebview to open my URL, and it is blazing fast compared to UIWebView, but after days of searching (every page containing 'WKWebView' and 'Phonegap' that Google knows of) and experimentation I have been unable to find any way to detect loadstop (or equivalent), nor have I found any way to execute a script in WKWebView from index.js.
I would probably be happy with ANY method to communicate between index.js and WKWebView. Is there a process similar to executescript after loadstop event, even if it is async? Is there some type of messaging capability?
I'd love to see some code examples for index.js.
I'm beginning to think that I'm going to have to break down and resort to learning native code in xcode to make this happen. I sure hope not because Phonegap Build has worked fine for me thus far.
Has anyone had any luck with this?
Here is the code that works under UIWebView. It works well enough under WKWebView to open the URL, but loadstop does not trigger and there is no execution of the script.
launchBrowserWindow: function (url) {
var ref;
try {
ref = window.open(url, '_self', 'location=no,toolbar=no');
} catch (e) {
console.log("McMApp catch window.open fail: " + url + " err: " + e.message);
}
try {
ref.addEventListener("loadstop", function () {
ref.executeScript(
{ code: 'window.location.search' },
function (value) {
var requestString = value[0];
console.log("McMApp loadstop request string: " + requestString);
});
});
} catch (e) {
console.log("McMApp FAIL ref.addeventlistener loadstop");
}
},
50 hard-boiled eggs to anyone that can help me get this working.
InAppBrowser is a fickle beast, so happy to help! For reference, I have an app now that uses InAppBrowser and WKWebView and both work using the following:
"LoadStop" not firing:
Self vs _blank:
I typically open the Browser via "_blank" instead of "self". Try that.
Newer versions of InAppBrowser should still be automatically aliased to 'window.open' but in the docs they mention this will go away soon. You can do that in the deviceready event like so:
window.open = cordova.InAppBrowser.open;
Or, and probably the safer option, just use "cordova.InAppBrowser.open".
Here's code I use. Try printing out or "alert"-ing the URLs that are coming through. They may not be what you expect, especially if there are multiple redirects.
var inAppBrowserRef = cordova.InAppBrowser.open("www.google.com", '_blank', 'location=no,toolbar=yes');
inAppBrowserRef.addEventListener('loadstop', function(event) {
console.log("loadstop: " + event.url);
alert("loadstop: " + event.url);
// run execute script code
}
});
Also, make sure any use of InAppBrowser is within/after the 'deviceready' event fires.
Execute Script Issue
I believe here the problem is that your code isn't firing. See here, wrap it into a function and call it immediately:
ref.executeScript(
{ code: 'var runCode = function() { window.location.search; } runCode();' },
function (value) {
var requestString = value[0];
console.log("McMApp loadstop request string: " + requestString);
});
I'm not totally sure, but according to MDN, shouldn't you be passing a parameter to the location search function too?
// Append "someData" as url parameter query
window.location.search = "someData";
Last, note that WKWebView does have lots of known issues currently. Always check first for known issues on GitHub or official Apache Cordova site, etc, because as you wrote, you can burn many hours getting nowhere. I'm currently using this fork of the WKWebView - this team is moving much faster than the "official" plugin fixing bugs so you might try that.
This is a weird issue, that is some what hard to generate and explore.
While building a web-app using Angular, my boss found that all the buttons on the app that are using ng-click directive are not working.
Now, this issue only happens on iphone 6 with IOS 8.3 and using the safari browser.
I can say that when was tested on iPhone5 (All versions), iPhone 6 (IOS 9), Safari for windows and all other browsers (Mobile and desktop), ng-click works like a charm.
The app is being build using Angular 1.4.3.
This is the code for the button, as you can see, nothing special about it:
<button class="btn calculate-button" ng-click="onCalculate()">Calculate</button>
And in the controller:
$scope.onCalculate = function () {
//Do something... And then:
$state.go('someplace');
};
I tried many changes that were suggested here, including ng-touch, ng-bind, building my own click directive as follows:
.directive('basicClick', function($parse, $rootScope) {
return {
compile: function(elem, attr) {
var fn = $parse(attr.basicClick);
return function(scope, elem) {
elem.on('click', function(e) {
fn(scope, {$event: e});
scope.$apply();
});
};
}
};
});
Couldn't find any proper solution for the problem.
Thanks.
IOS 8.4.1 Update has a known issue which stop ng-link and ng-click to work.
Using "touchstart click" can possibly solve this issue.
app.directive("ngMobileClick", [function () {
return function (scope, elem, attrs) {
elem.bind("touchstart click", function (e) {
e.preventDefault();
e.stopPropagation();
scope.$apply(attrs["ngMobileClick"]);
});
}
}])
HTML call: ng-mobile-click="onCalculate()"
I fixed it in the end.
The problem was in the //Do something... And then: part of the function.
At some point along the way, that function saves some data to the browser local storage.
My boss was using private browsing on safari, and apparently when using private browsing on safari, the browser wont save and data on the local storage and it throws an exception and kills the code.
Well, thanks any way.
I have the following .js file for my project. This is running in a regular browser, using jquery 1.9.x and jquerymobile 1.3.1. The init function below appears to be running when the page loads and the UI is not updated. Though... I can copy the function into the console and run it, and the UI updates as it is supposed to, so this in not a case of incorrect file paths, or incorrect ids for the UI elements, but I suspect timing. I am also NOT using cordova or phone gap in this instance.
So, my question is, why is the UI not updating when the $(document).bind('pageinit', ...) function is called? If I put a breakpoint in the init method, it is getting called when the page loads. Any suggestions on using a different event or approach?
var simulator = simulator || {};
(function (feedback, $, undefined) { 'use-strict';
feedback.init = function () {
$.get('feedback-config.xml', function (data) {
$('#feedback-to').val($(data).find('email').text());
$('#feedback-subject').val($(data).find('emailSubject').text());
$('#feedback-display').html($(data).find('message').text());
$('#feedback-form').attr('action', $(data).find('serverurl').text()).ajaxForm({success: function () {
alert("Thank you for your feedback!");
}, error: function () {
alert("We're having difficulties sending your feedback, sorry for the inconvenience.");
}});
});
};
}(simulator.feedback = simulator.feedback || {}, jQuery));
$(document).bind('pageinit', function () { 'use strict';
simulator.feedback.init;
});
Thanks in advance.
Found it, simple mistake... In the 'pageinit' function I am calling simulator.feedback.init; instead of simulator.feedback.init(); Not sure why JSLint didn't pick that up initially, but it pointed it out when I tried again later. Thanks.
I've been looking for ways to open a html local levels, Local I mean that the html is inside the www folder of the application of phonegap, with inappbrowser.
var about = window.open("About.html", "_blank", "location=yes");
This is the line of code with which I intend to do this, but apparently does not work, if someone could help me I would be very grateful.
Are you using Phonegap 3.0.0? I think this is a bug with this Phonegap version.
I have been using this as a workaround (opening an inappbrowser instance):
// Image zoom
$('#container').on('tap', '#content.cmscontent img', function() {
var browser = window.open((navigator.userAgent.indexOf('Android') != -1 ? 'file:///android_asset/www/' : '') + encodeURI($(this).attr('src')), '_blank', 'location=no,toolbar=yes,enableViewportScale=yes,transitionstyle=crossdissolve');
});
See I added (navigator.userAgent.indexOf('Android') != -1 ? 'file:///android_asset/www/' : '') as a prefix before the url. Now it detects when you're app is on Android and adds the local URL in front of it.
Thanks for your answers, and achieves it work apparently the problem is that there was cleaning the project and for this reason not added the www about.html
But now I have another problem, as I will have already seen pretending to show a about of the application, for which show the ios version and device name. for this I am using the properties of the object name and version device.That for some reason unknown to me but that are not available in the index file, that I decided to pass these attributes to html url about, for example:
var about = window.open("About.html?"+device.name+"&"+device.version, "_blank", "location=yes");
and about.html handles these variables with:
var cadGET = location.search.substr(1,location.search.length);
but does not show the html inappbrowser and location bar only shows loading ...
know if the inappbrowser supports pass url parameters?
The code that you have written is correct. it is opening page in inappbrowser.
Now the thing is you have to make sure that you call it after device is ready.
Also check you are using 2.x version of cordova framework. and still if you getting issue with the inappbrowser please provide some more information.
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicity call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
},
// Update DOM on a Received Event
receivedEvent: function(id) {
var about = window.open("about.html", "_blank", "location=yes");
console.log('Received Event: ' + id);
}
};
I have a requirement for a popup to appear with a custom heading (having it appear from index.html on an app just looks tacky).
I tried the suggestion at the end of the following link:
Custom JavaScript alerts in iOS using PhoneGap HTML
So I added the code below to my index.html in the script section:
function showMessage(message, callback, title, buttonName){
title = title || "default title";
buttonName = buttonName || 'OK';
if(navigator.notification && navigator.notification.alert){
navigator.notification.alert(
message, // message
callback, // callback
title, // title
buttonName // buttonName
);
}else{
alert(message);
callback();
}
}
UPDATE
I have the following code for the alert;
if ((inputNumber>maxAllowed))
{
showMessage("The input is too high.",null,"Warning","Warning");
}
After compiling the app, this is not working.
The following is in index.html:
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
// Now safe to use the PhoneGap API
}
<function shown above is here>
Any idea why this is still not working? Showing from index.html
Thank you.
Kind Regards,
Gary Shergill
This error tells you that function navigator.notification don't exist.
Usually this is because:
Phonegap/Cordova is not initialized inside a HEAD
Function is not initialized inside a deviceready event. Basically function can't be called before cordova.js is fully initialized.
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
// Now safe to use the PhoneGap API
}
Here is a function I use while testing Phonegap applications on my PC. I remove it when deploying app on mobile device. It's for confirm function, but you can adjust it for alerting and so on.
// TODO: remove on deploy
navigator.notification = {
confirm: function (message, successCallback) {
successCallback(1);
}
};
You are testing in a browser so navigator.notification is undefined. Also It seems that you added the function showMessage but you are not using it. Try with:
showMessage("The value is too high!", null,"Warning", "Warning");
From phone, notice that the callback is not a string. So in your function, you pass it a string and that is causing it a problem.
http://docs.phonegap.com/en/1.0.0/phonegap_notification_notification.md.html
navigator.notification.alert(
'You are the winner!', // message
alertDismissed, // callback
'Game Over', // title
'Done' // buttonName
);
I see this is the case because I am trying to do this also. So unfortunately you cannot override the callback, and you need to "hard Code" it.
I have add the plugin using CLI like :
$ cordova plugin add cordova-plugin-dialogs
and its working fine for me.