Angular-ui ui-scroll - how to make it work when scrolling up? - angular-ui

I'm using the angular-ui ui-scroll and it's great when I scroll down, keeps adding items as expected. However when I scroll up, it stops at the top of the last batch that I loaded. For example if I have 100 items and my buffer size is 10, and I've scrolled down so that items 61-70 are showing, when I scroll back up I want to see items 51-60. However I can't scroll up past item 61. I don't know what I'm doing wrong.
Here's the html:
<div row="row" ui-scroll="row in transactionSource" buffer-size="10" >{{row.data}}</sq-transaction>
Here's the script:
$scope.transactionSource = {
get: function (index, count, callback) {
if (index < 0) {
callback([])
}
else {
var buffer = 10;
var end = ctrl.nextIndex + buffer;
if (end > ctrl.transactions.length) end = ctrl.transactions.length;
var items = ctrl.transactions.slice(ctrl.nextIndex, end);
ctrl.nextIndex = end;
callback(items);
}
}
};
If it's related, when I console.log the index and count values received, after the first load of 10 I get an index of -9 (in which case I return an empty array - if I don't do this, the entire array gets loaded). When I scroll up, I don't get a console.log message at all so it's like the 'get' only gets called when scrolling down.
Thanks in advance for any and all help.

Your datasource looks wrong. Items retrieving (slicing in your case) should be based on index and count parameters that you have from the datasource.get method arguments. I'd like to post an example of datasource implementation where the result items array is limited from 0 to 100 and should be sliced from some external data array:
get: function(index, count, success) {
var result = [];
var start = Math.max(0, index);
var end = Math.min(index + count - 1, 100);
if (start <= end) {
result = externalDataArray.slice(start, end + 1);
}
success(result);
};
Hope it helps!

Related

Player character won't go in front of buildings

