Knockout JS data-binding on Virtual Element inside template is not working on Windows 8.1 Cordova Application - windows

I am using following code for virtual DOM element data binding in my Cordova Application. This code is working fine for IE 11, Android and iOS but not working on Windows 8.1 Cordova App
If I use regular DOM element binding it's working fine for Windows as well. But my requirement is to use Virtual DOM Element Binding.
Any kind of help will be appreciated.
<html>
<head>
<meta charset="utf-8" />
<title>Prooduct</title>
<link href="css/index.css" rel="stylesheet" />
<script src="libs/knockout/knockout.js"></script>
<script type="text/html" id="product-template">
<ul>
<!-- ko foreach: productArray-->
<li><span data-bind="text: productName"></span><br /></li>
<!-- /ko -->
</ul>
</script>
</head>
<body>
<h4>Product List</h4>
<div data-bind="template: { name: 'product-template'}"></div>
<script type="text/javascript">
function ProductViewModel() {
this.productArray = ko.observableArray([
{ productName: 'Milk' },
{ productName: 'Oil' },
{ productName: 'Butter' }]);
}
ko.applyBindings(new ProductViewModel());
</script>
</body>
</html>

I tested it successful with cordova CLI 4.3.1/Visual Studio 2015/Windows 10 and Windows 8.1(remote debugging):
index.js:
// and then run "window.location.reload()" in the JavaScript Console.
$(document).ready(function () {
document.addEventListener( 'deviceready', onDeviceReady.bind( this ), false );
function onDeviceReady() {
// Handle the Cordova pause and resume events
document.addEventListener( 'pause', onPause.bind( this ), false );
document.addEventListener( 'resume', onResume.bind( this ), false );
// TODO: Cordova has been loaded. Perform any initialization that requires Cordova here.
};
function onPause() {
// TODO: This application has been suspended. Save application state here.
};
function onResume() {
// TODO: This application has been reactivated. Restore application state here.
};
function AppViewModel() {
var self = this;
self.productArray = ko.observableArray([
{ productName: 'Milk' },
{ productName: 'Oil' },
{ productName: 'Butter' }]);
self.removeProduct = function () {
self.productArray.remove(this);
}
};
var vm = new AppViewModel();
ko.applyBindings(vm);
});
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>testios</title>
<!-- testios references -->
<link href="css/index.css" rel="stylesheet" />
</head>
<body>
<h2>List of product</h2>
<hr />
<ul>
<!-- ko foreach: productArray -->
<li>
<span data-bind="text: productName"></span> Remove
</li>
<!-- /ko -->
</ul>
<!-- Cordova reference, this is added to your app when it's built. -->
<script src="scripts/jquery-2.1.4.js"></script>
<script src="scripts/knockout-3.3.0.js"></script>
<script src="cordova.js"></script>
<script src="scripts/platformOverrides.js"></script>
<script src="scripts/index.js"></script>
</body>
</html>
Initial window:
After click on Remove Oil:
Did you use the latest knockout-3.3.0.js?
In my opinion you could also test it with IE without cordova, because it is the same browser engine:
http://jsfiddle.net/k7x7a6q9/
Tested in IE11 and MS Edge 20.10240.16384.0 under Windows 10
A good way to find the root cause, is to look in the DOM-Explorer, to see what is happening. It is automatically open, when you start debugging or you can open it by typing "DOM" in the Quick Launch field during debugging in the top right of Visual Studio:
...and set a breakpoint in JavaScript, to verify if the click event is thrown:

The above code produces a JavaScript-error: "productName not found" under Windows 8.1. I assume it is a race condition between the script block in the header and body.
The following code does not produce this error:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<title>KnockoutTemplate</title>
<script src="scripts/knockout-3.3.0.js"></script>
<link href="css/index.css" rel="stylesheet" />
</head>
<body>
<h4>Product List</h4>
<div data-bind="template: { name: 'product-template'}"></div>
<script src="cordova.js"></script>
<script src="scripts/platformOverrides.js"></script>
<script src="scripts/index.js"></script>
<script type="text/html" id="product-template">
<ul>
<!-- ko foreach: productArray-->
<li><span data-bind="text: productName"></span><br /></li>
<!-- /ko -->
</ul>
</script>
<script type="text/javascript">
function ProductViewModel() {
this.productArray = ko.observableArray([{
productName: 'Milk'
}, {
productName: 'Oil'
}, {
productName: 'Butter'
}]);
}
ko.applyBindings(new ProductViewModel());
</script>
</body>
</html>
I would strongly recommend to put the JavaScript into an external file as I wrote in the first answer.

Related

Lazy Loading a service using oclazyload

