Sencha Touch - how to re-initialize a map view from a controller - sencha-touch

I would like to re-initialize my map view after a certain action performed in the controller.
This is my mapview:
Ext.define("App.view.MapView", {
extend: 'Ext.Container',
requires: [
'Ext.device.Geolocation',
'Ext.MessageBox'
],
xtype: 'mapview',
constructor: function () {
this.callParent(arguments);
this.element.setVisibilityMode(Ext.Element.OFFSETS);
this.on('painted', this.renderMap, this);
},
renderMap: function(){
var me = this,
lat = localStorage.getItem('latitude'),
lng = localStorage.getItem('longitude'),
geo = [lat, lng];
var map = L.map('map', {
center: geo,
zoom: 13
});
var layer = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
var marker = L.marker(geo, {
draggable: true,
title: 'Your position'
}).addTo(map);
}
});
How do I get and reset(re-initialize) my map view? I tried to make a reference to the mapview in the controller:
config: {
refs: {
mapCmp: 'mapview',
},
And then called it like this:
this.getApplication().getMapCmp.reset();
But it didn't work - I got 'function is undefined'. Basically I need it to initialize again like when the app starts up.
Please advise.

You get function is undefined message because the reset() function is not defined in your view.
However, if you want to initialize the MapView, you need to use the initialize() function. Add it in your file:
Ext.define("App.view.MapView", {
extend: 'Ext.Container',
requires: [
'Ext.device.Geolocation',
'Ext.MessageBox'
],
xtype: 'mapview',
constructor: function () {
this.callParent(arguments);
this.element.setVisibilityMode(Ext.Element.OFFSETS);
this.on('painted', this.renderMap, this);
},
initialize: function() {
// This function is launched each time the application starts up
}
renderMap: function(){
var me = this,
lat = localStorage.getItem('latitude'),
lng = localStorage.getItem('longitude'),
geo = [lat, lng];
var map = L.map('map', {
center: geo,
zoom: 13
});
var layer = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
var marker = L.marker(geo, {
draggable: true,
title: 'Your position'
}).addTo(map);
},
});

Related

Using a custom Drop Down List field to set a value in a grid

I'm trying to use the Rally 2.1 SDK to set a custom data field (c_wsjf) in a grid. I have a custom drop down list that I want to check the value of (c_TimeCrticalitySizing).
I created c_TimeCrticalitySizing as a feature card field in my Rally workspace with different string values (such as "No decay"). Every drop down list value will set the custom field to a different integer. When I try to run the app in Rally I get this error:
"Uncaught TypeError: Cannot read property 'isModel' of undefined(…)"
I'm thinking the drop down list value may not be a string.
How would I check what the type of the drop down list value is?
How could I rewrite this code to correctly check the value of the drop down list so I can set my custom field to different integers?
Here's my code block for the complete app. I'm still trying to hook up a search bar so for now I directly call _onDataLoaded() from the launch() function.
// START OF APP CODE
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
featureStore: undefined,
featureGrid: undefined,
items: [ // pre-define the general layout of the app; the skeleton (ie. header, content, footer)
{
xtype: 'container', // this container lets us control the layout of the pulldowns; they'll be added below
itemId: 'widget-container',
layout: {
type: 'hbox', // 'horizontal' layout
align: 'stretch'
}
}
],
// Entry point of the app
launch: function() {
var me = this;
me._onDataLoaded();
},
_loadSearchBar: function() {
console.log('in loadsearchbar');
var me = this;
var searchComboBox = Ext.create('Rally.ui.combobox.SearchComboBox', {
itemId: 'search-combobox',
storeConfig: {
model: 'PortfolioItem/Feature'
},
listeners: {
ready: me._onDataLoaded,
select: me._onDataLoaded,
scope: me
}
});
// using 'me' here would add the combo box to the app, not the widget container
this.down('#widget-container').add(searchComboBox); // add the search field to the widget container <this>
},
// If adding more filters to the grid later, add them here
_getFilters: function(searchValue){
var searchFilter = Ext.create('Rally.data.wsapi.Filter', {
property: 'Search',
operation: '=',
value: searchValue
});
return searchFilter;
},
// Sets values once data from store is retrieved
_onDataLoaded: function() {
console.log('in ondataloaded');
var me = this;
// look up what the user input was from the search box
console.log("combobox: ", this.down('#search-combobox'));
//var typedSearch = this.down('#search-combobox').getRecord().get('_ref');
// search filter to apply
//var myFilters = this._getFilters(typedSearch);
// if the store exists, load new data
if (me.featureStore) {
//me.featureStore.setFilter(myFilters);
me.featureStore.load();
}
// if not, create it
else {
me.featureStore = Ext.create('Rally.data.wsapi.Store', {
model: 'PortfolioItem/Feature',
autoLoad: true,
listeners: {
load: me._createGrid,
scope: me
},
fetch: ['FormattedID', 'Name', 'TimeCriticality',
'RROEValue', 'UserBusinessValue', 'JobSize', 'c_TimeCriticalitySizing']
});
}
},
// create a grid with a custom store
_createGrid: function(store, data){
var me = this;
var records = _.map(data, function(record) {
//Calculations, etc.
console.log(record.get('c_TimeCriticalitySizing'));
var timecritsize = record.get('c_TimeCriticalitySizing');
//console.log(typeof timecritsize);
var mystr = "No decay";
var jobsize = record.get('JobSize');
var rroe = record.get('RROEValue');
var userval = record.get('UserBusinessValue');
var timecrit = record.get('TimeCriticality');
// Check that demoniator is not 0
if ( record.get('JobSize') > 0){
if (timecritsize === mystr){
var priorityScore = (timecrit + userval + rroe) / jobsize;
return Ext.apply({
c_wsjf: Math.round(priorityScore * 10) / 10
}, record.getData());
}
}
else{
return Ext.apply({
c_wsjf: 0
}, record.getData());
}
});
// Add the grid
me.add({
xtype: 'rallygrid',
showPagingToolbar: true,
showRowActionsColumn: true,
enableEditing: true,
store: Ext.create('Rally.data.custom.Store', {
data: records
}),
// Configure each column
columnCfgs: [
{
xtype: 'templatecolumn',
text: 'ID',
dataIndex: 'FormattedID',
width: 100,
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
},
{
text: 'WSJF Score',
dataIndex: 'c_wsjf',
width: 150
},
{
text: 'Name',
dataIndex: 'Name',
flex: 1,
width: 100
}
]
});
}
});
// END OF APP CODE
The app works great until I add the if (timecritsize === mystr) conditional.
I also use console.log() to check that I've set all values for timecritsize to "No decay"