Ok, so I managed to get all the buildings to stay in place, but now for some reason, the player character won't go in front of the buildings.
I tried switching the places in the code where the if the command for checking if the character's going behind the building and the if-else for checking if it's going in front of the code, but nothing changed.
here's the code:
var _dg = depth_grid;
var _inst_num = instance_number(obj_depth_buildings);
//below is for resizing the grid
ds_grid_resize(depth_grid,2, _inst_num);
//below adds instance info to grid
var _yy = 0;
with (obj_depth_buildings)
{
_dg[# 0,_yy] = id;
_dg[# 1,_yy] = y;
_yy++;
}
//below sorts the grid so that the ones with the biggest y variables end up at the top
ds_grid_sort(_dg,1,false);
//below goes through the grid and identifies everything
var _inst;
_yy = 0;
repeat (_inst_num)
{
//below pulls out an id
_inst = _dg[# 0, _yy];
//below gets the instance execute depth
with(_inst)
{
_inst.depth= layer_get_depth("collision") + _yy;
with (obj_nonbuilding_depths)
{
if object_index.y > _inst.y
{
object_index.depth = (_inst.depth + 1);
}
else if object_index.y <= _inst.y
{
object_index.depth = (_inst.depth - 1);
}
}
}
_yy++;
}
you should change the object depth by change the leyar depth in GMS2

setPriority() deletes priority

I'm working with ordered data and ran into this problem:
I add items to a location with push() and set their priority to their creation date in milliseconds so they are ordered by date. When I try to change the order of the items I find the next, or previous (if there's no next) item and get it's priority, then I add or substract one and set the priority of the moved item to the result. I fetch the priority ok, but when I call setPriority() the item loses the priority. Exporting the item with the graphical debugger returns no priority for each item moved. Returns correct priority for unmoved items.
Some code:
/* id is the id of the div being moved
using jquery ui's sortable
div id's are formed like "item_" + firebaseref.name()
*/
name = id.substr(id.indexOf('_') + 1);
id2 = $('#' + id).next().attr('id');
if(id2){
name2 = id2.substr(id2.indexOf('_') + 1);
itemRef = rootRef.child('path/to/my/items/'+name2);
itemRef.once('value', function (dataSnapshot){
var pr = Number(dataSnapshot.getPriority()),
myRef = rootRef.child('path/to/my/items/'+name);
myRef.setPriority(pr - 1); // tried this or toString as below
});
} else {
// try previous item
id2 = $('#' + id).prev().attr('id');
if(id2){
name2 = id2.substr(id2.indexOf('_') + 1);
itemRef = rootRef.child('path/to/my/items/'+name2);
itemRef.once('value', function (dataSnapshot){
var pr = Number(dataSnapshot.getPriority()) + 1,
myRef = rootRef.child('path/to/my/items/'+name);
myRef.setPriority(pr.toString());
});
}
}
I had a 'child_moved' listener but I'm not using it now. Any ideas?
This is a bug in Firebase. I'm not sure of the cause at this point but it appears that numbers larger than a certain size are not being properly saved. We'll investigate and update this answer when complete.
Update: This bug has been resolved. Give it another try!

Fullcalendar : How to reliably get reference to HTML element for date box on which external element was dropped

I would like a way to obtain an HTML element or CSS selector (or a reference to the droppable object itself) for the date on which an external draggable element was dropped. I tried using the following within the drop() callback to get the node for the date box using the coordinates of the drop event:
var pageX = jsEvent.originalEvent.pageX;
var pageY = jsEvent.originalEvent.pageY;
var domElem = document.elementFromPoint(pageX, pageY);
var node = Y.one(domElem).ancestor('#calendar > .fc-content table.fc-border-separate tr > td', true);
(I'm using the YUI 3 Y.one() and ancestor() methods above to get the node I want, but other methods could be used.)
The above does correctly locate the node of the date box as long as the drop does NOT land on top of an event cell rendered on that date. If the drop does happen to land on an event cell, however, domElem ends up being the event cell, which is an absolutely positioned element outside of the calendar, and the ancestor() methodology above does not work.
I have also tried getting a reference to the droppable obj by way of the draggable element revert property:
revert: function(droppableObj) {
if(droppableObj === false) {
alert('No droppableObj');
return true;
}
else {
alert(Y.dump({droppableObj: droppableObj}));
return false;
}
},
Unfortunately, the above does not work. Even though the external element does drop correctly, the revert function does not recognize the calendar as droppable. (For details, see my earlier stackoverflow post at: Fullcalendar: draggable object rejects fullcalendar as droppable even though fullcalendar accepts drop )
The only alternative I can think of is to use the date object in the drop() callback, and with that find the correct fc-dayXX element, but that seems pretty cumbersome. I have searched on this already, but not found anything so far. If anyone has a suggestion, please let me know.
Here is what I came up with for the fullcalendar drop callback:
function getSelectorForDroppedOnDate(date, allDay, jsEvent, ui) {
if (! date) return;
var displayedDate = $('#calendar').fullCalendar('getDate');
var displayedMonth = displayedDate.getMonth(); // 0 - 11
var displayedYear = displayedDate.getFullYear();
var droppedOnYear = date.getFullYear();
var droppedOnMonth = date.getMonth(); // 0 - 11
var droppedOnDate = date.getDate(); // 1 - 31
var droppedOnDayOfWeek = date.getDay(); // 0 - 6 no matter what week of the month
// Get values related to the last day of the month before the month the event was dropped on
// so that the grid location of the drop can be determined
var lastDayOfMonthBeforeDroppedOnMonth = new Date(droppedOnYear, droppedOnMonth, 0); // This is actually correct
var dateOfLastDayOfMonthBeforeDroppedOnMonth = lastDayOfMonthBeforeDroppedOnMonth.getDate(); // 1 - 31
var dayOfWeekOfLastDayOfMonthBeforeDroppedOnMonth = lastDayOfMonthBeforeDroppedOnMonth.getDay(); // 0 - 6
var i;
var gridLocationOfDrop; // 0 - 41 to cover 42 days of six weeks always shown
if (droppedOnMonth === displayedMonth) { // dropped on month is same as currently displayed month
i = 0;
// adjust droppedOnDayOfWeek by 1 to account for 0-based index
while ((droppedOnDayOfWeek + 1) + i*7 < droppedOnDate) {
i++;
}
gridLocationOfDrop = droppedOnDayOfWeek + i*7;
}
else {
// if dropped on date is in month previous to currently displayed month (need to compare years since inequality will reverse at year boundary)
if ((droppedOnMonth < displayedMonth && droppedOnYear === displayedYear) || (droppedOnMonth > displayedMonth && droppedOnYear < displayedYear)) {
gridLocationOfDrop = droppedOnDayOfWeek;
}
// else if dropped on date is in month after currently displayed month (need to compare years since inequality will reverse at year boundary)
else if ((droppedOnMonth > displayedMonth && droppedOnYear === displayedYear) || (droppedOnMonth < displayedMonth && droppedOnYear > displayedYear)) {
i = 0;
// adjust dayOfWeekOfLastDayOfMonthBeforeDroppedOnMonth by 1 to account for 0-based index
while ((dayOfWeekOfLastDayOfMonthBeforeDroppedOnMonth + 1) + i*7 < dateOfLastDayOfMonthBeforeDroppedOnMonth) {
i++;
}
gridLocationOfDrop = (dayOfWeekOfLastDayOfMonthBeforeDroppedOnMonth + i*7 + droppedOnDate);
}
}
selector = '#calendar > .fc-content table tr > td.fc-day' + gridLocationOfDrop;
return selector;
}
Works for me!

Flex 4 Printing Error with dynamic components

I have a set of components that are added to my Flex 4 stage dynamically.
Problem 1:
How do I address these objects when adding them to print.I cant generate objects on the fly and append them because then the print manager does not wait for the dynamic data to populate.
I currently use the following code to address items dynamically which fails:
public function PrintDashPreview():void{
var ItemsDrawn:int = 0;
var printJob:FlexPrintJob = new FlexPrintJob();
if(printJob.start()){
for each (var item:Object in GetDashBoardPreviewItems.lastResult.DashboardItem)
{
ItemsDrawn ++
this.addElement(dashPreview["flexShape" + TheID]);
printJob.addObject(dashPreview["flexShape" + TheID]);
this.removeElement(dashPreview["flexShape" + TheID]);
}
printJob.send()
Alert.show('Sent: ' + ItemsDrawn + ' items to page for printing.','Print Progress Debug');
}
}
How can I tell flex to grab these specific items and add them to the print job.
Problem 2:
How do I tell flex to lay each item out one below the other 2 per page.
Please and thank you for any help you can provide.
Regards
Craig Mc
The recipe for printing dynamic content usually goes like this:
(1) Start the printJob:
printJob = new FlexPrintJob();
printJob.printAsBitmap = false;
printJob.start();
(2) Obtain the print page dimensions. Use it if you have overflowing content:
printerPageHeight = printJob.pageHeight;
printerPageWidth = printJob.pageWidth;
(3) Create all of the dynamic objects and wait for the corresponding CREATION_COMPLETE events:
var componentsToBeInitialized:Number = 0;
var pages:Array = [];
for each (var itemData:Object in dataProvider) {
var component:UIComponent = new PageComponent();
someContainerOnTheDisplayList.addChild(component);
component.data = itemData;
componentsToBeInitialized ++;
pages.push(component);
component.addEventListener(FlexEvent.CREATION_COMPLETE, handlePageCompletion);
}
(4) Waiting for all CREATION_COMPLETE events:
function handlePageCompletion(e:Event):void {
componentsToBeInitialized --;
if (componentsToBeInitialized == 0)
printAllPages();
}
(5) Print the pages:
function printAllPages():void {
for each (var printPage:UIComponent in pages) {
printJob.addObject(printPage);
}
printJob.send();
}

When to render Legend in Flex

My Flex chart has code that creates a legend from each data series. Currently, I have the drawLegend function execute when a button is clicked.
I am trying to get the legend to draw automatically but I am having trouble determining when to call the drawLegend function. Users click on an 'Update' button which retrieves data. I want the legend to get created after this, without the users having to click on another button.
I have put my drawLegend function in several places (ResultHandler, afterEffectEnd(for chart animation, etc.) and nothing works.
Sometime after the series has been added to the chart and after the series animation ends, the legend can be added.
How can I trap this point in time and call my function?
Any ideas?
Below is the code I used to create the legend. Note that even though the code processes each series, I noticed that the Fill color is null if it is called too early.
private function drawLegend(event:Event):void {
clearLegend();
// Use a counter for the series.
var z:int = 0;
var numRows:int;
if (chart.series.length % rowSize == 0) {
// The number of series is exactly divisible by the rowSize.
numRows = Math.floor(chart.series.length / rowSize);
} else {
// One extra row is needed if there is a remainder.
numRows = Math.floor(chart.series.length / rowSize) + 1;
}
for (var j:int = 0; j < numRows; j++) {
var gr:GridRow = new GridRow();
myGrid.addChild(gr);
for (var k:int = 0; k < rowSize; k++) {
// As long as the series counter is less than the number of series...
//skip columnset group
if (chart.series[z] is LineSeries || chart.series[z] is ColumnSeries){
if (z < chart.series.length) {
var gi:GridItem = new GridItem();
gr.addChild(gi);
var li:LegendItem = new LegendItem();
// Apply the current series' displayName to the LegendItem's label.
li.label = chart.series[z].displayName;
// Get the current series' fill.
var sc:SolidColor = new SolidColor();
sc.color = chart.series[z].items[0].fill.color;
// Apply the current series' fill to the corresponding LegendItem.
li.setStyle("fill", sc.color);//was just sc
// Apply other styles to make the LegendItems look uniform.
li.setStyle("textIndent", 5);
li.setStyle("labelPlacement", "left");
li.setStyle("fontSize", 9);
gi.setStyle("backgroundAlpha", "1");
gi.setStyle("backgroundColor", sc.color);
//gi.width = 80;
// Add the LegendItem to the GridItem.
gi.addChild(li);
}
}
// Increment any time a LegendItem is added.
z++;
}
}
}
Well, I couldn't quite figure out what event to trap so I used the following in the chart's parent container:
chart.addEventListener(ChartItemEvent.ITEM_ROLL_OVER,drawLegend);
Seems to work ok.

Resources