Phonegap images not showing - image

I'm having trouble getting my images to work in my phonegap build.
I've read that the absolute paths might not work so i've tried both absolute and relative paths, still no luck.
I'm including the images like this:
<Col key={1} xs={3}>
<Image src='/tire_selected.png' responsive />
</Col>
or relative
<Col key={1} xs={3}>
<Image src='tire_selected.png' responsive />
</Col>
equals
<img class="img-responsive" src="tire_deselected.png" data-reactid=".0.0.1.0.0.0.0.1.1.0.0.$4.0">
Col & Image is bootstrap helper components using bootstrap-react. And this all works fine in the web view, but not when built with phonegap. It should though, the source is already compiled and without errors in both cases.
Following is my config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.app.exampleapp" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0">
<name>App</name>
<description>
App
</description>
<author email="support#example.com" href="http://www.example.com">
Author
</author>
<content src="index.html" />
<preference name="permissions" value="none" />
<preference name="orientation" value="default" />
<preference name="target-device" value="universal" />
<preference name="fullscreen" value="true" />
<preference name="webviewbounce" value="true" />
<preference name="prerendered-icon" value="true" />
<preference name="stay-in-webview" value="false" />
<preference name="ios-statusbarstyle" value="black-opaque" />
<preference name="detect-data-types" value="true" />
<preference name="exit-on-suspend" value="false" />
<preference name="show-splash-screen-spinner" value="true" />
<preference name="auto-hide-splash-screen" value="true" />
<preference name="disable-cursor" value="false" />
<preference name="android-minSdkVersion" value="14" />
<preference name="android-installLocation" value="auto" />
<gap:plugin name="org.apache.cordova.geolocation" />
<icon src="icon.png" />
<access origin="*" />
<plugin name="cordova-plugin-whitelist" version="1" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
</widget>
Git repository:
app.js
vendor.js
config.xml
favicon.ico
humans.txt
index.html
robots.txt
tire_deselected.png
tire_selected.png
Icon.png works fine though. I have no idea whats causing the other images to not work. Any help would be appreciated!
Edit
I've tried setting content-security-policy, if that was the issue that i weren't able to set img-src and display images via javascript.
<meta http-equiv="Content-Security-Policy" content="
default-src http://10.3.10.104/ 'self' * 'unsafe-inline';
style-src http://10.3.10.104/ 'self' * 'unsafe-inline';
img-src http://10.3.10.104/ 'self' * 'unsafe-inline';
script-src http://10.3.10.104/ 'self' * 'unsafe-inline';">
But still no luck
file:///tire_deselected.png net::ERR_FILE_NOT_FOUND
There file is there, because when inserting an img-element into index.html it's displayed.
I even tried accessing it by the path that's displayed in the source folder running developer tools.
file:///data/user/0/com.oas.exampleapp/files/downloads/app_dir/tire_deselected.png
Doesn't work either, i'm starting to think that phonegap is broken, atleast works very poorly in combination with react.

After compilation the build.phonegap.com put your source files into "www" directory.
You can access your local image file using the following path "/android_asset/www/"
<image src='/android_asset/www/tire_selected.png' responsive />
If your image is placed in a subdirectory inside the root direcctory then you can use the following:
<image src='/android_asset/www/sub-direcctory/tire_selected.png' responsive />
Note: replace the "sub-direcctory" with your own if there is any in which the local image file is contained.

I added an img tag to index.html and set the src attribute to "images/logo.png" and it loads without issue.
...
<body>
<div id="root"></div>
<img id="footer-logo" src="images/logo.png" style="background-color: black; width: 200px;" />
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script src="js/vendor.bundle.js"></script>
<script src="js/app.bundle.js?v=2"></script>
</body>
</html>
I have a react component with an img tag and the same src value "images/logo.png"
...
<div style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin: 0px; padding-top: 0px; letter-spacing: 0px; font-size: 24px; font-weight: 400; color: rgb(48, 48, 48); height: 64px; line-height: 64px; flex: 1 1 0px; text-align: center;">
<img id="header-logo" src="images/logo.png" style="width: 105px; margin-top: 16px;">
</div>
...
The img in the react component doesn't load; 404. Yet this equates to true
document.getElementById('footer-logo').src === document.getElementById('header-logo').src
How is it that one of the images loads and the other doesn't? Does it have something to do with the react component being loaded into the DOM dynamically or react's virtual DOM?
The src attributes equate to file:///images/logo.png. IF I set the src attribute on the #header-logo like this, it loads:
document.getElementById('header-logo').src = cordova.file.applicationDirectory + "www/images/logo.png"
Hope this provides more info to this very bizarre behaviour.

