edit: This questions is solved
Stupidly enough, the url /img/images.json is treated differently by the simpleHttpServer used to test the application than by the iOS simulator.
It was a long search why it would show the list in the browser when testing but not in the simulator. Apparently the simpleHttpServer that comes with python will treat a url starting with the / as it's root, for example the www folder. The simulator does not and would appreciate a relative location, starting with no /
The problem seems mostly caused by the rustiness of my web-dev skills ^.^
====================
I am trying to make a simple ionic app, and for some input I am using the Angular Tutorial.
I have a very simple page that should load the contents of a json-file with image data. And all it needs to do for now is showing the image names. At the end it should dump the complete data from the json-file.
This is all based of the blank project created with ionic.
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="js/controller.js"></script>
</head>
<body ng-app="phocalsApp">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Ionic Blank Starter</h1>
</ion-header-bar>
<ion-content ng-controller="imageListCtl">
<ul class="imagelist">
<li ng-repeat="image in imagelist" >
{{image.imgName}}
</li>
</ul>
{{imagelist | json}}
</ion-content>
</ion-pane>
</body>
</html>
app.js:
// Ionic Starter App
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
angular.module('phocalsApp', ['ionic', 'phocalsControllers'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
controller.js
'use strict';
var phocalsControllers = angular.module('phocalsControllers', []);
phocalsControllers.controller('imageListCtl', ['$scope', '$http',
function($scope, $http) {
$http.get('/img/images.json').success(function(data) {
$scope.imagelist = data;
});
$scope.orderProp = 'imgDate';
}]);
images.json:
[
{
"imgUrl":"",
"imgName":"Nieuwste Foto",
"imgDate":20140525
},
{
"imgUrl":"",
"imgName":"tweede Foto",
"imgDate":20140524
},
{
"imgUrl":"",
"imgName":"derde Foto",
"imgDate":20140523
}
]
Seeing as I pretty much use the same code as the angular example, I would expect this to work, unfortunately all the output I am getting when running in the ios Simulator is an empty page with the header-bar. No errors or nothing. Can anyone tell me what I am doing wrong here?
You are missing some console.log(data) in your controller to check whether the controller is initialized, wether $http actually succeeds etc.
Even after using angular for months, i have to log every step cause there are too many things to go wrong :)
Also you should add an error function to
$http.get('/img/images.json').success(function(data) {
$scope.imagelist = data;
}).error(function(data) ....;
Related
I'm a newbie to reactjs and trying to test a very basic component, however it seems all my struggle is futile because its not showing up in the browser.
I'm using asp.net MVC 5 app and I've been following along this tutorial https://reactjs.net/getting-started/tutorial_aspnet4.html as the tutorial states you need to add React.Web.Mvc4 Nuget package which have some dependencies.
My simple React component (SimpleComponent.jsx)
var ComponentBox = React.createClass({
render: function() {
return (<div style="background-color:antiquewhite">Hello World ReactJs Component!</div>);
}
});
ReactDOM.render(
<ComponentBox />,
document.getElementById('reactDiv')
);
and my razor view is pretty simple
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/remarkable/1.7.1/remarkable.min.js"></script>
</head>
<body>
<div id="reactDiv"></div>
<script src="#Url.Content("~/Scripts/SimpleComponent.jsx")"></script>
</body>
</html>
Did I miss something?
The Solution for my problem was to replace the style element in my jsx file as following
var ComponentBox = React.createClass({
render: function () {
return (<div style={{background:'antiquewhite'}}>Hello World ReactJs Component!</div>);
}
});
Based on react docs "using the style attribute as the primary means of styling elements is generally not recommended"
by using javascript object to store the style as properties and I hope this'll help someone.
I'm looking to create a test file (test.js). The Test.js file's purpose will be to perform unit tests for a particular controller (ie: Main.controller.js).
How can I load in this controller to an external js file?
I've tried using sap.require:
sap.ui.require(["/pricingTool/Controller/Main.controller"],
function(Main){
//Quint code
test("hello test", function(assert) {
assert.ok(1 == "1", "Passed!");
});
});
But I get an error that says:
failed to load /Controller/Main.controller.js
This tells me I'm either structuring this wrong, using the wrong path, or both. Any suggestions would be helpful. I've attached my file tree below for reference.
Component.js
sap.ui.define(['sap/ui/core/UIComponent'],
function(UIComponent) {
"use strict";
var Component = UIComponent.extend("pricingTool.Component", {
metadata : {
metadata : {
maniest: "json"
},
rootView : "pricingTool.view.Main",
dependencies : {
libs : [
"sap.m",
"sap.ui.layout"
]
},
config : {
sample : {
files : [
"Main.view.xml",
"Main.controller.js"
]
}
}
},
init : function () {
// call the init function of the parent
UIComponent.prototype.init.apply(this, arguments);
// additional initialization can be done here
}
});
return Component;
});
index.html
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<title>Pricing Tool</title>
<script id="sap-ui-bootstrap"
src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.m"
data-sap-ui-theme="sap_belize"
data-sap-ui-xx-bindingSyntax="complex"
data-sap-ui-preload="async"
data-sap-ui-compatVersion="edge"
data-sap-ui-resourceroots='{"pricingTool": "./"}'>
</script>
<script src='../pdfmake-master/build/pdfmake.min.js'></script>
<script src='../pdfmake-master/build/vfs_fonts.js'></script>
<!-- Application launch configuration -->
<script>
sap.ui.getCore().attachInit(function() {
new sap.m.App ({
pages: [
new sap.m.Page({
title: "Pricing Tool Rapid Prototype",
enableScrolling : true,
content: [ new sap.ui.core.ComponentContainer({
name : "pricingTool"
})]
})
]
}).placeAt("content");
});
</script>
</head>
<!-- UI Content -->
<body class="sapUiBody" id="content" role="application">
</body>
</html>
initialTest.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>QUnit Example</title>
<link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.15.0.css">
<script id="sap-ui-bootstrap"
src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js">
</script>
<script src="//code.jquery.com/qunit/qunit-1.15.0.js"></script>
<script src="allTests.js"></script>
<script src="/Controller/Main.controller.js"></script>
<script>
</script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>
You do not need to reference the controller file directly inside the .html file.
The problem is that UI5 does not know where to find your resources. The resolution process is the following:
All standard resources are loaded from a path relative to where your sap-ui-core.js was loaded from.
All resources with custom namespaces are loaded based on the resource roots definition.
Basically, in the resource roots you define a map between a namespace prefix and the location where to find the resources starting with that prefix. If you use relative paths, then the locations are resolved relative to your html file.
In your index.html you have done this: data-sap-ui-resourceroots='{"pricingTool": "./"}' which is perfectly fine. Because your index.thml is located at the root of the project, requesting the pricingTool/Controller/Main.controller will lead to making a request at ./Controller/Main.controller which is actually our file.
But in your initialTest.html you failed to specify any resource root at all. Moreover, you referenced your controller directly and the path seems to not be right (note that a path starting with a leading / is considered an absolute path on the current host; depending on the server you are using, this might not be correct, as usually each application has its own subpath in the server).
You should therefore include a data-sap-ui-resourceroots='{"pricingTool": "../"}' inside your initialTest.html. Notice that I have used .. because the html file is inside the Test folder (and the other stuff is in sibling folders).
I see some others (e.g. this post) have had trouble using external javascript scripts in JQuery Mobile - as of today I have joined their ranks.
I have a single external js script (controllers.js) which contains code that affects several pages on the site. It is loaded on every page of the site. I put the js file just before the tag it works fine on the initial page load. However when I navigate thereafter (using the JQM Ajax methods) all functions in the script stop working. I would have thought the script would remain in cache - but heyho. Anyhow there's an FAQ which answers this question and I've implemented their suggestion which is: "...to reference the same set of stylesheets and scripts in the head of every page." I have done this but when I do even on the first page load the js doesn't fire. There aren't page specific scripts - so the remainder of that FAQ does not apply.
My cut down html looks like this:
<!doctype html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="/static/jquery-ui-1.10.3.custom.min.css">
<link rel="stylesheet" href="/static/jquery-mobile/css/themes/default/jquery.mobile-1.3.2.min.css">
<script src="/static/jquery-1.9.1.min.js"></script>
<script src="/static/jquery-ui/jquery-ui-1.10.3.custom/js/jquery-ui-1.10.3.custom.min.js"></script>
<script src="/static/jquery-mobile/js/jquery.mobile-1.3.2.min.js"></script>
<!-- CSS: implied media="all" -->
</head>
<body>
<div data-role="page" id = "main-page">
<div data-role="header" style="overflow:hidden;">
</div>
<div id = "home" data-role="content">
<input type ='button' id = "some_btn" value="press me">
</div>
</div>
<script type="text/javascript" src="/static/js/controllers.js"></script>
</body>
</html>
and within the javascript file
controllers.js
$('#some_btn').click(function()
{
alert('button pressed');
});
Any ideas on what I may be doing wrong here?
Since the content in the #page is loaded dynamically via ajax, click will not work, since it only works on elements that are on the page when the script is called.
You need to use the .on() method:
$('body').on('click','#some_btn',function()
{
alert('button pressed');
});
when I tried to run even a blank app, the console output is:
"Error calling js to fire nativeReady event. Did you include cordova.js in your html script tag?"
Doctype is:
<!DOCTYPE html>
And this are script references:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="initial-scale=1, width=device-width, height=device-height" />
<link rel="stylesheet" href="css/jquery.mobile.structure-1.3.0.min.css" />
<link rel="stylesheet" type="text/css" href="css/index.css" />
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type='text/javascript' src='js/angular.min.js'></script>
<script type='text/javascript' src='js/angular-ui.js'></script>
<script type='text/javascript' src='js/jqm-setup.js'></script>
<script type="text/javascript" src="js/jquery.mobile.js"></script>
<script type="text/javascript" src="js/jquery-mobile-angular-adapter.min.js"></script>
<script type="text/javascript" src="cordova-2.5.0.js"></script>
<script type="text/javascript" src="js/index.js"></script>-->
This error disappears only when I remove the jquery mobile stuff...
Thanks in advance.
I would avoid JQuery Mobile in PhoneGap applications. I got to meet Andrew Trice, Adobe PhoneGap Evangelist, at a DC Droid Meet and listened to him present in a few Webinars. I've heard him say more than once that JQuery Mobile has huge performance issues. He recommended using other frameworks if possible. There are many other frameworks out there with good design, widgets, and samples that make them easy to learn. I think he even created his own called AppUI. Just look around and you'll find some really cool ones.
That error is definitely what it says: your cordova.js file is not being included correctly. Fix that first.
To answer your larger question: Angular, jQuery Mobile, and PhoneGap will play together but it comes with some big caveats.
The biggest issue is that the jQuery Angular Mobile adapter is currently abandoned while they invest time in building a better solution: angular-jqm. That means that the adapter only works with outdated versions of the libraries.
Second: those outdated library versions have some issues working with Windows Phone. These are fixable, too, but lock you into an even less maintainable version of them.
So here is the setup:
<script src="javascripts/vendor/jquery-mobile-1.3.1.js"></script>
<!-- this angular-1.0.6 includes a patch to support WP8 URLs: https://github.com/angular/angular.js/issues/2303 -->
<script src="javascripts/vendor/angular-1.0.6.js"></script>
<script src="javascripts/vendor/jquery-angular-mobile-adapter-1.3.2.js"></script>
Unfortunately I was never able to get partials to load via XHR so I included all pages in index.html document.
<body ng-controller="AppController">
<div data-role="page" id="first" ng-controller="FirstController">
<h1>First Page</h1>
<p>{{foo}}</p>
<p>Second Page</p>
</div>
<div data-role="page" id="second" ng-controller="SecondController">
<h2>Second Page</h2>
</div>
</body>
Then you need to switch off a few niceties in the JavaScript and set up your routes:
<script>
var so_example = angular.module('so_example', []).
config(function ($routeProvider, $locationProvider, $compileProvider) {
// turn off html5 mode so that we just navigate around using hashes
$locationProvider.html5Mode(false).hashPrefix("");
// allow for the odd URLs included in Windows Mobile PhoneGap
$compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel|x-wmapp0):/);
$routeProvider.
when('/second', {
templateUrl: '#second',
jqmOptions: { transition: 'slide' }
}).
when('/', {
templateUrl: "#first"
});
}).
controller("FirstController", function ($scope) {
$scope.foo = "Hello, World!";
}).
controller("SecondController", function ($scope) {
});
</script>
Now you need to leverage the Cordova library before you bootstrap Angular to your HTML:
var app = (function () {
function onDeviceReady() {
angular.bootstrap(document, ['so_example']);
$.mobile.phonegapNavigationEnabled = true;
}
return {
initialize: function() {
document.addEventListener('deviceready', onDeviceReady, false);
}
};
})();
app.initialize();
I am having trouble with using OpenLayers in Gmaps4Rails (Gem version 1.5.2.) When I click on a marker I would like to show the typical callout (Infobox). Unfortunately I get the following JavaScript error:
this.serviceObject is undefined
Firebug calls the line 195 of the file "gmaps4rails.openlayers.js" responsable:
return this.serviceObject.addPopup(popup);
If I use Google Maps as API provider instead, everything works fine. Showing and hiding the infobox works nicely. This is why I assume that the error must be somewhere in "gmaps4rails.openlayers.js"
I tried on the latest FF and Chrome on Mac.
For reproducing the error in a reduced example, I created a simple HTML page in the public folder of my Rails 3.2 app and directly linked the needed JS and CSS files. To create the HTML page I copied the HTML code of my broken Rails app and reduced it.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link href="/assets/gmaps4rails.css" media="screen" rel="stylesheet" type="text/css" />
<script src="/assets/gmaps4rails/gmaps4rails.base.js" type="text/javascript"></script>
<script src="/assets/gmaps4rails/gmaps4rails.openlayers.js" type="text/javascript"></script>
</head>
<body>
<div class="map_container">
<div id="map" class="gmaps4rails_map"></div>
</div>
<script src="http://www.openlayers.org/api/OpenLayers.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
Gmaps.map = new Gmaps4RailsOpenlayers();
Gmaps.load_map = function() {
Gmaps.map.map_options.provider = "openlayers";
Gmaps.map.initialize();
Gmaps.map.markers = [
{"description":"<p>This shall be in in the popup</p>",
"id":117979030,
"lat":39.5715,
"lng":2.64694}
];
Gmaps.map.create_markers();
Gmaps.map.adjustMapToBounds();
Gmaps.map.callback();
};
Gmaps.oldOnload = window.onload;
window.onload = function() {
Gmaps.triggerOldOnload();
Gmaps.loadMaps();
};
</script>
</body>
</html>
Unfortunately I could not find a working example of a successful Gmap4Rails–Openlayers integration on the web. Am I missing a mandatory parameter?
Thanks in advance.
It's a bug.
Replace:
return this.serviceObject.addPopup(popup);
with:
return this.map.addPopup(popup);
I'll push a fix soon, thanks and +1