react-virtualized InfiniteLoader in both directions, top and bottom - infinite-scroll

How to make infinite scrolling in both directions, up and down. I am using the InfiniteLoader and the List, both are react-virtualized components. I have a list of timestamps with initial date-time range. From there the list should be infinite in both directions. Currently, scroll-down to the bottom of the List will trigger the function _loadMoreRows(). However, I would like to trigger the _loadMoreRows() with the same functionality when scrolling in the direction up.

I have it working now :) Everything is fine. The threshold prop of the <InfiniteLoader> defines the threshold number of indices before the start/end of the List when to prefetch data, i.e. trigger _loadMoreRows().
The first and the last item in this.state.items should have their corresponding loadedRowsMap set to undefined after the initial data fetch.
const items = _getItems(); // fetch items
const rowCount = items.length;
const loadedRowsMap = [];
_.map(this.state.loadedRowsMap,(row,index)=>{
const status = (index===0 || index===rowCount-1) ? undefined : STATUS_LOADED;
loadedRowsMap.push(status)});
scrollToIndex = parseInt(rowCount/2,10);
this.setState({
items, rowCount, loadedRowsMap, scrollToIndex,
});
Before displaying the list, a scrollToIndex prop of the <List> component should be set to the middle of the list, i.e. rowCount/2. This number should satisfy the equation
0 + threshold < scrollToIndex < rowCount - 1 - threshold.
Function _isRowLoaded() will check loadedRowsMap[index]. If it is set to STATUS_LOADED or STATUS_LOADING (internal constants used inside the InfiniteLoader) it will not trigger _loadMoreRows(). If it is set to undefined, then it will trigger _loadMoreRows().
With this setup, trigering _loadMoreRows() works in both scroll directions, up and down.

Related

Listbox multiple selection matlab

