Titanium: ListView load remote images - titanium

I've got the below bit of code which pull back a list of the users facebook contacts along with their profile picture, however the images are not loading for each user, it is only showing the images for a few users.
fb.requestWithGraphPath('me/friends', {
fields : 'first_name,last_name,id,installed,picture.width(120).height(120),gender'
}, 'GET', function(e) {
if (e.success) {
var d = JSON.parse(e.result);
var pData = [];
var iData = [];
var row = d.data;
row = row.sort(sortByName)
for (var i = 0; i < d.data.length; i++) {
var img = row[i].picture.data.url
if (row[i].installed) {
pData.push({
properties : {
title : row[i].first_name + " " + row[i].last_name,
id : row[i].id,
image : img,
gender : row[i].gender,
accessoryType : Ti.UI.LIST_ACCESSORY_TYPE_DISCLOSURE
},
template : Ti.UI.LIST_ITEM_TEMPLATE_DEFAULT
});
} else {
iData.push({
properties : {
title : row[i].first_name + " " + row[i].last_name,
id : row[i].id,
image : img,
accessoryType : Ti.UI.LIST_ACCESSORY_TYPE_DISCLOSURE
},
template : Ti.UI.LIST_ITEM_TEMPLATE_DEFAULT
});
}
}
var play = Ti.UI.createListSection({
headerTitle : 'Play with Facebook Friends',
items : pData
});
var invite = Ti.UI.createListSection({
headerTitle : 'Invite Facebook Friends',
items : iData
});
var listView = Ti.UI.createListView({
sections : [play, invite],
});
self.add(listView)
} else {
alert("Facebook Error");
}
})
The images are stored in var img = row[i].picture.data.url and pushed into the data array as part of image : img but not all images are loading.
Is there a way to force the images to load? and show a default image whilst they are loading?

Here is a link to complete example to do exactly what you are trying to accomplish abaove
http://www.clearlyinnovative.com/blog/post/34758524584/alloy-listview-facebook-friends#.UgexZGRATrg

Related

OL3 add backup url

I'm trying to add a backup route for a tiles with ol3. I would like to test on the errorload event if the source url starting by "http".
If "yes" : replace this tile by a custom tile.
If "no" : change the source url of this tile by another one and retry
I think i need to use something like that :
layerTile.getSource().setUrl('file:///local/{z}/{x}/{y}.jpg');
var errorTilePath='https://image.noelshack.com/fichiers/2017/14/1491403614-errortile.png';
var serverBackup='http://otile1.mqcdn.com/tiles/1.0.0/map/';
layerTile.getSource().setTileLoadFunction((function() {
var tileLoadFn = layerTile.getSource().getTileLoadFunction();
return function(tile, src) {
var image = tile.getImage();
image.onload = function() {console.log('Tile ok : ' + src); };
image.onerror = function() {
console.log('Tile error : ' + src);
console.log(tile);
if (src.substr(0,4)!='http') {
var tmp=src.split('/').reverse();
var serverBackupPath=serverBackup+tmp[2]+'/'+tmp[1]+'/'+tmp[0].split('.')[0]+'.png';
console.log("Second url : " + serverBackupPath)
src=serverBackupPath;
tile.getImage().src=src;
var image = tile.getImage();
image.onload = function() {console.log('Tile backup ok : ' + src);};
image.onerror = function() {console.log('Tile backup error : ' + src); src=errorTilePath; tile.getImage().src=src; tileLoadFn(tile, src);}
} else {
console.log('Custom tile : ');
src=errorTilePath;
tile.getImage().src=src;
}
tileLoadFn(tile, src);
};
tileLoadFn(tile, src);
};
})());
With that, I can see that the backup tile is downloaded but not visible on map.
Certainely, I misunderstood something.
Thanks in advance if somebody could help me.
Oups, without code my answer is null.
layerTile.getSource().setUrl('file:///local/{z}/{x}/{y}.jpg');
var serverBackup='https://{a-c}.tile.openstreetmap.org/';
var errorTilePath=urlBase+'css/images/error.png';
layerTile.getSource().setTileLoadFunction((function() {
return function(tile, src) {
if (UrlExists(src)) {
tile.getImage().src=src;
} else {
if (src.substr(0,4)=='file') {
var tmp=src.split('/').reverse();
src='https://'+['a', 'b', 'c'].sort(function() {return 0.5 - Math.random()})[0]+'.tile.openstreetmap.org/'+tmp[2]+'/'+tmp[1]+'/'+tmp[0].split('.')[0]+'.png';
if (UrlExists(src)) {
tile.getImage().src=src;
} else {
tile.getImage().src=errorTilePath;
}
} else {
tile.getImage().src=errorTilePath;
}
}
};
})());
function UrlExists(url){
try {
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
return http.status==200||http.status==403;
} catch(err){return false;}
}

c3.js total count in title of pie chart

