Sencha touch selectfield works fine in chrome, but it fails in android 2.1 emulator and Android 2.2 phone - google-chrome

I am learning Sencha Touch. I am having a strange issue. A view using select field is not showing it on Android emulator, but it does in Google Chrome. It worked fine before, I cannot guess what changed to "break" it.
In the emulator logcat I can see these three messages:
E/ActivityThread(243): Failed to find provider info for android.server.checkin
W/Checkin(243): Can't update stat BROWSER_SNAP_CENTER: java.lang.IllegalArgumentException: Unknown URL content://android.server.checkin/stats
D/CordovaLog(243): undefined: Line 1 : TypeError: Result of expression 'c' [null] is not a constructor.
Sometimes only the third is shown.
Hereafter the view code:
(function() {
var setSettingValue = function(component, query, value) {
var c = component.query(query);
if (c && value && (c.length > 0)) {
c[0].setValue(value);
}
};
var createToolbar = function () {
return Ext.create('Ext.Toolbar', {
xtype: 'toolbar',
docked: 'bottom',
layout: { pack: 'center' },
items: [
{
iconMask: true, ui: 'normal', iconCls: 'info',
itemId: 'infoButton'
},
{ xtype: 'spacer' },
{
iconMask: true, ui: 'normal', iconCls: 'reply',
itemId: 'backButton'
}
]
})};
Ext.define('MyWF.view.Settings', {
extend: 'Ext.Container',
initialize: function ()
{
this.setItems([createToolbar()]);
this.callParent();
},
config : {
layout : 'vbox',
padding : '0 10',
scrollable: {
direction: 'vertical'
},
onBackAction: function () { console.log('back'); },
onInfoAction: function () { console.log('info'); },
listeners: [{
delegate: "#backButton",
event: 'tap',
fn: 'onBackAction'
},
{
delegate: "#infoButton",
event: 'tap',
fn: 'onInfoAction'
},
{
event: 'show',
fn: function(component, eOpts) {
setSettingValue(component, 'selectfield[name=windMU]','kmh');
setSettingValue(component,'selectfield[name=temperatureMU]','C');
}
}],
items : [{
xtype : 'fieldset',
title : 'Measure units',
items : [{
xtype : 'selectfield',
name : 'temperatureMU',
label : 'Temperature',
labelAlign: 'top',
listeners : {
change : function(selectField, newData, oldData, eOpts) {
alert('Your choice is: ' + newData);
}
},
options : [{
text : 'Celsius',
value : 'C'
}, {
text : 'Farenheit',
value : 'F'
},]
}, {
xtype : 'selectfield',
name : 'windMU',
label : 'Wind speed',
labelAlign : 'top',
listeners : {
change : function(selectField, newData, oldData, eOpts) {
alert('Your choice is: ' + newData);
}
},
options : [{
text : 'Kilometers per hour',
value : 'km/h'
}, {
text : 'Meters per second',
value : 'm/s'
}, {
text : 'Miles per hour',
value : 'MPH'
}, {
text : 'Knots',
value : 'kn'
}]
}]
},]
}
});
})();
Thanks for any suggestion

Well I got some time to fix the issue.
First of all I add a lacking information to the question: I was running the app with a custom build of the Sencha Touch library, the library version is 2.0.1.1.
On Google Chrome the select field (Ext.field.Select) creates by default an Ext.dataview.List instance for the list of choiches, while on a phone an Ext.picker.Picker is created.
But Ext.picker.Picker also creates an Ext.TitleBar, that was lacking in my custom build of sencha library, while the Ext.dataview.List class is in.
So the application can show the select field in Chrome, but it cannot in the emulator, and it gives the unclear message, because the libary build is compressed and obfuscated.
There are two solutions:
you can force the use of a list also in the emulator or phone. The class Ext.picker.Picker has a creation option for this: "usePicker: false", by default set to "auto".
or, better, add an explicit reference to the title bar component in the app file: "Ext.require('Ext.TitleBar');" to include it in the library build.
I saw the problem forcing the use of the picker in Chrome, by setting the picker configuration "usePicker: true", and running the app with the debug library build "sencha-touch-debug.js", see http://docs.sencha.com/touch/2-0/#!/api/Ext.Loader, and http://docs.sencha.com/touch/2-0/#!/guide/building .
Then in the Chrome console, as well in the Android emulator logcat, I saw the clear message:
[WARN][Anonymous] [Ext.Loader] Synchronously loading 'Ext.TitleBar';
consider adding 'Ext.TitleBar' explicitly as a require of the corresponding class
A suggestion: in the logcat is better to filter the many messages, for example writing "Ext.Loader" in the filter mask.