This is index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://code.jquery.com/jquery-1.11.2.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.js"></script>
<script src="node_modules/oclazyload/dist/ocLazyLoad.js"></script>
<script src="testApp.js"></script>
</head>
<body>
<h3>Lazy load succeded if you can see 'Hello world' below</h3>
<div id="example" ng-app="LazyLoadTest" ng-controller="TestController">
<button ng-click="fun()">Start</button>
</div>
<script>
angular.module("LazyLoadTest", ["oc.lazyLoad"])
.controller("TestController", function($scope, $ocLazyLoad, $compile) {
$scope.fun=function(MyService){
$ocLazyLoad.load("testApp.js").then(function() { //loading a module
console.log('loaded!!'+$scope);
var el, elToAppend,elToAppend2;
elToAppend = $compile('<say-hello to="world"></say-hello>')($scope); //appending it to div
el = angular.element('#example');
console.log(el);
el.append(elToAppend)
//el.append(elToAppend2);
}, function(e) {
console.log('errr');
console.error(e);
})
}
});
</script>
</body>
</html>
The above code is the module which is to be loaded at run time. Able to load Directive but need some help to load service.
How to laxyload the service defined in testApp.js?
Please help me out with this

Simple Polymer element from web server works in Chrome but not Firefox or Safari or IE

I am working with serving a simple polymer element from a Tomcat server. The element works fine in Chrome but fails in the recent version of Firefox 49.0.2.
I have attached the content the two elements and the problem seems to happen because the WebComponentsReady event is fired repeatedly over and over again in Firefox but in Chrome only four times.
Furthermore by including a include on the paper-slider element in the simple-element below causes Firefox to go into a loop where it keeps reloading the files over and over again ?!
<link rel="import" href="./bower_components/paper-slider/paper-slider.html">
What is going on?
simple-element-demo.html (below)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="description" content="Demo of simple element">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
</script>
<script src="./bower_components/webcomponentsjs/webcomponents-lite.js">
</script>
<link rel="import" href="./bower_components/polymer/polymer.html">
<link rel="import" href="./simple-element.html"></link>
</head>
<body>
<div>Hello! I am going to demo simple-element. See below me.</div>
<simple-element></simple-element>
</body>
<script>
document.addEventListener('WebComponentsReady', function(e) {
console.log('WebComponentsReady', e);
debugger;
});
</script>
</html>
simple-element.html below
<!doctype html>
<html>
<head>
<title>Simple Element</title>
<script src="./bower_components/webcomponentsjs/webcomponents-lite.js">
</script>
<link rel="import" href="./bower_components/polymer/polymer.html">
<link rel="import" href="./bower_components/paper-slider/paper-slider.html">
</head>
<body>
<dom-module id="simple-element">
<template>
<div class="container flex-horizontal">
Hi There! I am Simple Element.
</div>
</template>
<script>
Polymer({
is: 'simple-element',
properties: {
prop1: {
type: String,
notify: true
},
},
created: function() {
console.log('Simple is created');
},
ready: function() {
console.log('Simple is ready');
}
});
</script>
</dom-module>
</body>
</html>
I was able to fix the problem by including webcomponents-lite.js only once in the main file: simple-element-demo.html.
I removed the line below from the simple-element.html and now it works just fine in all browsers.
<script src="./bower_components/webcomponentsjs/webcomponents-lite.js">
</script>

Difficulty implementing Chart widget with Kendo UI

I'm creating a mobile app using KendoUI in the Telerik AppBuilder. I created a blank view to hold my chart and then went in to start adding the code. I cannot get the chart to appear.
These are the scripts referenced in my index.html:
<script src="cordova.js"></script>
<script src="kendo/js/jquery.min.js"></script>
<script src="kendo/js/kendo.mobile.min.js"></script>
<script src="app.js"></script>
<script src="lib/progress/progress.all.min.js"></script>
<script src="dataProviders/progressDataProvider.js"></script>
Here is the code of my chart view:
<div data-role="view" data-title="Audit Tracker" data-layout="main" data- model="app.auditTracker" data-show="app.auditTracker.onShow" data-after-show="app.auditTracker.afterShow">
<div id="chart">
</div>
</div>
And here is the code in the associated JavaScript file:
'use strict';
app.auditTracker = kendo.observable({
onShow: function () {},
afterShow: function () {}
});
(function(parent) {
$("#chart").kendoChart({
title: {
text: "Audit Tracker"
},
series: [
{name: "Audits Completed", data: [5,10,15,3]}
],
categoryAxis: {
categories: ["January", "February", "March", "April"]
}
});
})(app.auditTracker);
What am I doing wrong here? This seems like it should be simple!
Thanks in advance for the help.
My problem was that I did not have the correct framework files referenced in my index.html.
Here are the files that I ended up using as far as the framework goes:
<script src="cordova.js"></script>
<script src="jquery.min.js"></script>
<script src="kendo.all.min.js"></script>
<link rel="stylesheet" href="kendo.common.min.css" />
<link rel="stylesheet" href="kendo.default.min.css" />
<link rel="stylesheet" href="kendo.mobile.all.min.css"/>

mediaelement.js failing when loaded via ajax

