topener / nl.fokkezb.infinitescroll Goto Github PK
View Code? Open in Web Editor NEWAlloy widget for infinitive scrolling TableViews and ListViews
Alloy widget for infinitive scrolling TableViews and ListViews
like in the changelog 1.4.4 is now support with ticollectionview.
But I tried to add module and method as an example
<Collection src="myPhotos" id="listPhotos" instance="true" />
<Window>
<ListView id="listView" backgroundColor="white" defaultItemTemplate="template" module="de.marcelpociot.collectionview" method="createCollectionView">
<Templates>
<ItemTemplate name="template">
<View id="photo_page">
<View id="photoWrap" onClick="openPhotoDetail">
<ImageView class="photoImage" touchEnabled="false" bindId="thumb"/>
<ImageView class="photoImage" touchEnabled="false" backgroundImage="/gradient_white_black.png"/>
<Label id="photoRestName" touchEnabled="false" bindId="name"></Label>
</View>
</View>
</ItemTemplate>
</Templates>
<Widget id="listWidget" src="nl.fokkezb.infiniteScroll" onEnd="listLoader"/>
<ListSection dataCollection="$.listPhotos" module="de.marcelpociot.collectionview" method="createCollectionSection">
<ListItem thumb:image="{thumb}" name:text="{name}"/>
</ListSection>
</ListView>
</Window>
Did not return any results. Is there something wrong ?
Thaks
SDK 4.1.0.GA
[ERROR] : TiExceptionHandler: (main) [21540,58998] ----- Titanium Javascript Runtime Error -----
[ERROR] : TiExceptionHandler: (main) [0,58998] - In alloy/widgets/nl.fokkezb.infiniteScroll/controllers/widget.js:42,69
[ERROR] : TiExceptionHandler: (main) [0,58998] - Message: Uncaught TypeError: Cannot read property 'items' of undefined
[ERROR] : TiExceptionHandler: (main) [0,58998] - Source: var itemIndex = Math.max(parentSymbol.sections[sectionIndex].items.len
[ERROR] : V8Exception: Exception occurred at alloy/widgets/nl.fokkezb.infiniteScroll/controllers/widget.js:42: Uncaught TypeError: Cannot read property 'items' of undefined
scrollview hangs for 5-7 seconds after dragging, can you help me?
function myLoader(e, collection) {
var ln = collection.models.length;
collection.fetch({
// whatever your sync adapter needs to fetch the next page
//data: { offset: ln },
// don't reset the collection, but add to it
add: true,
query:"SELECT o.order_id, lower(o.status) AS status, strftime('%d/%m/%Y', o.date) AS date, o.partial_total, o.point_sale, c.name FROM orders AS o "+
"INNER JOIN customers AS c ON o.customer_id = c.customer_id ORDER BY o.date LIMIT 20 OFFSET "+ln,
success: function (col) {
// call done() when we received last page - else success()
(col.models.length === ln) ? e.done() : e.success();
},
// call error() when fetch fails
error: function(col) {
// pass optional error message to display
e.error(L('isError', 'Tap to try again...'));
}
});
}
Ive been debugging this for a long time now - at first I though the issue was with tableviews and views/labels- but it appears that I can render over 100 at once of my complex tableview row without any problems.
I run into crashes on older devices (read less memory) when I use IS in conjunction with a SQL fetch.
I initially fetch my rows:
function propertiesFetchLocation(latitude, longitude) {
Ti.API.info('propertiesFetchLocation()');
lastQuery = 'SELECT * FROM properties WHERE distance(latitude, longitude, '+ latitude +', '+ longitude +') < '+ Alloy.Globals.settings.maxDistance +' ORDER BY distance(latitude, longitude, '+ latitude +', '+ longitude +') ASC LIMIT '+ Alloy.Globals.settings.itemLimit;
properties.fetch({
query: lastQuery,
// silent: true,
success: function (col) {
Alloy.Globals.loading.hide();
if(Alloy.isTablet) {
addPins();
}
}
});
Ti.API.info('Length '+properties.models.length);
return properties.models.length;
}
with:
<TableView id="content" dataCollection="properties">
<Require src="property.row" />
<Widget id="is" src="nl.fokkezb.infiniteScroll" onEnd="myLoader" />
</TableView>
myLoader:
function myLoader(e) {
var thelength = properties.models.length;
if(thelength<Alloy.Globals.settings.itemLimit) {
return;
}
properties.fetch({
query: lastQuery + ' OFFSET '+ thelength,
add: true,
// silent: true,
success: function (col) {
(col.models.length === thelength) ? e.done() : e.success();
$.is.setOptions({
msgDone: String.format(L('isDone'), col.models.length)
});
if(Alloy.isTablet) {
addPins();
}
},
error: function(e) {
Alloy.Globals.countly.event({
name:'error'
, count:1
, segmentation:{type:'myLoader ', message:e.error}
});
}
});
}
Whilst it works, as in its able to retrieve and append results once, maybe twice- subsequent calls run into massive memory leaks and kill the app.
This has only become a problem since the Alloy 1.3.0 update- so between that and what is going on in IS something has gone amiss- I am at a loss as to what to debug next to locate the root cause further.
Is there any plan to add infinite "reverse scrolling" similar to the standard chat apps? This would be a real boon. I can't find a way to perform reverse scrolling (automatically loading the rows on top instead of bottom) that prevents the tableview or listview from automatically scrolling when a new row is inserted on top (a really undesirable behavior).
A IndexOutOfBoundsException when I move the scroll to down, testing the infiniteScroll. When I use Tap to load more is ok.
Only in Android!
My View:
<Alloy>
<View id="win" class="window">
<TableView id="clients" visible="false">
<Widget id="clientsPullToRefresh" src="nl.fokkezb.pullToRefresh" onRelease="fetchClientsPullToRefresh" />
<Widget id="clientsInfiniteScroll" src="nl.fokkezb.infiniteScroll" onEnd="fetchClientsInfiniteScroll" />
</TableView>
</View>
</Alloy>
My Controller:
...
function fetchClientsPullToRefresh(e) {
Ti.API.log("fetchClientsPullToRefresh");
page = 1;
fetchClients(e);
}
function fetchClientsInfiniteScroll(e) {
Ti.API.log("fetchClientsInfiniteScroll");
page += 1;
fetchClients(e);
}
The Exception:
10-01 18:58:53.644: E/TiApplication(13138): (main) [5633,13704] Sending event: exception on thread: main msg:java.lang.IndexOutOfBoundsException: Invalid index 10, size is 10; Titanium 3.1.1,2013/06/15 16:10,f7592c1
10-01 18:58:53.644: E/TiApplication(13138): java.lang.IndexOutOfBoundsException: Invalid index 10, size is 10
10-01 18:58:53.644: E/TiApplication(13138): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
10-01 18:58:53.644: E/TiApplication(13138): at java.util.ArrayList.get(ArrayList.java:304)
10-01 18:58:53.644: E/TiApplication(13138): at ti.modules.titanium.ui.widget.tableview.TiTableView.getItemAtPosition(TiTableView.java:411)
10-01 18:58:53.644: E/TiApplication(13138): at ti.modules.titanium.ui.TableViewProxy.fireEvent(TableViewProxy.java:163)
10-01 18:58:53.644: E/TiApplication(13138): at org.appcelerator.titanium.view.TiUIView.fireEvent(TiUIView.java:1474)
10-01 18:58:53.644: E/TiApplication(13138): at org.appcelerator.titanium.view.TiUIView.fireEvent(TiUIView.java:1465)
10-01 18:58:53.644: E/TiApplication(13138): at org.appcelerator.titanium.view.TiUIView$5.onTouch(TiUIView.java:1245)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.View.dispatchTouchEvent(View.java:5536)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1951)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1712)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
10-01 18:58:53.644: E/TiApplication(13138): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1912)
10-01 18:58:53.644: E/TiApplication(13138): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1371)
10-01 18:58:53.644: E/TiApplication(13138): at android.app.Activity.dispatchTouchEvent(Activity.java:2364)
10-01 18:58:53.644: E/TiApplication(13138): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1860)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.View.dispatchPointerEvent(View.java:5721)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:2890)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2466)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:845)
10-01 18:58:53.644: E/TiApplication(13138): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2475)
10-01 18:58:53.644: E/TiApplication(13138): at android.os.Handler.dispatchMessage(Handler.java:99)
10-01 18:58:53.644: E/TiApplication(13138): at android.os.Looper.loop(Looper.java:137)
10-01 18:58:53.644: E/TiApplication(13138): at android.app.ActivityThread.main(ActivityThread.java:4424)
10-01 18:58:53.644: E/TiApplication(13138): at java.lang.reflect.Method.invokeNative(Native Method)
10-01 18:58:53.644: E/TiApplication(13138): at java.lang.reflect.Method.invoke(Method.java:511)
10-01 18:58:53.644: E/TiApplication(13138): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
10-01 18:58:53.644: E/TiApplication(13138): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
10-01 18:58:53.644: E/TiApplication(13138): at dalvik.system.NativeStart.main(Native Method)
First, thanks for your work on both Pull to Refresh and Infinite Scroll, they have helped greatly. I can't quite figure out 2 things though.
Whenever it loads the next page of results it resets the table so I only see 10 records at a time (instead of keeping the 10 items from page 1 and adding to it). I have set collection.fetch({ add:true }), which is what I thought would do it.
Second question, how do you reset the page index so that I can reload the table with just the first page of results? I tried to calling $.tableWidget.load(); but it just reloads the current page. Is there a currentIndex or something? Or do I need to detach and re-initialize/load the Infinite Scroll module?
Sorry for 2 questions in one post but I know you don't work on this often and only wanted to bug you once. :) Thanks again for the work.
I'm using your pull to request widget as well and when I pull to refresh, it trigged twice, one for pull to refresh and another to load more.
There's a way to block my infinityScroll ?
Hi,
The initial call to
$.is.load();
Makes the loading show up but doesn't trigger the end event.
Althogh, If I don't call the initial load I get an empty list with the button to load more. If I click it the function that loads more is called normally.
Is it a bug with newer version of titanium/alloy?
My info:
SDK Version = 3.5.1.GA
Target Platform = android
Alloy Version = 1.5.1
Some simplified code:
Template:
<Widget id="ptr" src="nl.fokkezb.pullToRefresh" onRelease="loadNewerMessages">
<ListView id="contentList" defaultItemTemplate="messageTemplate">
<Templates>
<ItemTemplate name="unreadMessageTemplate">
<View class="item-block">
<Label bindId="topText" class="item-element item-top-text"></Label>
<Label bindId="titleText" class="item-element item-title"></Label>
<Label bindId="bottomText" class="item-element item-bottom-text"></Label>
</View>
<View class="item-shadow"></View>
</ItemTemplate>
<ItemTemplate name="readMessageTemplate">
<View class="item-block read-message">
<Label bindId="topText" class="item-element item-top-text"></Label>
<Label bindId="titleText" class="item-element item-title"></Label>
<Label bindId="bottomText" class="item-element item-bottom-text"></Label>
</View>
<View class="item-shadow"></View>
</ItemTemplate>
</Templates>
<ListSection/>
<Widget id="is" src="nl.fokkezb.infiniteScroll" onEnd="loadMoreMessages" />
</ListView>
</Widget>
Controller:
$.is.init($.contentList);
var loadMoreMessages = function(e) {
XHR.get(
'messages',
{
start: currentIndex,
limit: listLimit
},
function(data) {
currentIndex += listLimit;
if (data.rows.length < listLimit) {
e.done();
} else {
e.success();
}
$.contentList.sections[0].appendItems(data);
}
);
};
$.is.load();
I'm trying to use it but it's loading all the items in the list, the last button showing up to load more
library.js (model)
exports.definition = {
config: {
columns: {
"id": "INTEGER PRIMARY KEY AUTOINCREMENT",
"title": "text",
"subtitle": "text",
"image": "text"
},
adapter: {
type: "sql",
collection_name: "library",
idAttribute: "id",
}
},
extendModel: function(Model) {
_.extend(Model.prototype, {
validate: function() {
var val = false;
if (this.get("title") != null && this.get("subtitle") != null && this.get("image") != null) {
return true;
} else {
return false;
}
return false;
}
});
return Model;
},
extendCollection: function(Collection) {
_.extend(Collection.prototype, {
// extended functions and properties go here
});
return Collection;
}
};
index.xml
<Alloy>
<Collection src="library" id="library" instance="true"/>
<Window class="container">
<ListView id="listView" defaultItemTemplate="template">
<Widget id="is" src="nl.fokkezb.infiniteScroll" onEnd="listLoader" />
<Templates>
<ItemTemplate name="template">
<ImageView bindId="image" class="img"/>
<Label bindId="title" class="title"/>
<Label bindId="subtitle" class="subtitle"/>
</ItemTemplate>
</Templates>
<ListSection id="section" dataCollection="$.library">
<ListItem rowid="{id}" title:text="{title}" subtitle:text="{subtitle}" image:image="{image}"/>
</ListSection>
</ListView>
<Button id="btn_add" title="add"/>
<Button id="btn_clear" title="clear"/>
</Window>
</Alloy>
index.js
function onClickAdd(e) {
var book = Alloy.createModel('library', {
title: 'Title' + Math.floor(Math.random() * 1000),
subtitle: 'asdfasdf ' + Math.floor(Math.random() * 1000),
image: 'https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/SIPI_Jelly_Beans_4.1.07.tiff/lossy-page1-220px-SIPI_Jelly_Beans_4.1.07.tiff.jpg'
});
if (book.validate()) {
book.save();
$.library.fetch();
}
}
function onClickClear(e) {
_.invoke(Alloy.Collections.library.toArray(), 'destroy');
}
function onClickItem(e) {
var rowid = e.section.getItemAt(e.itemIndex).properties.rowid;
if (OS_IOS) {
$.listView.deselectItem(e.sectionIndex, e.itemIndex);
}
Alloy.Collections.library.where({
id: rowid
})[0].destroy();
}
$.listView.addEventListener("itemclick", onClickItem);
$.btn_clear.addEventListener("singletap", onClickClear);
$.btn_add.addEventListener("singletap", onClickAdd);
$.is.init($.listView);
$.index.open();
$.is.load();
function listLoader(e) {
myLoader(e, $.library);
}
function myLoader(e, collection) {
var ln = collection.models.length;
collection.fetch({
data: { offset: ln },
//add: true, -> Message: Uncaught Error: Can't add an invalid model to a collection
success: function(col) {
(col.models.length - ln < 10) ? e.done() : e.success();
},
error: e.error
});
}
Can someone help me?
I am running into an issue which I can't explain. When the list reaches the end myLoader is called however the listview is not updated. When I tap on load more the listview is updated with new data and the data from the previous scroll trigger is also added. If I trigger the myloader manually(for example from a button somewhere else) it always works.
Notice the log output which will state which items are being added.
I am not using a collection here to simplify my example, however I have the same issue in my project which uses collections and sql queries.
It might be an SDK issue with listviews however I don't understand why it works fine if I trigger the myloader via button but not via scroll.
I have the following code:
index.js
var iter = 0;
var addpercall = 50;
$.index.open();
$.is.init($.list);
$.is.load();
function myLoader(e) {
console.log('load more start: ', iter);
var section = Ti.UI.createListSection();
var items = [];
for (var i = 0; i < addpercall; i++) {
iter++;
items.push({
properties: {
itemId: 1
},
template: 'listRow',
name: {
text: 'text ' + iter
}
}
);
}
section.setItems(items);
$.list.appendSection(section);
e.success();
console.log('load more end: ', iter);
}
index.xml
<Alloy>
<Window class="container">
<ListView id="list" defaultItemTemplate="listRow">
<Templates>
<ItemTemplate name="listRow" id="listRow" height="44">
<View>
<View>
<Label id="name" bindId="name"/>
</View>
</View>
</ItemTemplate>
</Templates>
<Widget id="is" src="nl.fokkezb.infiniteScroll" onEnd="myLoader"/>
</ListView>
</Window>
</Alloy>
This issue also causes me to run into "[ERROR] message = "attempt to insert section 4 but there are only 2 sections after the update";".
Widget doesn't work anymore when compiling the app with SDK 3.2.X. Android & iOS are generating the same error:
message = "'undefined' is not an object (evaluating '__parentSymbol.addEventListener')";
__parentSymbol seems to be undefined.
Tested on empty Alloy project, index.xml:
Code: http://pastebin.com/Gf9wyd4B
Screenshot:
SDK 3.2.X with Studio 3.2.0.201312142258. Tested on Android and iOS (7.0.3).
I've created an app with a tab group in the root window.
A single tab has infinite scroll logic. When I click the back button to close the app, I experience a crash, but only when using $.is.detach
or $.is.cleanup
.
It seems the tab group is already doing some cleaning up, because the code is running to an error when trying to execute $.isIndicator.hide()
The log shows the following:
[DEBUG] TabGroup: Tabgroup is closed normally.
[WARN] TiUIActivityIndicator: (main) [570,8340] Unable to create an activity indicator. Activity is null
Not using the cleanup methods solves the problem, but that's not what you want.
If you're using this awesome module for Android (iOS works great as-is), and your Rows creates gaps sometimes between the rows as you scroll up & down (especially if you have images within your rows), the solution is to remove borderRadius (or set it to 0) and thats it!
Wasn't sure where to place this info, but surely will come handy to some.
Should it be pertinent to mention when using sql queries in the fetch to use col.models.length in the docs somewhere?
I'd hate to think anyone else being stuck dumbfounded at this in the future.
I followed all the directions and I have it showing the "Tab to load more.." button. This all works but it doesn't automatically try to load more items when I reach the bottom of the TableView.
Am I missing something or is this not implemented yet for Android? I am using the latest version of Titanium (3.2.0)
We are having some troubles using both widgets on a tableview. It seems the pulltorefresh is triggering the onend event on the infinitescroll widget, thus causing two API requests instead of one. Are there tips or examples of them working together? Thanks
I used the new update for . When i use this module with nl.fokkezb.infiniteScroll i cannot publish while it debugs and runs sucessfully only on simulator. While publishing with appcelerator studio i get arm64 and armv7 error and most times it throws compileC error. Error only exists when using with TiCollectionView. I think nl.fokkezb.infiniteScroll does not supports TiCollectionView in publish/release
[ERROR] : ** BUILD FAILED ** [ERROR] : The following build commands failed: [ERROR] : Ld build/HelloWorlder.build/Release-iphoneos/HelloWorld-universal.build/Objects-normal/armv7/HelloWorld normal armv7 [ERROR] : Ld build/HelloWorld.build/Release-iphoneos/HelloWorld-universal.build/Objects-normal/arm64/HelloWorld normal arm64 [ERROR] : (2 failures) TRACE | titanium exited with exit code 1 ERROR | Error: ti run exited with error code 1 at ChildProcess.<anonymous> (/Users/alex/.appcelerator/install/4.0.0/package/node_modules/appc-cli-titanium/plugins/run.js:84:66) at ChildProcess.emit (events.js:117:20) at Process.ChildProcess._handle.onexit (child_process.js:820:12)
Had to make a few updates to the code (tiapp.xml and replace iphone ai style). However, it didn't fix the crash.
Running ios sim (iPhone 5s; ios 8.3, sdk 3.5.1.GA), still getting same error
[ERROR] Script Error { [ERROR] column = 44; [ERROR] line = 150; [ERROR] message = "undefined is not an object (evaluating 'Ti.UI.ActivityIndicatorStyle.DARK')"; [ERROR] sourceURL = "file:///Users/mjstelly/Library/Developer/CoreSimulator/Devices/869608B4-D439-4739-A61C-A523254FCBD3/data/Containers/Bundle/Application/6B7AEC71-F057-4147-A6B2-BBDF4448AA47/test.app/alloy/widgets/nl.fokkezb.infiniteScroll/controllers/widget.js";
The offending line in the compiled code is:
$.__views.isIndicator = Ti.UI.createActivityIndicator({ style: Ti.UI.ActivityIndicatorStyle.DARK, id: "isIndicator" });
Not really sure what's causing this problem.
It may be that im using query: in my fetch, but the success function seems to be firing constantly even after all items have been loaded, so whenever I scroll the table view it fires, reloads / tries to add data and causes the tableview to become unresponsive for a few seconds until all touches / fires have finished but the moment I start scrolling again the function fires off again and fetches and renders the table unresponsive.
I found that in some cases I still need to call '$.is.init($.table);' even in the latest version of Ti (3.2.3). Maybe something to mention in the Readme since it appears to still not work everywhere?
Not Needed:
<Alloy>
<Collection src="book" />
<TableView id="table" dataCollection="book" dataFilter="bookFilter" dataTransform="bookTransform">
<Require src="bookRow"/>
<Widget id="is" src="nl.fokkezb.infiniteScroll" onEnd="infiniteCallback" />
</TableView>
</Alloy>
Needed:
<Alloy>
<Collection src="book" />
<Tab id="tab" title="Book" icon="/images/icons/book.png">
<Window id="bookListWindow" title="Book">
<TableView id="table" onClick="openbook" dataCollection="book" dataFilter="bookFilter" dataTransform="transformFunction" filterAttribute="mySearchFilter">
<SearchBar hintText="Search"/>
<Require src="bookRow"/>
<Widget id="is" src="nl.fokkezb.infiniteScroll" onEnd="infiniteCallback" />
</TableView>
</Window>
</Tab>
</Alloy>
Hello,
It seems that the "http://www.tidev.io/feed/json" is not reachable.
Perhaps temporarily.
Oups, for the "test" branch
var result = Ti.UI.createTableView({
});
var is = Alloy.createWidget('nl.fokkezb.infiniteScroll');
result.setFooterView(is.getView());
I use the above code to add the widget, but getting the following error:
[ERROR] : TiApplication: (main) [3308,7581] Sending event: exception on thread: main msg:java.lang.NullPointerException; Titanium 3.2.3,2014/04/22 10:17,b958a70
[ERROR] : TiApplication: java.lang.NullPointerException
[ERROR] : TiApplication: at ti.modules.titanium.ui.widget.tableview.TiTableView.layoutHeaderOrFooter(TiTableView.java:457)
[ERROR] : TiApplication: at ti.modules.titanium.ui.widget.tableview.TiTableView.(TiTableView.java:343)
[ERROR] : TiApplication: at ti.modules.titanium.ui.widget.TiUITableView.processProperties(TiUITableView.java:106)
[ERROR] : TiApplication: at org.appcelerator.kroll.KrollProxy.setModelListener(KrollProxy.java:1185)
[ERROR] : TiApplication: at org.appcelerator.titanium.proxy.TiViewProxy.realizeViews(TiViewProxy.java:480)
[ERROR] : TiApplication: at org.appcelerator.titanium.proxy.TiViewProxy.handleGetView(TiViewProxy.java:471)
[ERROR] : TiApplication: at org.appcelerator.titanium.proxy.TiViewProxy.getOrCreateView(TiViewProxy.java:449)
[ERROR] : TiApplication: at org.appcelerator.titanium.proxy.TiViewProxy.handleAdd(TiViewProxy.java:566)
[ERROR] : TiApplication: at org.appcelerator.titanium.proxy.TiViewProxy.handleMessage(TiViewProxy.java:218)
[ERROR] : TiApplication: at android.os.Handler.dispatchMessage(Handler.java:95)
[ERROR] : TiApplication: at android.os.Looper.loop(Looper.java:137)
[ERROR] : TiApplication: at android.app.ActivityThread.main(ActivityThread.java:5105)
[ERROR] : TiApplication: at java.lang.reflect.Method.invokeNative(Native Method)
[ERROR] : TiApplication: at java.lang.reflect.Method.invoke(Method.java:511)
[ERROR] : TiApplication: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
[ERROR] : TiApplication: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
[ERROR] : TiApplication: at dalvik.system.NativeStart.main(Native Method)
i use infiniteScroll and pullToRefresh in one table.
when i dettach
IOS 6.1
Really nice to have a example or sample without models/collections but normal payloads, special with ListView api.
Hi, how can I change the Text ? "tap to load more..."
I have the same problem on your other widget... pull to refresh
Thanks
I got the module loaded and thanks for making it public but wondering if you can show an example how how to put data in there and get more data.. that's where I'm a bit lost and trying to dig around the code i'm getting no where
thanks
In Alloy 1.3.0 the usage of silent:true is different and is not adding anything to the tableview. removing this entry or setting it to false fixes "IS". Docs may need updating.
I was looking into this module to create a chatting program. As the module is right now, there doesn't seem to have any way to infinitely scroll upwards to add more data.
I can't get infiniteScroll to work if I have app/lib/alloy/backbone.js and app/lib/alloy/underscore.js, it crashes when $.listWidget.load(); is called
I understand that using this widget with a search functionality will only show results of the items that are currently showing. I'm trying to work out a good solution for what can be done for when the user search's the list, finds no results to show, but in reality there are results, just not in what is currently showing. Is there a working solution someone has already done, or a suggested way to handle this?
Hi, I had some problems with this bug that is most likely not due to your code.
It happens only when i scroll down immediately after i see the window.
It disappears when I comment out the lines that add and remove ActivityIndcator from the View it belongs to.
I thought you might be interested in knowing this. Thanks for your work.
I have a tableview with 2 items in it, if I move the tableview at all, the onEnd fires, if I click it - it also fires causing paging to go crazy.
Hey Fokke,
Just gave a try to my app using your widget with the latest Ti SDK, and here is the error it throws:
line = 40;
message = "'undefined' is not an object (evaluating '__parentSymbol.sections[sectionIndex]')";
name = TypeError;
sourceId = 314850144;
sourceURL = "[...]/alloy/widgets/nl.fokkezb.infiniteScroll/controllers/widget.js";
Tell me if there is anything you need to figure what this is.
Cheers
I am struggling to get the infiniteScroll to work properly. I have a news feed that the user can click and go to the details page for the clicked item. The infinite scroll work properly on startup and will load new item onEnd. But when you click back and close details page to return to the scroll view page. No data will load and just says click to load more. I can verify that my API call is getting data, but no results show up onEnd. I am pretty new to Appcelerator so that does not help either i suppose.
When I return in the window myLoader executes twice.
Hi, I want to use the widget in a tabbed window that both tabs have a table, but I only want to use the widget in one of them.
I put the <Widget .... /> only in the tab 2 but when de first load ends it call to myLoad().
mainpage.js
$.postsTableView.addEventListener('click', selectRow);
loadPosts();
var data = [];
//
function selectRow(e){
var rowId = e.rowData.rowId;
var detailView = Alloy.createController("detail",{
pid : rowId
}).getView();
// detailView.open();
$.indexTob.open(detailView, {
animated : true
});
}
//load more posts
function loadPosts(){
// var data=[];
var url = "http://192.168.1.103/user/showPosts";
var xhr = Ti.Network.createHTTPClient({
onload : function(e) {
// this function is called when data is returned from the server and available for use
// this.responseText holds the raw text return of the message (used for text/JSON)
// this.responseXML holds any returned XML (including SOAP)
// this.responseData holds any returned binary data
var loginResponse = JSON.parse(this.responseText);
var success = loginResponse.success;
var posts = loginResponse.posts;
if (success) {
// alert(success);
// Populate the TableView data.
for (var i=0; i < posts.length; i++) {
//create a tableview row
var row = Ti.UI.createTableViewRow({
// title:posts[i].position //string only
hasChild : true,
className : 'post-row'
});
row.rowId=posts[i].id;
//title label
// Create a Label.
var titleLabel = Ti.UI.createLabel({
text : posts[i].position,
// color : '#textColor',
font : {fontSize:14,fontWeight:'bold'},
height : 20,
width : '95%',
top : 5,
left : 20
});
// Add to the parent view.
row.add(titleLabel);
//description label
// Create a Label.
var descriptionLabel = Ti.UI.createLabel({
text : posts[i].salary,
// color : '#textColor',
font : {fontSize:10,fontWeight:'normal'},
height : 60,
width : '95%',
top : 25,
left : 10,
});
// Add to the parent view.
row.add(descriptionLabel);
$.postsTableView.appendRow(row);
// data.push(row);
};
// globalData.concat(data);
// $.postsTableView.data=data;
};
},
onerror : function(e) {
// this function is called when an error occurs, including a timeout
Ti.API.debug(e.error);
alert('error');
},
timeout : 5000 /* in milliseconds */
});
xhr.open("POST", url);
xhr.send(); // request is actually sent with this statement
}
//infinite scroll
function myLoader (e) {
alert("mei you le ");
// console.log('sdfs');
loadPosts();
}
mainpage.xml
sdfsfds
dfsldfjls
I am not even sure why I am making this issue since it's not the module's fault. However, for anyone who wants to use this module with Alloy Collections, whenever you perform a fetch to add data onto a collection, the entire containing view (ListView, TableView) and rows will get redrawn/recreated.
My use case was that each of my TableViewRow(s) have an ImageView in them; those ImageViews have a postLayout event to figure out whether or not to fetch a newer image blob from the server. I noticed that my server was receiving requests for the rows that were already drawn. I haven't tried, but I am thinking about simplifying the TableViewRow(s) further.
Hi Fokke,
I have tried to integrate both of your widgets in single ListView and also in table view. but not able to integrate successfully. After using both widgets either app got crashed or data on list view is not visible. Can you please help me in this scenario or give the example code.
Thanks
Note really a issue, but is it possible to remove the footer with the info text when done() is triggered?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.