Related

JQgrid - cannot get output from Json where value of array is Object, Object

I have 2 applications that use the free version of jqgrid.
The one that works has a Json array as follows;
Notice the value of data is [...]
For the application where the data does not get rendered;
Notice the value of data is NOT [...]. So what do I need to do to the data to get it in the correct format so that it will render?
EDIT
I think the data issue I raised originally was mistaken.
I have a jsFiddle of what I want and it works, see
https://jsfiddle.net/arame/cxh7zh3a/
But my code in my .Net MVC application does not. The grid is displayed with headers, but the data rows are not rendered.
var populateGrid = function (data) {
var grid = $("#grid");
grid.jqGrid({
data: data,
colNames: ["Contract No", "Title", ""],
colModel: [
{ name: "FullContractNo", label: "FullContractNo", width: 80, align: "center" },
{ name: "ContractTitle", label: "ContractTitle", width: 400, searchoptions: { sopt: ["cn"] } },
{ name: "Link", label: "Link", search: false, align: "center" }
],
cmTemplate: { width: 100, autoResizable: true },
rowNum: 20,
pager: "#pager",
shrinkToFit: false,
rownumbers: true,
sortname: "FullContractNo",
viewrecords: true
});
grid.jqGrid("filterToolbar", {
beforeSearch: function () {
return false; // allow filtering
}
}).jqGrid("gridResize");
$("#divLoading").hide();
}
var getGrid = function () {
var url = GetHiddenField("sir-get-selected-contract-list");
var callback = populateGrid;
dataService.getList(url, callback);
}
getGrid();
The code is a little different to the JsFiddle as the data is extracted from a Web API.
The data is correct however, as I put a breakpoint in and check it.
See
I have found the answer! I feel daft posting this, but for some reason I cannot fathom I had an old version of the jqGrid library. I had version 4.7 and the current version is 4.14.
With the right version it is now working.

Why is my JSON showing up in Kendo UI as Datasource.options.data but not Datasource.data?

New to Kendo and I'm having a tough time getting my JSON data to display in the Kendo Grid. If i reference my $scope.actionData through a normal html table, i'm able to view it in the page.
Ultimately I'm trying to accomplish this
The column headers display on the page, but no data beneath them.
When I'm attempting to populate the kendo grid, I can see the data I'm expecting through the Chrome Kendo UI Inspector in the DataSource -> Options -> Data Array, but I can't figure out how to get it to display on the page, and it's not populating the DataSource -> Data array. I've tried working through the examples on the angular-kendo page, but no luck. I've also tried adding various elements/tags under the div in the html, but I'm back where I started.
Let me know if I need to add anything else. Any assistance getting this to populate is greatly appreciated. Thanks in advance!
HTML:
<div kendo-grid k-data-source="gridOptions"></div>
Controller:
var actionHistoryControllers = angular.module('actionHistoryControllers', ['kendo.directives'])
.controller('ActionHistoryCtrl', ['$scope', '$routeParams', 'ActionHistory',
function ($scope, $routeParams, ActionHistory) {
$scope.actionData = ActionHistory.query({ appid: $routeParams.appid },
function (data) {
$scope.error = false;
$scope.errorMsg = "";
},
function (data) {
$scope.error = true;
$scope.errorMsg = "<strong>Unable to load!</strong> Please reload the page.";
});
$scope.gridOptions = {
data: $scope.actionData,
columns: [
{field: "UserID", title: "User ID"},
{field: "ActionText", title: "Action Text"}]
}
}])
Chrome Kendo UI Inspector:
Data source
options: Object{9}
data: Array[3]
0: Object{17}
ActionHistoryID: 315911
ActionText: "System"
...
Please replace the following:
$scope.gridOptions = {
data: $scope.actionData,
columns: [
{field: "UserID", title: "User ID"},
{field: "ActionText", title: "Action Text"}]
}
with the following:
$scope.gridOptions = {
dataSource: {
transport: {
read: function (o) {
o.success($scope.actionData);
}
},
columns: [
{field: "UserID", title: "User ID"},
{field: "ActionText", title: "Action Text"}]
}
}