I have a simple page which uses the mediaelement.js audioplayer plugin. The player attaches and functions correctly when loaded normally. However, when the page is loaded via ajax, the mediaelementplayer does not attach to the audio tag.
I use this code to call the file via ajax and jquery:
<html>
<head>
<link href="/test-vocabulary.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script>
$(document).ready(function(){
$(".ajax_vocab_link").click(function(evento){
evento.preventDefault();
var ajaxDivNum = $(this).attr('id').split('_')[1];
var searchTerm = $(this).attr('title');
$("#ajaxcontainer_"+ajaxDivNum).load("test-audioplayer-se.php", {chrisSearch: searchTerm}
);
});
})
</script>
</head>
<body>
<p><button class='ajax_vocab_link' id='ajaxlink_1' title='clothes'>Link to load ajax doc</button></p>
<div class='ajax_vocab_container' id='ajaxcontainer_1'>This is div id ajaxcontainer_1</div>
</body>
</html>
The audioplayer page is:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es">
<head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<!-- Audio Player CSS & Scripts -->
<script src="http://www.ingles23.com/audioplayer/js/mediaelement-and-player.min.js"></script>
<link rel="stylesheet" href="http://www.ingles23.com/audioplayer/css/style4.css" media="screen">
<!-- end Audio Player CSS & Scripts -->
<script>
$(document).ready(function() {
$('#audio-player-vocab0').mediaelementplayer({
alwaysShowControls: true,
features: ['playpause'],
audioVolume: 'horizontal',
audioWidth: 400,
audioHeight: 120
});
});
</script>
</head>
<body>
<div class='display_vocab_container' >
<div class='display_vocab_text' >
<div class='audio-player-slim'>
<audio controls='controls' type='audio/mp3' src='/sound/mp3/i23-crear-frases-ingles-5.mp3' id='audio-player-vocab0'></audio>
</div>
</div>
</div>
</body>
</html>
I've tried many combinations including using on, live, success and moving the css/js links between the documents, but these have all made the situation worse.
What can i do get the file to attach medaielementplayer when loaded via ajax?
Try to put the mediaelementplayer() function call in the ajax success function, that worked for me. So unless you want to use .ajax instead of .load you'll need to pass it as the second argument to the load function. Or use http://api.jquery.com/ajaxSuccess/
$(".ajax_vocab_link").click(function(evento) {
evento.preventDefault();
var ajaxDivNum = $(this).attr('id').split('_')[1];
var searchTerm = $(this).attr('title');
$("#ajaxcontainer_"+ajaxDivNum).load("test-audioplayer-se.php", function() {
$('#audio-player-vocab0').mediaelementplayer({
alwaysShowControls: true,
features: ['playpause'],
audioVolume: 'horizontal',
audioWidth: 400,
audioHeight: 120
});
});
});

Tablesorter not working on MVC3 web app on Visual Studio 2010

Tablesorter not working on MVC3 web app on Visual Studio 2010?
To reproduce the problem:
open Visual Studio 2010
create a new ASP.NET MVC 3 Web Application
Replace Views/Shared/_Layout.cshtml with:
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
#* This doesn't work and I don't know why *#
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.tablesorter.min.js")" type="text/javascript"></script>
#*This works*#
#*<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
*#
</head>
<body>
<div class="page">
<div id="main">
#RenderBody()
</div>
</div>
</body>
</html>
Replace Views/Home/Index.html with:
<h2>debug jquery Kano</h2>
<p>
testing
</p>
<table id="theTable" class="tablesorter">
<thead>
<tr><th>Tic</th><th>Tac</th><th>Toe</th></tr>
</thead>
<tbody>
<tr><td>o</td><td>o</td><td>x</td></tr>
<tr><td>x</td><td>o</td><td>o</td></tr>
<tr><td>o</td><td>x</td><td>x</td></tr>
</tbody>
</table>
<script type="text/javascript">
// $(function () {
// alert("$: jQuery found!");
// });
$(document).ready(function () {
$("#theTable").tablesorter();
});
</script>
Download jquery.tablesorter.min.js from http://tablesorter.com and put into /Scripts directory.
Build and run the app.
As you will hopefully see, the tablesorter call in Index.cshtml doesn’t seem to successfully execute.
Thank you for your help!
Cheers,
Kevin
bestway to do is add tablesorter.js to bundleconfig.cs like this-
bundles.Add(new ScriptBundle("~/bundles/jquery.tablesorter").Include("~/Scripts/jquery.tablesorter.js"));
On _layout.cshtml page
add css-
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
<link href="#Url.Content("~/Content/style.css")" rel="stylesheet" type="text/css" />
</head>
and on bottom add script like
</footer>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryui")
#RenderSection("scripts", required: false)
</body>
</html>
and on the page using add a session for it.. so u dont have to use on every single page
#section scripts
{
#Scripts.Render("~/bundles/jquery.tablesorter")
<script type="text/javascript">
$(document).ready(function () {
$("#myTable").tablesorter();
});
$(document).ready(function () {
$("#myTable").tablesorter({ sortList: [[0, 0], [1, 0]] });
});
</script>
}
The problem seems to be in the way that Javascript is cached. The workaround is to close all instances of the browser between runs and to minimize the use of the back buttons on the browser.

Resources