I have a question about the pie chart in c3.js.
How can I add the total count of a pie chart in the title??
var title = new Array('data1.sql','data2.sql')
var dtitle = new Array('title1','title2')
var chart = new Array('chart0', 'chart1')
for(var i = 0; i < title.length; i++){
chart[i] = c3.generate({
bindto : '#chart' + i,
size: {
height: 550,
width: 800
},
data : {
url : '/json/sql/data/test/' + title[i],
mimeType : 'json',
type : 'donut'
},
donut: {
title: dtitle[i] + ' - Total:' ,
label: {
format: function(value, ratio, id) {
return value;
}
}
}
});
}
The annoying thing here is that the title option can take a function, but the chart variable is not initialised within it so using the c3 api methods can't be done at this point.
So the best (maybe only) way is to add an onrendered callback that adds up the data as you'd need to anyways and then replace the text in the chart's title text using a spot of d3:
onrendered: function () {
var data = this.api.data();
var total = data.reduce (function (subtotal, t) {
return subtotal + t.values.reduce (function (subsubtotal,b) { return subsubtotal + b.value; }, 0);
}, 0);
d3.select(this.config.bindto + " .c3-chart-arcs-title").text("Total: "+total);
}
Edit: If you want it to keep track of a total as you hide/show series use this
var data = this.api.data.shown.call (this.api);
instead of
var data = this.api.data();

Corrupt Windows in Titanium

I open windows as follows:
app.js:
var NavigationController = require('NavigationController').NavigationController,
TestWindow = require('main_windows/tmain').TestWindow;
//create NavigationController which will drive our simple application
var controller = new NavigationController();
//open initial window
controller.open(new TestWindow(controller));
function openWindow(name, naController, event) {
var TestWindow2 = require('main_windows/t' + name).TestWindow;
var win = Titanium.UI.currentWindow;
var swin = Titanium.UI.createWindow();
if(event.bid)
swin.bid = event.bid;
if(event.uniq)
swin.uniq = event.uniq;
if (event.zipcode)
swin.zipcode = event.zipcode;
if (event.user_id)
swin.user_id = event.user_id;
if (event.service_id)
swin.service_id = event.service_id;
if (event.service_name)
swin.service_name = event.service_name;
if (event.user_uniqid)
swin.user_uniqid = event.user_uniqid;
if (event.user_name)
swin.user_name = event.user_name;
if (event.user_email)
swin.user_email = event.user_email;
if (event.provider_id)
swin.provider_id = event.provider_id;
if (event.provider_name)
swin.provider_name = event.provider_name;
if (event.total)
swin.total = event.total;
if(event.response)
swin.response = event.response;
swin.backgroundColor = '#f7f7f7';
swin.barImage = 'images/example.gif';
naController.open(new TestWindow2(naController, swin));
}
Here is the NavigationController.js
exports.NavigationController = function() {
this.windowStack = [];
};
exports.NavigationController.prototype.open = function(/*Ti.UI.Window*/windowToOpen) {
//add the window to the stack of windows managed by the controller
this.windowStack.push(windowToOpen);
//alert('open' + this.windowStack.length);
//grab a copy of the current nav controller for use in the callback
var that = this;
windowToOpen.addEventListener('close', function() {
// alert('open' + that.windowStack.length);
if(that.windowStack.length > 1)
{
//alert('pop' + that.windowStack.length);
that.windowStack.pop();
}
});
//hack - setting this property ensures the window is "heavyweight" (associated with an Android activity)
windowToOpen.navBarHidden = windowToOpen.navBarHidden || false;
//This is the first window
if(this.windowStack.length === 1) {
if(Ti.Platform.osname === 'android') {
windowToOpen.exitOnClose = true;
windowToOpen.open();
} else {
//alert('nav' + this.windowStack.length);
this.navGroup = Ti.UI.iPhone.createNavigationGroup({
window : windowToOpen
});
var containerWindow = Ti.UI.createWindow();
containerWindow.add(this.navGroup);
containerWindow.open();
}
}
//All subsequent windows
else {
if(Ti.Platform.osname === 'android') {
windowToOpen.open();
} else {
//alert('nav2' + this.windowStack.length);
this.navGroup.open(windowToOpen);
}
}
};
//go back to the initial window of the NavigationController
exports.NavigationController.prototype.home = function() {
//store a copy of all the current windows on the stack
//alert('reset' + this.windowStack.length);
var windows = this.windowStack.concat([]);
for(var i = 1, l = windows.length; i < l; i++) {
(this.navGroup) ? this.navGroup.close(windows[i]) : windows[i].close();
}
this.windowStack = [this.windowStack[0]]; //reset stack
//alert('n' + this.windowStack.length);
};
Here is tmain.js
exports.TestWindow = function(navController) {
var win = Ti.UI.createWindow({
backButtonTitleImage : 'images/backb.gif',
fullscreen : false,
navBarHidden : true,
});
var t1 = null;
win.backgroundImage = 'images/back.jpg';
var view = Titanium.UI.createView({
width : '100%',
height : '100%',
top : 270,
layout : 'vertical'
});
var b3 = Titanium.UI.createImageView({
url : 'images/login.gif',
height : 80
});
view.add(b3);
var b4 = Titanium.UI.createImageView({
url : 'images/signup.gif',
top : 0,
height : 80
});
view.add(b4);
win.add(view);
var list1 = function(e) {
openWindow('login', navController, e);
};
b3.addEventListener('click', list1);
var list2 = function(e) {
openWindow('register', navController, e);
};
b4.addEventListener('click', list2);
win.addEventListener('close', function (e) {
alert(3);
b3.removeEventListener('click', list1);
b4.removeEventListener('click', list2);
});
return win;
};
So I use the openWindow function to open windows in the app. I have a logout botton, that when people click on it, calls the function navController.home() (see Navigation Controller), but the problem is clicking on the logout link causes corrupt window state - meaning that the application crashes and when you try to open it, windows are mixed together (like buttons in window 3 show up in window 2).
What am I doing wrong?