I created a listbox and enabled multiple selections. My listbox contain numbers from 1 to 10. When I select 3, 1, and 8, the function always put my selections in alphabetical order (1,3,8). Is there any way I could make it not put my selection in alphabetical order? So if I select 3, 1, and 8 the output of my selection is 3, 1, 8.
Thank you.
For the purpose of this answer I'm assuming you're using matlab-hg2.
From the docs for uicontrol:
'listbox' ... The Value property stores the row indexes of currently selected list box items, and is a vector value when you select multiple items. After any mouse button up event that changes the Value property, MATLAB evaluates the list box's callback routine. To delay action when multiple items can be selected, you can associate a "Done" push button with the list box. Use the callback for that button to evaluate the list box Value property.
From the above we learn that the information on the selected lines is returned in Value. From there, it's a matter of keeping track of what's selected. This can be quite easily done using a persistent variable inside the listbox' Callback as shown in the following example:
function LISTBOX_EXAMPLE
hFig = figure('Units','Pixels','Position', [200 200 100 200],'Menubar','none');
uicontrol(hFig, ...
'Style', 'listbox',...
'Units','Pixels',...
'Position', [20 20 80 150],...
'Max',3,...
'Min',0,...
'String',num2cell(1:10),...
'Callback',#selectionCallback);
function selectionCallback(hObject,~)
persistent previouslyChosenItems
%// Elements were added:
if numel(previouslyChosenItems) < numel(hObject.Value)
previouslyChosenItems = union(previouslyChosenItems,hObject.Value,'stable');
%// Elements were removed:
elseif numel(previouslyChosenItems) > numel(hObject.Value)
previouslyChosenItems = intersect(previouslyChosenItems,hObject.Value,'stable');
%// A different element was selected (single element):
elseif numel(previouslyChosenItems) == numel(hObject.Value) && numel(hObject.Value)==1
previouslyChosenItems = hObject.Value;
end
disp(['Currently selected items (in order): ' num2str(previouslyChosenItems(:)')]);
end
end
Example output:
Currently selected items (in order): 7
Currently selected items (in order): 3
Currently selected items (in order): 3 9
Currently selected items (in order): 3 9 1
Then it's up to you to assign the value of previouslyChosenItems somplace useful.

jquery ui sortable temporary element swapping during drag

I need to implement temporary drag replacement in a size-limited jquery ui sortable list.
I have 2 sortable lists:
A "slot" with only 1 spot to hold a single element
A "bucket" that holds several elements from which the user can pick any to fill the "slot"
The user has to drag an element from the bucket into the slot. While the user is holding the element with the mouse over the slot, if the slot is already occupied, the current slotted element should be moved into the bucket to visually make room for the dragged element. Then the user has 2 options:
If the user drops the new element: insert the new element into the slot
If the user cancels the drop: move the previously slotted element back into the slot (as it was originally)
This behaviour should repeat until the user has either cancelled the drag or dropped the element into the slot or the bucket.
To visually limit the slot to a single element, I have limited it to the exact height of a single element and setted its overflow to hidden.
Unfortunately, I have not been able to produce the effect while keeping a single element in the slot at all time.
EDIT 1: Here is an example of what I have so far
$(".slot").bind("sortchange", function (event, ui) {
var slot = $(event.target);
var bucket = $(".bucket");
// Move any element already in the slot (other than the currently
// dragged element) into the bucket
var slotElements = slot.children(".item").not(ui.item);
if (slotElements.length > 0) {
for (var idx = 0; idx < slotElements.length; idx += 1) {
var element = $(slotElements[idx]);
moveAnimate(element, bucket);
}
}
});

FormLayout, FormData and controls

can someone please explain to me how FormData on FormLayout works? I'm trying to understand the FormAttachment constructors and its parameters (numerator, offset, denominator). When do you need only one of them, two of them or all of the parameters... Also, if i have a group (or a composite) which will add widgets like buttons and labels which will need to be resized as per resolution using FormData, does the Group need to have a FormLayout also? I tried specifying a width of a group with form layout but no change
FormAttachment has several different constructors, I generally use two typically:
new FormAttachment (int numerator, int offset) - If there's only two integer parameters then the first parameter represents the percentage from the edge of the parent. Which edge is determined by which slot in the FormData object you insert the FormAttachment into: FormData.top, data.bottom, data.left, and FormData.right.
new FormAttachment (Control control, int offset) - Instead of positioning the object against the parent, this positions the object next to another child object. This works in conjunction with the previous constructor so that you effectively "anchor" one element against the parent, then build your layout by positioning other elements relative to the anchor. This also allows you to easily move and insert elements into the overall layout without having to rebuild the entire layout.
The others are variations on the themes of these two. FormAttachment (int numerator, int denominator, int offset) is the same as the FormAttachment with two integer parameters, but with two the denominator just becomes "100", i.e. it turns the numerator into a percentage. But you could say something like (1, 2, 0) for 1/2 of the way across or (1, 3, 0) for 1/3 of the space.
I'm not sure what you mean about whether the Group will need to have a layout defined but in general every parent Composite must have a layout defined on it to display children elements. If you want elements to resize as the parent resizes, one option is to attach the child to both the left and right sides of the element:
FormData formData = new FormData();
formData.left = new FormAttachment (0, 0); // Attach at the 0% left with 0 offset
formData.right = new FormAttachment (100, 0); // Attach at the 100% right with 0 offset
The Eclipse site has a lot of good snippets showing FormLayout, check out:
http://www.eclipse.org/swt/snippets/
Scroll down to the FormLayout section.

Setting up some properties for a combobox (scroll, edit, jump)

There are 3 properties that I want to set for some VBA form comboboxes and I don't know if it's possible.
I don't want to let the combobox editable. Right now if the user types something in it that it submits the form it will send that value... I want to let him choose only from the values I added in the Combobox.
I want to make the list of items in the combobox scroll-able. Right now I'm able to scroll through the list if I use the scroll-bar but I don't know why I can't scroll with the mouse scroll.
And I want to jump to some item if I start typing. Let's say I have the months of the year in one combobox... if I start to type mar I want it to jump to march. I know that for the html forms this properties is by default but I don't know about VBA forms...
Thanks a lot
Of the behaviours you want, some are possible with settings on the Combo, others you will need to code
List of Months: Put a list of entries on a (hidden) sheet and name the range. Set .RowSource to that range
Match as you type: Set properties .MatchEntry = fmMatchEntryComplete and .MatchRequired = True
Reject non list entries: A Combo with these settings will allow you to type an invalid entry, but will reject it with an error message popup when you commit. If you want to silently reject invalid data as you type, you will need to code it.
If you want the selected value returned to a sheet, set .ControlSource to a cell address (preferable a named range)
By "...scroll with the mouse scroll..." I assume you mean the mouse wheel. Unfortunatley Forms don't support mouse wheel scroll. You will have to code it yourself. There is a Microsoft patch for this at here (not tried it myself yet)
Sample code to silently reject invalid entries
Private Sub cmbMonth_Change()
Static idx As Long
Dim Match As Boolean
Dim i As Long
If cmbMonth.Value = "" Then Exit Sub
If idx = 0 Then idx = 1
i = idx
Match = False
For i = 0 To cmbMonth.ListCount
If cmbMonth.List((i + idx - 1) Mod cmbMonth.ListCount) Like cmbMonth.Value & "*" Then
cmbMonth.ListIndex = (i + idx - 1) Mod cmbMonth.ListCount
Match = True
Exit For
End If
Next
If Not Match Then
cmbMonth.Value = Left(cmbMonth.Value, Len(cmbMonth.Value) - 1)
End If
End Sub
Set the propertie MatchEntry of combobox to 1 (fmMatchEntryComplete) and MatchRequired to true for example
combobox1.MatchEntry=1
combobox1.MatchRequired=True
[]'s

how to get the drop target from gwt-dnd

I have a vertical panel containing two rows, say row 1 and row 2, each
row contains couple of widgets, now i need to allow the user to drag
and drop widgets between row 1 and row 2, here is what i did
_handler = new DragHandler() { .... };
_widgetDragController = new PickupDragController(boundaryPanel, false);
_widgetDragController.setBehaviorMultipleSelection(false);
_widgetDragController.addDragHandler(_handler);
then for each row, create panel to hold widgets and assign a drop controller:
VerticalPanelWithSpacer vPanel = new VerticalPanelWithSpacer();
// initialize a widget drop controller for the current column VerticalPanelDropController
widgetDropController = new VerticalPanelDropController(vPanel);
_widgetDragController.registerDropController(widgetDropController);
how can i find the drop target (namely which row) when i dnd widgets between row 1 and row 2? is there any way the _widgetDragController can tell which drop controller got involved and then i can further call getDropTarget() from the drop controller?
You could implement the functionality in VerticalPanelDropController.onDrop(DragContext), which gets called when the users drop on that drop controller. The drop controller knows the VerticalPanelWithSpacer it belongs to, and the dragContext contains information such as the x, y coordinates. You could use this information (the y coordinate & the coordinates of the widget) to calculate the row which should be added (although you might need to take scrolling etc into account, which makes it a bit more tricky). Hope that helps :-)