Hope this helps. So I also had the problem.
What I did was, was to create a another folder /images/ (duplicate) and still use my images I imported via react via my /static/components/images folder. You can take it a bit further by adding conditionals for staging or live.
So the answer is here.:
import Logo from '../images/logo.png';
<img src={`./${Logo}`} alt="Logo" />
Full example.:
import React, { Component } from 'react';
import Logo from '../images/logo.png';
class Header extends Component {
render() {
return(
<div className="logo mt-3">
<img src={`./${Logo}`} alt="Logo" />
</div>
);
}
}
export default Header;
Got the idea from this post.: Images not showing in PhoneGap Build application

Related

Why SAPUI5 loads similar fragment several times?

I have an XML fragment and use it in several places in an XML view.
<IconTabFilter text="ABC" key="1" icon="sap-icon://alphabetical-order">
<content>
<Table id="table1" width="auto" items="{path:'/ContactSet',parameters:{expand:'BusinessAddress,HomeAddress,OtherAddress,Photo'},filters:[{path:'Surname',operator:'StartsWith',value1:'A'},{path:'Surname',operator:'StartsWith',value1:'B'},{path:'Surname',operator:'StartsWith',value1:'C'}]}" noDataText=" {worklistView>/tableNoDataText}" busyIndicatorDelay="{worklistView>/tableBusyDelay}" growing="true" growingScrollToLoad="true" updateFinished="onUpdateFinished">
<headerToolbar>
<core:Fragment fragmentName="de.cimt.cimply.AddressBook.view.worklist.tablesHeader" type="XML"/>
</headerToolbar>
<columns>
<core:Fragment fragmentName="de.cimt.cimply.AddressBook.view.worklist.tablesColumns" type="XML"/>
</columns>
<items>
<core:Fragment fragmentName="de.cimt.cimply.AddressBook.view.worklist.tablesRows" type="XML"/>
</items>
</Table>
</content>
</IconTabFilter>
<IconTabSeparator icon="sap-icon://process"/>
<IconTabFilter text="DEF" key="2" icon="sap-icon://alphabetical-order">
<content>
<Table id="table2" width="auto" items="{path:'/ContactSet',parameters:{expand:'BusinessAddress,HomeAddress,OtherAddress,Photo'},filters:[{path:'Surname',operator:'StartsWith',value1:'D'},{path:'Surname',operator:'StartsWith',value1:'E'},{path:'Surname',operator:'StartsWith',value1:'F'}]}" noDataText="{worklistView>/tableNoDataText}" busyIndicatorDelay="{worklistView>/tableBusyDelay}" growing="true" growingScrollToLoad="true" updateFinished="onUpdateFinished">
<headerToolbar>
<core:Fragment fragmentName="de.cimt.cimply.AddressBook.view.worklist.tablesHeader" type="XML"/>
</headerToolbar>
<columns>
<core:Fragment fragmentName="de.cimt.cimply.AddressBook.view.worklist.tablesColumns" type="XML"/>
</columns>
<items>
<core:Fragment fragmentName="de.cimt.cimply.AddressBook.view.worklist.tablesRows" type="XML"/>
</items>
</Table>
</content>
</IconTabFilter>
But the view takes too long to load, especially in WEBIDE.
The reason is it loads similar fragment files several times. Here is an evidence:
The question is how can I improve the performance?
I don't want to repeat the code and I need to put that part of the code in a fragment, but I expected my browser to not load the same file several times.
There is no need to change your code in that case. SAP Web IDE / SCP leverages App Cache Buster concept out of the box, which fetches application resources (e.g. fragments) from the browser cache as long as those resources were not altered before.
See the sample screenshot below:
Given
Code:
<core:Fragment fragmentName="demo.view.fragment.MyFragment" type="XML" />
<core:Fragment fragmentName="demo.view.fragment.MyFragment" type="XML" />
<core:Fragment fragmentName="demo.view.fragment.MyFragment" type="XML" />
<core:Fragment fragmentName="demo.view.fragment.MyFragment" type="XML" />
<core:Fragment fragmentName="demo.view.fragment.MyFragment" type="XML" />
<core:Fragment fragmentName="demo.view.fragment.MyFragment" type="XML" />
URL attribute sap-ui-appCacheBuster=... which Web IDE automatically appends on app launch (describes where sap-ui-cachebuster-info.json is located)
If the devtool is open: Disable cache Unchecked <-- probably that was still activated in your case
Result
As you can see, fragments (and other resources) are loaded fron the disk cache instead of re-fetching them again and again.
Additionally, if the application is bundled for the final production environment, those fragments won't be even requested multiple times as they're typically already included in the bundled file (e.g. Component-preload.js).
If you run your app not in the webide testing environment the fragements should be loaded from cache.
However, you could load your fragment in your controller and use factoryfunctions instead of templates. Something like:
View:
<mvc:View controllerName="test.test.controller.View1" xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core" displayBlock="true" xmlns="sap.m">
<Shell id="shell">
<App id="app">
<pages>
<Page id="page" title="{i18n>title}">
<content>
<List items="{ path: '/myList', factory: '.myListFactory' }"/>
</content>
</Page>
</pages>
</App>
</Shell>
in your controller:
onInit: function () {
this.getView().setModel(new JSONModel({
"myList" : [{
"Name": "Test1"
}, {
"Name": "Test2"
}]
}));
},
myListFactory: function (sId) {
if(!this._myListFragment){
this._myListFragment = new sap.ui.xmlfragment("test.test.view.myListFragment", this);
}
return this._myListFragment.clone(sId);
}
fragment:
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core">
<StandardListItem icon="sap-icon://warning" title="{Name}" />