List doesn't show after android native build application

I have Ext.dataview.List, I successfully can see it in my browser. But after buildind my application for android list and it's title doesn't shown. I tried almost everything but noghing helps.
Here is my code:
MenuTabPanel.js:
Ext.define('App.view.MenuTabPanel', {
extend: 'Ext.tab.Panel',
xtype: 'menutb',
requires: [
'Ext.TitleBar',
'Ext.dataview.List'
],
config: {
tabBarPosition: 'bottom',
fullscreen : true,
id: 'menuTabPanel',
//layout: 'fit',
listeners: {
painted : function(element, eOpts) {
if(this.getActiveItem()) {
var title = this.getActiveItem().child('[xtype=list]').title;
var navBar = Ext.getCmp('navMenu').getNavigationBar();
navBar.setTitle(title);
}
}
}
},
initialize: function() {
var content = [];
//var menuStore = Ext.getStore('menuItemsStore');
var menuStore = Ext.create('App.store.MenuItemsStore');
var onMenuItemClicked = function(list, index, node,record){
var navigateTo = Ext.create('App.view.' + record.get('Id') + 'View');
var navMenu = Ext.getCmp('navMenu');
navMenu.push(navigateTo);
};
var tabPanel = this;
var onStoreLoad = function(){
menuStore.filter("Level",1);
menuStore.each(function(record) {
var tabItem = {};
var items = {};
tabItem['iconCls'] = record.get('Id');
tabItem['layout'] = 'fit';
items['id'] = record.get('Id');
items['title'] = record.get('Title');
items['xtype'] = 'list';
items['height'] = '100%';
items['width'] = '100%';
//items['layout'] = 'vbox';
//items['flex'] = 1;
items['itemTpl'] = '<div class="menuitem-text"><img src="../resources/icons/{Id}.png" /> {Title}</div>';
//items['store'] = Ext.getStore('menuItemsStore');
var listen = {};
listen['itemtap'] = onMenuItemClicked;
items['listeners'] = listen;
tabItem['items'] = [items];
content.push(tabItem);
}
);
tabPanel.add(content);
}
menuStore.load(onStoreLoad);
this.callParent(arguments);
}
});
MenuController.js:
Ext.define('App.controller.MenuController', {
extend: 'Ext.app.Controller',
requires: [
'Ext.dataview.List'
],
config: {
control: {
"menutb": {
activeitemchange: 'onTabPanelActiveItemChange'
}
}
},
onTabPanelActiveItemChange: function(othis, value, oldValue, eOpts) {
var list = value.child('[xtype=list]');
var mainStore = Ext.getStore('menuItemsStore');
var results = mainStore.queryBy(function(rec){
if(rec.get('Level') == 2 && rec.get('Parent') == list.title)
return true;
});
var data1 = Ext.Array.pluck(results.getRange(), 'data');
list.setStore({
model: 'Mobile.model.MenuItem',
data: data1
});
var navBar = othis.getParent().getNavigationBar();
navBar.setTitle(list.title);
}
});
MenuView.js:
Ext.define('App.view.MenuView', {
extend: 'Ext.NavigationView',
xtype: 'menu',
requires: [
'Ext.TitleBar',
'Ext.dataview.List',
'App.view.MenuTabPanel'
],
config: {
id: 'navMenu',
items: [{
xtype: 'menutb'
}
]
}
});
My app starts from MenuView.js.
What I am doing wrong or what I miss? Or maybe it is problem in android with Lists?
Edited:
I find out that there is some problem with activeitemchange event, it fires after initialize. When I commented this event list normally is shown on android. Also when I don't load store and write manually data, the event fires normally.