Not updating list in the panel at the run time in sencha

i have two panel. when i'm click on the left panel items its calling web service and populating the right panel and same time its updating the number of items in the right panel to the left panel item which is clicked.
for first time its updating the left panel items but when i click on the other left panel item its not updating left panel items again.
its updating only first time.
my code is:
onInboxListTap:function (dataview, index, item, record) {
console.log('Inside onInboxListTap function');
var queuestore = dataview.getStore();
var rec = queuestore.getAt(index);
console.log(rec.data.workSetName);
var store = Ext.getStore('InboxWorkitemStore');
store.clearData(); //Function To clear WorkitemStore
//creating object of InboxQueueServices class
var inboxQueueServiceObject =
Ext.create('InfoImage.common.services.InboxQueueServices', {
config:{
scope:this
}
}, this.onQueueContentRetrievalSuccess, this.onQueueContentRetrievalFailure());
// calling loadQueueContent function to load queue contents
inboxQueueServiceObject.loadQueueContent(rec.data.workSetName);
},
//To call Function onQueueContentRetrievalSuccess after loadQueueContent successful
onQueueContentRetrievalSuccess:function () {
console.log('Inside onQueueContent Retrieval Success function');
var store = Ext.getStore('InboxWorkitemStore');
//Getting componenet queueDetails list
var inboxWorkitemList = Ext.getCmp('inboxWorkitemList');
var queueDetails = Ext.getCmp('queueDetails');
var queueList = Ext.getCmp('queuelist'); //Getting component list
var queueViewPanel = Ext.getCmp('queueViewPanel'); //Getting queueViewPanel
queueDetails.setStore(store);
store.sync();
var queueCount = store.getCount();
if (queueCount > 0) {
var queueItem = store.getAt(0);
var queueStore = queueList.getStore();
queueStore.each(function (record) {
if (record.get('workSetName') == queueItem.get('sourceWorkstep')) {
record.data.queueName = queueItem.get('sourceWorkstep') + '(' +
queueCount + ')';
}
});
queueList.setStore(queueStore);
queueStore.sync();
queueList.getStore().each(function (record) {
console.log('queueList:' + record.data.queueName);
});
console.log('store UPDATED');
}
queueList.refresh();
console.log('store count: ' + store.getCount());
console.log(queueDetails);
// navigates the panel
queueViewPanel.animateActiveItem(
inboxWorkitemList, {
type:'slide',
direction:'up',
duration:250
});
},
Please help me on this isssue.
i have to set record for that i resolve it.
queueStore.each(function (record) {
if (record.get('workSetName') == workitem.get('sourceWorkset')) {
record.data.queueName = workitem.get('sourceWorkset')
+ '(' + queueCount + ')';
// queueStore.updateRecord(record.data.queueName);
record.set(record.data.queueName);
}
});

Titanium: Picker crashes with remote data

I am trying to fill remote data into picker, but it crashes.
here is the code:
var countryDataArray = [];
var picker_country = Ti.UI.createPicker
({
bottom:'-251dp'
});
win.add(picker_country);
getCountryList(); //to call web service
//Gets country list from the server
function getCountryList()
{
getCountry.onload = function()
{
var jsonString = JSON.parse(this.responseText);
var msg = jsonString.Message;
var success = jsonString.IsSuccess;
countryDataArray = jsonString.dsetData.CountryList;
Ti.API.log('countryList value:'+countryDataArray);
activity.hide();
if(countryDataArray.length > 0)
{
for (var i=0; i < countryDataArray.length ; i++)
{
data[i] = Ti.UI.createPickerRow(
{
title:countryDataArray[i].Name,
country_id:countryDataArray[i].ID,
fontSize:18
});
};
}
picker_country.add(data);
}
what's wrong with this code ? code works fine with static data !!!
static data :-
var data = [
{title:'Bananas',custom_item:'b',fontSize:18},
{title:'Strawberries',custom_item:'s',fontSize:20},
{title:'Mangos',custom_item:'m',fontSize:22,selected:true},
{title:'Grapes',custom_item:'g',fontSize:24}
];
Solved !!! I Don't why but I just assign the data to picker before adding the picker into the view and it get solved !
picker_country.add(data);
win.add(picker_country);