How do I request permissions for my PhoneGap project built using PhoneGap Build?

I am trying to get started with Phonegap and Phonegap Build to create a html/jquery based Android app. Currently my app consists of one single html page that allows you to enter two numbers, those numbers are sent out to my server, and the response is displayed on screen. Here is the code:
<!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>PoC</title>
<script src="JS/jquery.min.js"></script>
<script src="JS/jquery-ui.min.js"></script>
<script language="javascript" src="JS/date.js"></script>
<link rel="stylesheet" type="text/css" media="all" href="css/style.css">
<script>
function doCalc() {
$.ajax({
url: "http://nightscapecreations.com/test.cfc?method=multNums&thisNum=" + $('#thisNum').val() + "&multBy=" + $('#multBy').val()
}).done(function( data ) {
data = data.trim();
if ($.isNumeric(data)) {
$('#resultDiv').html(data);
} else {
$('#resultDiv').html(data);
}
})
}
</script>
</head>
<body>
<script type="text/javascript" src="cordova.js"></script>
This is a test. Here, multiply some numbers:
<input id="thisNum" placeholder="5" onChange="doCalc();"> x
<input id="multBy" placeholder="3" onChange="doCalc();">
=
<div id="resultDiv">
</div>
<input type="button" value="Calculate" onClick="doCalc();" style="width:150px;">
</body>
</html>
Just a very messy test to see how this whole thing works. This functions when opened on a browser, or when run through the Phonegap app. However, when I upload this to Phonegap Build, download the apk, copy it to the device, and install it there, the div fails to populate.
I looked at my app and was surprised to see it listed with no permissions. I suspect this is the cause of the failure; the app cannot access the internet and so cannot get a response back from its ajax call. This would also explain why PB's Weinre debugging shows no targets. However, no matter what I do I cannot figure out how to get PB to assign permissions.
This is my current config:
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.nightscapecreations.test"
version="1.0.0"
xmlns="http://www.w3.org/ns/widgets"
xmlns:gap="http://phonegap.com/ns/1.0">
<name>Test</name>
<description>
A PoC app
</description>
<author email="xxxxxxxxxxxx#hotmail.com" href="http://phonegap.com">
My Name
</author>
<content src="index.html" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
<preference name="orientation" value="portrait"/>
<preference name="fullscreen" value="false"/>
<preference name="permissions" value="none"/>
<feature name="http://api.phonegap.com/1.0/network"/>
<plugin name="cordova-plugin-network-information" source="npm" spec="~1.2.0" />
</widget>
There's a lot in there because I've been going through countless iterations of trial and error with stuff pulled from all over SO and various blogs. I have tried with and without the preference tags, the feature tag, the plugin tag, and much more, but no permissions are ever requested by the app.
I also tried adding a security policy as suggested in another post, but without success:
<meta http-equiv="Content-Security-Policy"
content="default-src *;
style-src 'self' 'unsafe-inline' 'unsafe-eval';
script-src 'self' 'unsafe-inline' 'unsafe-eval';">
How do I insure that my app has sufficient privileges to get data from my server?

PhoneGap Build with OneSignal not working