ExtJs 4: How do I create a dynamic menu?

I have a menu system set up in a panel which needs to be dynamically created. I have created a mock static menu which the client likes but the menu categories and items will need to be loaded via JSON from a store.
Here is what I have for the first few menu items set statically:
Ext.define('SimpleSearch.view.FacetSDL' ,{
extend: 'Ext.panel.Panel',
alias : 'widget.facetsdl', //alias is referenced in MasterList.js
requires: ['SimpleSearch.store.SDLResults', 'FacetData' ],
title: 'Facet Search',
html: null,
frame: true,
layouts: 'fit',
items: [
{
id: 'group-menu',
title: 'Browse',
xtype: 'menu',
plain: true,
floating: false,
layouts: 'fit',
items: [
{
text: 'Security',
listeners:
{
click: function() {
var groupmenu = Ext.ComponentQuery.query('#group-menu')[0];
groupmenu.hide()
var securitymenu = Ext.ComponentQuery.query('#security-menu')[0];
securitymenu.setPosition(0,-groupmenu.getHeight(),false);
securitymenu.show()
}
},
menu: { // <-- submenu by nested config object
items: [
{
text: 'Classification',
listeners:
{
click: function() {
var groupmenu = Ext.ComponentQuery.query('#group-menu')[0];
groupmenu.hide()
var securitymenu = Ext.ComponentQuery.query('#security-menu')[0];
var classificationmenu = Ext.ComponentQuery.query('#classification-menu')[0];
classificationmenu.setPosition(0,-groupmenu.getHeight() - securitymenu.getHeight(),false);
classificationmenu.show()
}
I was thinking that maybe creating a class that loads all of the necessary data and then iterating through that class for the "items" field may be the way to go, but I am not sure if that will work.
You should look at using a Tree and TreeStore. Then make use of the ui:'menu' or viewConfig { ui: 'menu' } config properties to differentiate it from a regular tree. Then style it however your client wants.
This way you have all the mechanisms in place for free to handle the data dynamically and all your submenus, you'll just have to get a little creative on the CSS side of things.
I got it working like this:
var scrollMenu = Ext.create('Ext.menu.Menu');
for (var i = 0; i < store.getCount(); ++i){
var rec = store.getAt(i);
var item = new Ext.menu.Item({
text: rec.data.DISPLAY_FIELD,
value:rec.data.VALUE_FIELD,
icon: 'js/images/add.png',
handler: function(item){
myFunction(item.value); //Handle the item click
}
});
scrollMenu.add(item);
}
Then just add scrollMenu to your form or container. Hope this helps!
This menu is created dynamically with ExtJs, the data is loaded from Json.
See my demo with the code.
Demo Online:
https://fiddle.sencha.com/#view/editor&fiddle/2vcq
Json loaded:
https://api.myjson.com/bins/1d9tdd
Code ExtJs:
//Description: ExtJs - Create a dynamical menu from JSON
//Autor: Ronny Morán <ronney41#gmail.com>
Ext.application({
name : 'Fiddle',
launch : function() {
var formPanelFMBtn = Ext.create('Ext.form.Panel', {
bodyPadding: 2,
waitMsgTarget: true,
fieldDefaults: {
labelAlign: 'left',
labelWidth: 85,
msgTarget: 'side'
},
items: [
{
xtype: 'container',
layout: 'hbox',
items: [
]
}
]
});
var win = Ext.create('Ext.window.Window', {
title: 'EXTJS DYNAMICAL MENU FROM JSON',
modal: true,
width: 680,
closable: true,
layout: 'fit',
items: [formPanelFMBtn]
}).show();
//Consuming JSON from URL using method GET
Ext.Ajax.request({
url: 'https://api.myjson.com/bins/1d9tdd',
method: 'get',
timeout: 400000,
headers: { 'Content-Type': 'application/json' },
//params : Ext.JSON.encode(dataJsonRequest),
success: function(conn, response, options, eOpts) {
var result = Ext.JSON.decode(conn.responseText);
//passing JSON data in 'result'
viewMenuDinamical(formPanelFMBtn,result);
},
failure: function(conn, response, options, eOpts) {
//Ext.Msg.alert(titleAlerta,msgErrorGetFin);
}
});
}
});
//Generate dynamical menu with data from JSON
//Params: formPanelFMBtn - > Panel
// result - > Json data
function viewMenuDinamical(formPanelFMBtn,result){
var resultFinTarea = result;
var arrayCategoriaTareas = resultFinTarea.categoriaTareas;
var containerFinTarea = Ext.create('Ext.form.FieldSet', {
xtype: 'fieldset',
title: 'Menu:',
margins:'0 0 5 0',
flex:1,
layout: 'anchor',
//autoHeight: true,
autoScroll: true,
height: 200,
align: 'stretch',
items: [
]
});
var arrayMenu1 = [];
//LEVEL 1
for(var i = 0; i < arrayCategoriaTareas.length; i++)
{
var categoriaPadre = arrayCategoriaTareas[i];
var nombrePadre = categoriaPadre.nombreCategoria;
var hijosPadre = categoriaPadre.hijosCategoria;
var arrayMenu2 = [];
//LEVEL 2
for(var j = 0; j<hijosPadre.length; j++)
{
var categoriaHijo = hijosPadre[j];
var nombreHijo = categoriaHijo.nombreHijo;
var listaTareas = categoriaHijo.listaTareas;
var arrayMenu3 = [];
//LEVEL 3
for(var k = 0; k < listaTareas.length; k++)
{
var tarea = listaTareas[k];
var nombreTarea = tarea.nombreTarea;
var objFinLTres =
{
text: nombreTarea,
handler: function () {
alert("CLICK XD");
}
};
arrayMenu3.push(objFinLTres);
}
var menuLevel3 = Ext.create('Ext.menu.Menu', {
items: arrayMenu3
});
var objFinLDos;
if(arrayMenu3.length > 0)
{
objFinLDos = {
text: nombreHijo,
menu:menuLevel3
};
}
else
{
//without menu parameter If don't have children
objFinLDos = {
text: nombreHijo
};
}
arrayMenu2.push(objFinLDos);
}
var menuLevel2 = Ext.create('Ext.menu.Menu', {
items: arrayMenu2
});
var objFinLUno;
if(arrayMenu2.length > 0)
{
objFinLUno = {
text: nombrePadre,
menu:menuLevel2
};
}
else
{
//without menu parameter If don't have children
objFinLUno = {
text: nombrePadre
};
}
arrayMenu1.push(objFinLUno);
}
var mymenu = new Ext.menu.Menu({
items: arrayMenu1
});
containerFinTarea.add({
xtype: 'splitbutton',
text: 'Example xD',
menu: mymenu
});
formPanelFMBtn.add(containerFinTarea);
}

Sencha Touch 2 Get Current Location on Button Click

I have a toolbar button which when clicked should update my map to my current location. I am unable to find a working example of this functionality and hoping someone can advise me. Please see below for sample code - thanks for your help
Map:
Ext.define('MyApp.view.Myap', {
extend: 'Ext.Map',
alias: 'widget.mymap',
config: {
useCurrentLocation: false,
mapOptions:{
zoom: 9,
center: new google.maps.LatLng(42.2, -72.5),
mapTypeId: google.maps.MapTypeId.ROADMAP
},
listeners: {
maprender : function(comp, map){
google.maps.event.addListenerOnce(map, "idle", function () {
var host = window.location.origin ? window.location.origin : window.location.protocol + "/" + window.location.host;
var kmlOptions = {preserveViewport: false}
var now = +new Date();
var layer = new google.maps.KmlLayer(host + '/path/to.kml?timestamp=' + now, kmlOptions);
layer.setMap(map);
return layer;
});
},
}
},
})
Toolbar Button:
Ext.define('MyApp.view.btnLocateMe', {
extend: 'Ext.Button',
alias: 'widget.btnlocateme',
config: {
ui: 'normal',
iconCls: 'locate',
iconMask: true,
text: 'Locate Me',
listeners: [
{
fn: 'onButtonTap',
event: 'tap'
}
]
},
onButtonTap: function(button, e, options) {
//Produces error: cannot call method of undefined
currentLocation: new google.maps.LatLng(this._geo.getLatitude(), this._geo.getLongitude());
MyApp.view.MyMap.map.setCenter(currentLocation);
}
});
my two cents contribution, try this
1) in MyApp.view.Myap substitute
useCurrentLocation: false,
by
useCurrentLocation : {
autoUpdate : false
},
Also you should declare currentLocation as a variable (I presume)
var currentLocation = ...
This should works. I've use a similar logic as yours in onButtonTap but inside a controller with no problems
Best regards
I have one suggestion.
Try changing current location to
new google.maps.LatLng( this.geo.getLatitude(),this.geo.getLongitude() ) ;
I think you can gather more info from this question in here.
The simplest way - switch to the another map view with option useCurrentLocation: true set in the config

dynamically creating carousel using sencha touch2

I have the following sample MVC application trying to dynamically creating carousel with image source being obtained from some remote url,when i execute the application i don't see any images being appended to my carouselview,please can any one highlight where i am going wrong?
Model Code:
Ext.define('Sencha.model.ImageModel', {
extend: 'Ext.data.Model',
config: {
fields: [
'id', 'title', 'link', 'author', 'content',
{
name: 'image',
type: 'string',
convert: function (value, record) {
var content = record.get('content'),
regex = /img src=\"([a-zA-Z0-9\_\.\/\:]*)\"/,
match = content.match(regex),
src = match ? match[1] : '';
if (src != "" && !src.match(/\.gif$/)) {
src = "http://src.sencha.io/screen.width/" + src;
}
return src;
}
}
]
}
});
Store Code:
Ext.define('Sencha.store.ImageStore', {
extend: 'Ext.data.Store',
config: {
model: 'Sencha.model.ImageModel',
proxy: {
type: 'jsonp',
url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://www.acme.com/jef/apod/rss.xml&num=20',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
}
}
});
Controller Code:
Ext.define('Sencha.controller.CarouselController', {
extend: 'Ext.app.Controller',
config:
{
init: function () {
var carousel = Ext.getCmp('imagecarousel');
Ext.getStore('ImageStore').load(function (pictures) {
var items = [];
Ext.each(pictures, function (picture) {
if (!picture.get('image')) {
return;
}
items.push({
xtype: 'apodimage',
picture: picture
});
});
carousel.setItems(items);
carousel.setActiveItem(0);
});
}
}
});
View code:
Ext.define('Sencha.view.CarouselView', {
extend: 'Ext.Img',
id:'imagecarousel',
xtype: 'apodimage',
config: {
/**
* #cfg {apod.model.Picture} picture The Picture to show
*/
picture: null
},
updatePicture: function (picture) {
this.setSrc(picture.get('image'));
}
});
App.js Code:
Ext.Loader.setConfig({
enabled: true
});
Ext.require([
'Ext.carousel.Carousel',
'Ext.data.proxy.JsonP'
]);
Ext.application({
name: 'Sencha',
controllers: ['CarouselController'],
stores: ['ImageStore'],
models: ['ImageModel'],
//views:['CarouselView'],
launch: function () {
Ext.create('Sencha.view.CarouselView');
}
});
Could be more specific about what doesn't work. Try to add console.logs in your code and give us the results, like the size the items at the end end of Ext.each of stuff like that.
My first idea would be to use the callback function of store.load :
Ext.getStore('ImageStore').load(
callback: function (pictures) {
var items = [];
Ext.each(pictures, function (picture) {
if (!picture.get('image')) {
return;
}
items.push({
xtype: 'apodimage',
picture: picture
});
});
carousel.setItems(items);
carousel.setActiveItem(0);
});
Hope this helps