Current location in sencha touch

I am using the following code to display my current location on Sencha Touch 2. Its showing the correct latitude in console.log() but not showing the map. Please help.
Ext.define('restApp.view.GreetingView', {
extend: 'Ext.Map',
alias: 'widget.mymap',
config: {
fullscreen: true,
//tpl: '<p>The ID is {uuid}</p><p>The content is {display}</p>',
layout: {
type: 'fit'
}
},
initialize:function(){
Ext.Viewport.add({
xtype: 'map',
id:'geomap',
itemId:'ma'
});
var geo = Ext.create('Ext.util.Geolocation', {
autoUpdate: true,
frequency: '10000',
listeners: {
locationupdate: function (geo) {
var center = new google.maps.LatLng(geo.getLatitude(), geo.getLongitude());
Ext.getCmp('geomap').setData(center);
//restApp.view.GreetingView.getComponent('ma').update(center);
var marker = new google.maps.Marker({
position: center,
map: Ext.getCmp('geomap').map
});
console.log('New latitude: '+ geo.getLatitude());
},
locationerror: function (geo, bTimeout, bPermissionDenied, bLocationUnavailable, message) {
if (bTimeout) {
alert('Timeout occurred.');
}
else {
alert('Error occurred.');
}
}
}
});
}
});
OLD ANSWER
Comparing it to a snippet I use for the same purpose (shown below), I realised the issue is a simple one. "center" is a reserved word. Try using a different variable name.
PART OF EDIT: removal of code snippets.
NEW ANSWER
I looked around and noticed your "project" is but a piecemeal collection of demo code.
Here's a complete code solution, with all excess pieces removed for simplicity, as well as over use of variables, also expanded to a longwinded format to be obvious.
/*
The application, including a simple launcher.
*/
Ext.application({
requires : ['Ext.device.Geolocation'],
views : ['MainView'],
controllers : ['Maps'],
name : 'Geo',
launch: function() {
Ext.create('Geo.view.MainView', {fullscreen: true});
}
});
/*
The View to display the map, as well as how to include the navigation bar
and include a "you are here" button.
*/
Ext.define('Geo.view.MainView', {
extend: 'Ext.navigation.View',
alias: 'widget.mainview',
requires: [
'Ext.Panel',
'Ext.Map',
'Ext.navigation.Bar',
'Ext.Button'
],
config: {
items: [
{
xtype : 'panel',
title : 'Map',
itemId : 'mapPanel',
items : [
{
xtype: 'map',
height: '100%',
itemId: 'map'
}
]
}
],
navigationBar: {
docked: 'top',
items: [
{
xtype: 'button',
itemId: 'youAreHereButton',
text: 'You Are Here'
}
]
}
}
});
/*
The Controller with functionality for the "you are here" button tap
*/
Ext.define('Geo.controller.Maps', {
extend: 'Ext.app.Controller',
config: {
refs: {
mapView: {
selector: 'mainview #map',
xtype: 'Ext.Map'
},
mainView: {
selector: 'mainview',
xtype: 'Ext.navigation.View'
}
},
control: {
"mainview #youAreHereButton": {
tap: 'onYouAreHereTap'
}
}
},
onYouAreHereTap: function(button, e, eOpts) {
// set 'mapView' as the parent view displaying the map
var mapView = this.getMapView();
// control measure for old browsers or denied permission for location detection.
if (Ext.feature.has.Geolocation) {
/*
Ext.device.Geolocation uses native (phone) Geolocation capabilities if available,
and falls back to Ext.util.Geolocation if only browser support detected.
*/
Ext.device.Geolocation.getCurrentPosition({
allowHighAccuracy : true,
maximumAge : 0,
timeout : 20000,
success : function(position) {
var latitude = position.coords.latitude,
longitude = position.coords.longitude,
location = new google.maps.LatLng(latitude, longitude),
marker = new google.maps.Marker({
position : location,
map : mapView.getMap(),
animation : google.maps.Animation.DROP
});
mapView.setMapOptions({ // Move to the center
center: location
});
},
failure: function() {
console.log('something went wrong!');
}
});
}
}
});
Yes, I could have simplified it further down to a single view, containing also the controller's handler for the "you are here" tap. I have chosen to present it this way to assist you with understanding the MVC pattern and how it applies in Sencha Touch.
For this to work, it'll require the Sencha Touch library, as well as this following line:
<script src="http://maps.google.com/maps/api/js?sensor=true"></script>
This is the script which includes Google Maps in your page and is essential for displaying.
Learn more:
https://www.sencha.com/learn/hello-world/ - getting started
http://docs.sencha.com/touch/2.3.1/#!/guide - complete documentation for how to do anything in Sencha Touch, starting with the Guides page.