I'm using PhoneGap Build with OneSignal but it is not working. It shows only the first alert message.
Here is the code:
https://github.com/claudiosw/ZumitApp/
And you can download the app here:
https://build.phonegap.com/apps/2193000/builds
Also pasting the code here:
File config.xml:
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.zumitapp" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0">
<name>ZumitApp</name>
<description>Tenha Mais Resultados</description>
<author email="claudiosw#" href="http://zumitapp.com/App">Claudio Shigueo Watanabe</author>
<preference name="phonegap-version" value="cli-6.3.0" />
<feature name="http://api.phonegap.com/1.0/device" />
<preference name="orientation" value="portrait" /> <!-- all: default means both landscape and portrait are enabled -->
<gap:plugin name="org.apache.cordova.device" />
<gap:plugin name="org.apache.cordova.camera" />
<gap:plugin name="org.apache.cordova.media-capture" />
<gap:plugin name="org.apache.cordova.file" />
<gap:plugin name="org.apache.cordova.file-transfer" />
<gap:plugin name="org.apache.cordova.splashscreen" />
<gap:plugin name="org.apache.cordova.contacts" />
<gap:plugin name="org.apache.cordova.geolocation" />
<gap:plugin name="org.apache.cordova.inappbrowser" />
<gap:plugin name="org.apache.cordova.dialogs" />
<gap:plugin name="org.apache.cordova.vibration" />
<gap:plugin name="org.apache.cordova.network-information" />
<!--gap:plugin name="com.simplec.plugins.localnotification" /-->
<!--plugin name="com.onesignal.plugins.onesignal" spec="1.5.0" source="pgb" /-->
<!--plugin name="com.onesignal.plugins.onesignal" spec="1.9.0" source="pgb" /-->
<gap:plugin name="onesignal-cordova-plugin-pgb-compat" source="npm" />
<gap:plugin name="cordova-plugin-googleplayservices" source="npm" />
<gap:plugin name="cordova-plugin-android-support-v4" source="npm" />
<!--gap:plugin name="onesignal-cordova-plugin" source="npm" /-->
<!-- Recommend the newest cli but requires cli-5.1.1+ and gradle for Android. -->
<!-- If the below settings are not compatible with your project set the "PGB ANT" version above. -->
<!--preference name="android-build-tool" value="gradle" /-->
<icon src="icon.png" />
<icon src="res/icons/ios/Icon.png" gap:platform="ios" width="57" height="57" />
<icon src="res/icons/ios/Icon#2x.png" gap:platform="ios" width="114" height="114" />
<icon src="res/icons/ios/Icon-72.png" gap:platform="ios" width="72" height="72" />
<icon src="res/icons/ios/Icon-72#2x.png" gap:platform="ios" width="144" height="144" />
<icon src="res/icons/android/drawable-ldpi/Icon.png" gap:platform="android" gap:density="ldpi" />
<icon src="res/icons/android/drawable-mdpi/Icon.png" gap:platform="android" gap:density="mdpi" />
<icon src="res/icons/android/drawable-hdpi/Icon.png" gap:platform="android" gap:density="hdpi" />
<icon src="res/icons/android/drawable-xdpi/Icon.png" gap:platform="android" gap:density="xhdpi" />
<gap:splash src="ZumitApp_grande.jpg" />
<gap:splash src="res/screen/android/drawable-ldpi/splash.png" gap:platform="android" gap:density="ldpi" />
<gap:splash src="res/screen/android/drawable-mdpi/splash.png" gap:platform="android" gap:density="mdpi" />
<gap:splash src="res/screen/android/drawable-hdpi/splash.png" gap:platform="android" gap:density="hdpi" />
<gap:splash src="res/screen/android/drawable-xdpi/splash.png" gap:platform="android" gap:density="xhdpi" />
<gap:splash src="res/screen/ios/Default.png" gap:platform="ios" width="320" height="480" />
<gap:splash src="res/screen/ios/Default#2x.png" gap:platform="ios" width="680" height="960" />
<gap:splash src="res/screen/ios/Deafult-568h-2x.png" gap:platform="ios" width="640" height="1136" />
<preference name="stay-in-webview" value="true" />
<content src="index.html" />
<access origin="*" subdomains="true" />
<allow-navigation href="*" />
</widget>
File index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ZumitApp</title>
<script src="phonegap.js"></script>
<script src="jquery.min.js"></script>
<script>
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
// Now safe to use the Codova API
// Enable to debug issues.
alert("teste0");
window.plugins.OneSignal.setLogLevel({logLevel: 4, visualLevel: 4});
alert("teste1");
var notificationOpenedCallback = function(jsonData) {
console.log('didReceiveRemoteNotificationCallBack: ' + JSON.stringify(jsonData));
};
alert("teste2");
window.plugins.OneSignal.init("22a70849-091e-4eca-8b5b-e7fc5821f95b",
{googleProjectNumber: "428050097085"},
notificationOpenedCallback);
alert("teste3");
// Show an alert box if a notification comes in when the user is in your app.
window.plugins.OneSignal.enableInAppAlertNotification(true);
//alert("teste4");
window.location="http://zumitapp.com/App";
//alert("teste5");
}
</script>
</head>
<body>
<header class="bar bar-nav">
<h1 class="title">Boas-vindas ao ZumitApp</h1>
</header>
<h2>Aguarde. Carregando...</h2>
</body>
</html>
I have tried to debug but it didn't worked out. Maybe it is because my smartphone is old (LG-P705) or the desktop (Windows Vista).
Thanks you very much!

iOS pushnotification receiving Device Token but not no notification using Phonegap Build

I am trying to implement push notification using PhoneGap Build.
I am receiving a Device Token on my iOS Device but not receiving a Notification in the tray. Here my success call back is getting called but then the callback function is not getting called.
I have included the latest version of push plugin in config.xml.
Few Points about App:
This is my first app
I am implementing it using Phonegap Build
iOS device : Iphone 6s : iOS 9
Android Device: Samsung: Android 4.1.2
I am receiving the tray notification using below code in Android (though Android is delayed) but not in my iOS device.
Do Let me know if you need more information.
Here is the javascript code snippet.
onDeviceReady: function() {
//alert('Inside onDeviceReady');
var pushNotification = window.plugins.pushNotification;
//var device = window.plugins.
//alert ('Value of Variable Pushnotification : ' + pushNotification);
//alert ('Device Platform : ' + device.platform);
if (device.platform === 'android' || device.platform === 'Android')
{
//alert('Inside Register Call for Android');
pushNotification.register(app.successHandler, app.errorHandler,{"senderID":"935585158292","ecb":"app.onNotificationGCM"});
}
else
{
//alert('Inside Register Call for iOS');
pushNotification.register(app.pg_token_handler, app.pg_error_handler, {"badge": "true","sound":"true","alert":"true","ecb":"app.on_pg_apn_notification"});
}
},
on_pg_apn_notification: function(event)
{
if ( event.alert )
{
alert('Inside Alert call of APN Notification');
navigator.notification.alert(event.alert);
}
if ( event.sound )
{
alert('Inside sound call of APN Notification');
var snd = new Media(event.sound);
snd.play();
}
if ( event.badge )
{
alert('Inside Badge call of APN Notification');
pushNotification.setApplicationIconBadgeNumber(app.successHandler, app.errorHandler, event.badge);
}
}
}
Pasting Config.xml relevant code.
<?xml version="1.0" encoding="UTF-8"?>
<!-- config.xml reference: https://build.phonegap.com/docs/config-xml -->
<widget xmlns = "http://www.w3.org/ns/widgets"
xmlns:gap = "http://phonegap.com/ns/1.0"
id = "com.phonegap.helloworld"
version = "1.0.0">
<name>CalendarSync</name>
<description>
This is my first application using PhoneGap
</description>
<author href="http://phonegap.com" email="support#phonegap.com">
Aditya Lele
</author>
<platform name="ios|winphone|wp8|android" />
<!--
If you do not want any permissions to be added to your app, add the
following tag to your config.xml; you will still have the INTERNET
permission on your app, which PhoneGap requires.
-->
<preference name="permissions" value="none"/>
<!-- Customize your app and platform with the preference element. -->
<preference name="orientation" value="default" /> <!-- all: default means both landscape and portrait are enabled -->
<preference name="target-device" value="universal" /> <!-- all: possible values handset, tablet, or universal -->
<preference name="fullscreen" value="true" /> <!-- all: hides the status bar at the top of the screen -->
<preference name="webviewbounce" value="true" /> <!-- ios: control whether the screen 'bounces' when scrolled beyond the top -->
<preference name="prerendered-icon" value="true" /> <!-- ios: if icon is prerendered, iOS will not apply it's gloss to the app's icon on the user's home screen -->
<preference name="stay-in-webview" value="false" /> <!-- ios: external links should open in the default browser, 'true' would use the webview the app lives in -->
<preference name="ios-statusbarstyle" value="black-opaque" /> <!-- ios: black-translucent will appear black because the PhoneGap webview doesn't go beneath the status bar -->
<preference name="detect-data-types" value="true" /> <!-- ios: controls whether data types (such as phone no. and dates) are automatically turned into links by the system -->
<preference name="exit-on-suspend" value="false" /> <!-- ios: if set to true, app will terminate when home button is pressed -->
<preference name="show-splash-screen-spinner" value="true" /> <!-- ios: if set to false, the spinner won't appear on the splash screen during app loading -->
<preference name="auto-hide-splash-screen" value="true" /> <!-- ios: if set to false, the splash screen must be hidden using a JavaScript API -->
<preference name="disable-cursor" value="false" /> <!-- blackberry: prevents a mouse-icon/cursor from being displayed on the app -->
<preference name="android-installLocation" value="auto" /> <!-- android: app install location. 'auto' will choose. 'internalOnly' is device memory. 'preferExternal' is SDCard. -->
<preference name="android-build-tool" value="gradle" />
<!--
Define a specific version of PhoneGap to build into your app.
-->
<preference name="phonegap-version"/>
<!-- Plugins -->
<!-- Core plugins -->
<gap:plugin name="com.phonegap.plugins.pushplugin" version="2.5.0"/>
<gap:plugin name="org.apache.cordova.device" spec="0.3.0" source="pgb" />
<!-- Third party plugins -->
<!-- A list of available plugins are available at https://build.phonegap.com/plugins -->
<!--
<gap:plugin name="com.phonegap.plugins.barcodescanner" />
-->
<!-- Define app icon for each platform. -->
<icon src="icon.png" />
<icon src="res/icon/android/icon-36-ldpi.png" gap:platform="android" gap:qualifier="ldpi" />
<icon src="res/icon/android/icon-48-mdpi.png" gap:platform="android" gap:qualifier="mdpi" />
<icon src="res/icon/android/icon-72-hdpi.png" gap:platform="android" gap:qualifier="hdpi" />
<icon src="res/icon/android/icon-96-xhdpi.png" gap:platform="android" gap:qualifier="xhdpi" />
<icon src="res/icon/blackberry/icon-80.png" gap:platform="blackberry" />
<icon src="res/icon/blackberry/icon-80.png" gap:platform="blackberry" gap:state="hover"/>
<icon src="res/icon/ios/icon-57.png" gap:platform="ios" width="57" height="57" />
<icon src="res/icon/ios/icon-72.png" gap:platform="ios" width="72" height="72" />
<icon src="res/icon/ios/icon-57-2x.png" gap:platform="ios" width="114" height="114" />
<icon src="res/icon/ios/icon-72-2x.png" gap:platform="ios" width="144" height="144" />
<icon src="res/icon/webos/icon-64.png" gap:platform="webos" />
<icon src="res/icon/windows-phone/icon-48.png" gap:platform="winphone" />
<icon src="res/icon/windows-phone/icon-173.png" gap:platform="winphone" gap:role="background" />
<!-- Define app splash screen for each platform. -->
<gap:splash src="res/screen/android/screen-ldpi-portrait.png" gap:platform="android" gap:qualifier="port-ldpi" />
<gap:splash src="res/screen/android/screen-mdpi-portrait.png" gap:platform="android" gap:qualifier="port-mdpi" />
<gap:splash src="res/screen/android/screen-hdpi-portrait.png" gap:platform="android" gap:qualifier="port-hdpi" />
<gap:splash src="res/screen/android/screen-xhdpi-portrait.png" gap:platform="android" gap:qualifier="port-xhdpi" />
<gap:splash src="res/screen/blackberry/screen-225.png" gap:platform="blackberry" />
<gap:splash src="res/screen/ios/screen-iphone-portrait.png" gap:platform="ios" width="320" height="480" />
<gap:splash src="res/screen/ios/screen-iphone-portrait-2x.png" gap:platform="ios" width="640" height="960" />
<gap:splash src="res/screen/ios/screen-iphone-portrait-568h-2x.png" gap:platform="ios" width="640" height="1136" />
<gap:splash src="res/screen/ios/screen-ipad-portrait.png" gap:platform="ios" width="768" height="1024" />
<gap:splash src="res/screen/ios/screen-ipad-landscape.png" gap:platform="ios" width="1024" height="768" />
<gap:splash src="res/screen/windows-phone/screen-portrait.jpg" gap:platform="winphone" />
<gap:config-file platform="ios" parent="CFBundleShortVersionString">
<string>100</string>
</gap:config-file>
<!--
Define access to external domains.
<access /> - a blank access tag denies access to all external resources.
<access origin="*" /> - a wildcard access tag allows access to all external resource.
Otherwise, you can specify specific domains:
<access origin="http://phonegap.com" /> - allow any secure requests to http://phonegap.com/
<access origin="http://phonegap.com" subdomains="true" /> - same as above, but including subdomains, such as http://build.phonegap.com/
<access origin="http://phonegap.com" browserOnly="true" /> - only allows http://phonegap.com to be opened by the child browser.
-->
<access origin="*"/>
<!-- Added the following intents to support the removal of whitelist code from base cordova to a plugin -->
<!-- Whitelist configuration. Refer to https://cordova.apache.org/docs/en/edge/guide_appdev_whitelist_index.md.html -->
<plugin name="cordova-plugin-whitelist" version="1" />
<!-- <plugin name="Device" value="org.apache.cordova.Device" spec="1.0.0" source="npm" />
<feature name="Device">
<param name="android-package" value="org.apache.cordova.device.Device" />
</feature>
<feature name="Device">
<param name="ios-package" value="CDVDevice" />
</feature> -->
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
</widget>
IOS does not show a notification if the app is open, so I'm betting your code is correct.
From Apple Developer documents:
If your app is already in the foreground, iOS does not show the notification.
Source: Handling an Actionable Notification
I would recommend you write some custom notification like a popup to trigger when the app is open and a notification is received.