Pass selectfield value to listener function

I have a listener in a view, which detects a change in a selectfield.
This is the selectfield:
{
xtype : 'selectfield',
store : companiesStore2,
name : 'companies',
id : 'companiesSelect',
itemId: 'companySelect',
valueField : 'companyname',
displayField : 'companyname',
},
And the listener:
listeners: [{
delegate: '#companySelect',
event: 'change',
fn: 'onGetStatsCommand'
}],
onGetStatsCommand: function () {
this.fireEvent('onGetStatsCommand');
},
The function that fires is in the controller and looks like this:
onGetStatsCommand: function () {
alert('HERE WE GO')
},
This all works fine, but, what I need to do is pass the value of the selected item to the onGetStatsCommand function.
How do I do this?
I'm not sure about the syntax, but if my intuition serves me right, it should be :
this.fireEvent('onGetStatsCommand',Ext.getCmp('companiesSelect').getValue());
onGetStatsCommand: function (val) {
alert(val)
}

Overriding default parameter names in ExtJS 4 Store

I'm trying to override the default parameter name for limitParam in proxy for the Store. I want to make a JSONP call to http://search.twitter.com/search.json?q=kathmandu&rpp=2 but instead of setting rpp directly I want to map it to limitParam and set it's value. But it's not setting through limitParam. The reason I'm doing is the parameter keys store sends (sort, dir, etc) do not match the parameters on the server side (which I've no control over). Thanks in advance.
Ext.require('Ext.grid.View');
Ext.require('Ext.util.Point');
Ext.application({
name: 'HelloExt',
launch: function() {
/*Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: [
{
title: 'Hello Ext',
html : 'Hello! Welcome to Ext JS.'
}
]
});*/
console.log('ok1');
Ext.define('Video', {
extend: 'Ext.data.Model',
fields: ['from_user', 'from_user_id']
});
var myStore2 = Ext.create('Ext.data.Store', {
model: 'Video',
storeId : 'restfulStore',
proxy: {
type: 'jsonp',
url : 'http://search.twitter.com/search.json?q=kathmandu',
reader: {
type: 'json',
//root: 'data.items'
root: 'results'
},
limitParam: 'rpp',
pageParam: 'page'
},
listeners: {
load: function(store, records) {
Ext.each(records, function(rec) {
console.log(rec.get('from_user'));
});
}
},
sorters: [{
property: 'from_user',
direction: 'DESC'
}, {
property: 'from_user_id',
direction: 'ASC'
}],
//autoLoad: true,
remoteSort: true
});
var p = myStore2.getProxy();
p.limitParam = 2;
myStore2.load();
console.log('loads anyway??? loaded the store ...');
Ext.create('Ext.grid.Panel', {
title: 'Restful Grid',
store: Ext.data.StoreManager.lookup('restfulStore'),
columns: [
{header: "From User", width: 200, sortable: true, dataIndex: 'from_user'},
{header: "From User ID", width: 200, sortable: true, dataIndex: 'from_user_id'}
],
height: 400,
width: 400,
renderTo: Ext.getBody()
});
console.log('store loaded!!');
}
});
Your proxy configuration is fine for what you want to do. The problem is in the way you load the store. You should not change limitParam which is really the config option for the name of the param. To affect the number of results, use the limit option of the load method, that you can also configure in the store with the pageSize option.
So, remove this:
var p = myStore2.getProxy();
p.limitParam = 2;
And instead, use the limit option when loading the store:
myStore2.load({
limit: 2
});
Alternatively, you can set this in the store config with the pageSize option:
Ext.create('Ext.data.Store', {
// ...
pageSize: 2
,autoLoad: true
});
You can mix both by setting a default with pageSize, and changing it at loading time with limit.
As a side note, the tweeter API doesn't seem to support sorting, so your sorters configuration won't have any effect on the returned results. You should switch remoteSort to false to have the returned results sorted on the client side according to your configuration.