EXT.net - Grid Panel via Entity with DropDowns, Dates, Pin Editing and Deletion

Title sounds like a real mouthful, so let me try to explain this. I'm very strong with grinding out Web Forms and this is my second crack at using a framework and MVC (don't ask about the first one). Start with a table like this:
Title: Milestones
Id int - Auto, PK
Project_Id int - FK, Many Milestones to One Project, Provided static for now
Number int
Name varchar(50)
Status_Id int - FK One Status to One Milestone
PlannedDate date
LatestEstimate date
MilestoneType_ID int - FK One Type to One Milestone
These all sit on an SQL server, are pulled in by an Entity and then are pulled in by an ObjectDataSource, like this:
<asp:ObjectDataSource runat="server" ID="MilestonesObjectSource" SelectMethod="GetByProject"
DeleteMethod="DeleteMilestone" TypeName="TCProjectManagement.Models.MilestonesAddition">
<SelectParameters>
<asp:Parameter DefaultValue="6" Name="ProjectID" Type="Int32" />
</SelectParameters>
<DeleteParameters>
<asp:Parameter Type="Int32" Name="Id" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Type="Int32" Name="Id" />
<asp:Parameter Type="Int32" Name="Number" />
<asp:Parameter Type="String" Name="Name" />
<asp:Parameter Type="Int32" Name="Status_Id" />
<asp:Parameter Type="DateTime" Name="PlannedDate" />
<asp:Parameter Type="DateTime" Name="LatestEstimate" />
<asp:Parameter Type="Int32" Name="MilestoneType_ID" />
</UpdateParameters>
</asp:ObjectDataSource>
Sofar so good. Data pull seems to work out okay. I've got a couple more Object Sources that deal exclusively with the Foriegn Keys, so I'll skip those since they seem to be working.
The problems I have are attempting to stitch together many examples that don't seem to go together well. My objectives, in no paticular order:
1) Pin Editing: Click a button to edit, click it again to confirm. Rather do this than have somebody infer to double click for a change. Sofar, this sorta works.
2) Drop Downs for Foriegn Keys: While not in edit mode, should display the "Name" field of the FK. While in edit it should be a Drop Down for options (there's only three). This stays blank dispite what I do.
3) Deletion: Press a button to blow away a row. I put the button there but it's a copy of the JS for editing. What do I need to use to have it be deletion?
4) Dates: This doesn't work at all. One of the weird parts is that from the SQL server's type of Date, it gets changed to DateTime in the Entity and stays that way throughout. However, I cannot get the desired control of ext:DateField to cooperate with the provided data since it displays a time and completely blanks out when editing.. I know I'm doing something wrong here.
5) Saving Changes: Not quite sure I set it up right (or at all).
Provisions of Javascript:
<script type="text/javascript">
var pinEditors = function (btn, pressed) {
var columnConfig = btn.column,
column = columnConfig.column;
if (pressed) {
column.pinOverComponent();
column.showComponent(columnConfig.record, true);
} else {
column.unpinOverComponent();
column.hideComponent(true);
}
};
var pinDeleters = function (btn, pressed) { };
</script>
And ASP Code:
<ext:GridPanel ID="MilestonesGridPanel" runat="server" Title="Milestones" Width="1000px"
Height="300px">
<Store>
<ext:Store ID="MilestonesGridStore" runat="server" DataSourceID="MilestonesObjectSource">
<Model>
<ext:Model runat="server" IDProperty="Id">
<Fields>
<ext:ModelField Name="Id" Type="Int" />
<ext:ModelField Name="Number" Type="Int" />
<ext:ModelField Name="Name" Type="String" />
<ext:ModelField Name="Status_Id" Type="Int" />
<ext:ModelField Name="PlannedDate" />
<ext:ModelField Name="LatestEstimate" />
<ext:ModelField Name="MilestoneType_ID" Type="Int" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel>
<Columns>
<ext:Column ID="IdColumn" runat="server" DataIndex="Id" Text="DBID" Visible="false" />
<ext:ComponentColumn ID="NumberColumn" runat="server" DataIndex="Number" OverOnly="true"
Pin="true" Flex="1" Text="Number" Editor="true">
<Component>
<ext:NumberField ID="NumberColumnNumberField" runat="server" />
</Component>
</ext:ComponentColumn>
<ext:ComponentColumn ID="NameColumn" runat="server" DataIndex="Name" OverOnly="true"
Pin="true" Flex="1" Text="Name" Editor="true">
<Component>
<ext:TextField ID="NameColumnTextField" runat="server" />
</Component>
</ext:ComponentColumn>
<ext:ComponentColumn ID="StatusColumn" runat="server" DataIndex="Status_Id" OverOnly="true"
Pin="true" Flex="1" Text="Status" Editor="true">
<Component>
<ext:ComboBox ID="StatusColumnDropDownBox" runat="server" QueryMode="Local" Editable="false"
StoreID="MilestoneStatusStore" DisplayField="Name" ValueField="ID" EmptyText="Empty" />
</Component>
</ext:ComponentColumn>
<ext:ComponentColumn ID="PlannedDateColumn" runat="server" DataIndex="PlannedDate"
OverOnly="true" Pin="true" Flex="1" Text="Planned Date" Editor="true">
<Renderer Format="Date" FormatArgs="'m/d/y'" />
<Component>
<ext:DateField ID="PlannedDateColumnTextField" runat="server" Format="MM/dd/yyyy"
EmptyText="Empty" />
</Component>
</ext:ComponentColumn>
<ext:ComponentColumn ID="LatestEstimateColumn" runat="server" DataIndex="LatestEstimate"
OverOnly="true" Pin="true" Flex="1" Text="Latest ETA" Editor="true">
<Renderer Format="Date" FormatArgs="'m/d/y'" />
<Component>
<ext:DateField ID="LatestEstimateColumnTextField" runat="server" Format="MM/dd/yyyy"
EmptyText="Empty" />
</Component>
</ext:ComponentColumn>
<ext:ComponentColumn ID="MilestoneTypeColumn" runat="server" DataIndex="MilestoneType_ID"
OverOnly="true" Pin="true" Flex="1" Text="Milestone Type" Editor="true">
<Component>
<ext:ComboBox ID="MilestoneTypeColumnComboBox" runat="server" QueryMode="Local" Editable="false"
StoreID="MilestoneTypesStore" DisplayField="Name" ValueField="ID" EmptyText="Empty" />
</Component>
</ext:ComponentColumn>
<ext:ComponentColumn ID="EditColumn" runat="server" Width="30" PinAllColumns="false"
AutoWidthComponent="false" OverOnly="true" Text="Edit" Sortable="False">
<Component>
<ext:Button ID="EditButton" runat="server" ToolTip="Pin Editors" Icon="Pencil" AllowDepress="true"
EnableToggle="true" Width="25">
<Listeners>
<Toggle Fn="pinEditors" />
</Listeners>
</ext:Button>
</Component>
</ext:ComponentColumn>
<ext:ComponentColumn ID="DeleteColumn" runat="server" Width="30" PinAllColumns="false"
AutoWidthComponent="false" OverOnly="true" Text="Delete" Sortable="False">
<Component>
<ext:Button ID="DeleteButton" runat="server" ToolTip="Delete Milestone" Icon="Delete"
AllowDepress="true" EnableToggle="false" Width="25">
<Listeners>
<Click Handler="#{MilestonesGridStore}.remove(this.parentMenu.dataRecord)" />
</Listeners>
</ext:Button>
</Component>
</ext:ComponentColumn>
</Columns>
</ColumnModel>
<SelectionModel>
<ext:RowSelectionModel runat="server" Mode="Single">
<Listeners>
<Select Handler="#{DeleteMilestoneGridButton}.enable();" />
<Deselect Handler="if (!#{MilestonesGridPanel}.selModel.hasSelection()) {
#{DeleteMilestoneGridButton}.disable();
}" />
</Listeners>
</ext:RowSelectionModel>
</SelectionModel>
<Buttons>
<ext:Button ID="AddtoMilestoneGridButton" runat="server" Text="Insert" Icon="Add">
<Listeners>
<Click Handler="#{MilestonesGridStore}.insert(0, {}); #{MilestonesGridPanel}.editingPlugin.startEditByPosition({row:0, column:0});" />
</Listeners>
</ext:Button>
<ext:Button ID="DeleteMilestoneGridButton" runat="server" Text="Delete" Icon="Delete"
Disabled="true">
<Listeners>
<Click Handler="#{MilestonesGridPanel}.deleteSelected();
if (!#{MilestonesGridPanel}.hasSelection()) {
#{DeleteMilestoneGridButton}.disable();
}" />
</Listeners>
</ext:Button>
<ext:Button ID="RefreshMilestonesGridButton" runat="server" Text="RefresH" Icon="Reload">
<Listeners>
<Click Handler="#{MilestonesGridStore}.load();" />
</Listeners>
</ext:Button>
<ext:Button ID="SaveMilestoneGridButton" runat="server" Text="Save" Icon="Disk">
<Listeners>
<Click Handler="#{MilestonesGridStore}.sync();" />
</Listeners>
</ext:Button>
</Buttons>
</ext:GridPanel>

Resources