How to automate vertical scrolling in Flex AdvancedDataGrid when dragging item below bottom of visible rows? - flex3

I have an AdvancedDataGrid with XML dataProvider. Drag and drop in enabled, and works within the visible rows of the ADG.
HOWEVER, if I attempt to drag an item past the bottom-most visible row of the ADG, the ADG does NOT scroll to display the next rows, which makes it impossible to drag and drop beyond the immediately visible rows. Although this would seem to be logical default behaviour of a datagrid (drag to bottom and keep dragging to reveal subsequent rows), Flex evidently doesn't Do Things That Way. I'm flummoxed how to implement this programatically.
Can anyone help?

I had to do this with a few items in the past, basically what I did was monitor the mouses Y position in the DG, if it was 50 or fewer pixels from the top or bottom then I would set the verticalscrollposition of the DG += 20 or -= 20 as required.
Let me know if you need a code snip but you should be able to figure out how to do all of this.

this worked for me, from Andre's solution but also checking for maxVerticalScrollPosition
and i was extending the ADG
protected function onDragOver(event:DragEvent):void
{
var dropIndex:int = calculateDropIndex(event);
autoScoll(dropIndex);
}
//to have the adg scroll when dragging
//http://stackoverflow.com/questions/2913420/how-to-automate-vertical-scrolling-in-flex-advanceddatagrid-when-dragging-item-be
protected function autoScoll(dropIndex:int):void
{
var rowsDisplayed:Number = rowCount;
var topvisibleIndex:int = verticalScrollPosition;
var botvisibleIndex:int = topvisibleIndex + rowsDisplayed;
if (dropIndex <= topvisibleIndex)
{
verticalScrollPosition = Math.max(verticalScrollPosition - 1, 0);
}
else if (dropIndex >= botvisibleIndex - 1 && dropIndex < (rowCount + maxVerticalScrollPosition - 1))
{
verticalScrollPosition += 1;
}
}

Got to love Flex, man. Where the obvious stuff takes a ton of time.
So this is what I ended up doing:
mygrid.addEventListener( DragEvent.DRAG_OVER, handleDragOver);
public function handlerDragOver(event:DragEvent):void{
var dropIndex:int = mygrid.calculateDropIndex(event);
var rowsDisplayed:Number = mygrid.rowCount;
var topvisibleIndex:int = mygrid.verticalScrollPosition;
var botvisibleIndex:int = topvisibleIndex + rowsDisplayed;
if ( dropIndex <= topvisibleIndex) {
mygrid.verticalScrollPosition = Math.max( mygrid.verticalScrollPosition- 1, 0 );
} else if( dropIndex >= botvisibleIndex - 1 ){
mygrid.verticalScrollPosition += 1;
}
}

Related

CreateJS Tick function not updating from external values.

I think this might be quite basic, I'm still learning CreateJS. I won't include all the code as its a large program but basically.
Outside of my tick function I have this code:
var hitOrMiss = 'Mada';
function hit()
{
hitOrMiss = 'Hit';
//alert(hitOrMiss);
}
function miss()
{
hitOrMiss = 'Miss';
//alert(hitOrMiss);
}
When I click a button and call these they are testing ok (alerting out the values).
Inside my tick() function the values are not being picked up.
if(hitOrMiss = 'Mada')
{
var basic = 'basic';
}
else if(hitOrMiss = 'Hit')
{
if(gamePrincessBmpAnimation.x < 1000)
{
gamePrincessBmpAnimation.x += gamePrincessBmpAnimation.vX;
var basic = 'Not basic';
}
}
else if(hitOrMiss = 'Miss')
{
if(gamePrincessBmpAnimation.x > 60)
{
gamePrincessBmpAnimation.x -+ gamePrincessBmpAnimation.vX;
var basic = 'Miss Not basic';
}
}
Do I need to specify a listener, if so how should it be set up?
I have already triggered the below, Does something similar need to be added to the tick function?
createjs.Ticker.addListener(window);
createjs.Ticker.useRAF = true;
createjs.Ticker.setFPS(60);
gameStage.update();
The other if statements within the tick function are all firing, an example of which:
if (bmpAnimation.x >= screen_width - 16) {
// We've reached right side of our screen
// We need to walk left to go back to our initial position
bmpAnimation.direction = -90;
}
Any help would be appreciated! :)
Fixed this one, wasn't a createJS issue, was a silly Javascript issue, the code here: else if(hitOrMiss = 'Hit') should have been else if(hitOrMiss == 'Hit') etc.

ManipulationDelta on pivot item only fires once

I am trying to animate an image based on the select pivoted items position.
I am currently using the ManipulationDelta event to try and see which direction the user is swiping so that I can fade out or fade in an animated image based on the position of the pivot item.
My problem is with the ManipulationDelta event, this event is only ever called once on a pivot item, regardless of how much manipulation of the pivot control is occurring.
Does anyone know a way to make it so the pivot items ManpulationDelta event is constantly called when it is being manipulated?
Probably your Pivot is intercepting further events. You may try to do such a thing - disable Pivot (then your Manipulations should work) and change PivotItems manually for example using TouchPanel and Touch.FrameReported. Sample code:
public MainPage()
{
InitializeComponent();
myPivot.IsHitTestVisible = false; // disable your Pivot
Touch.FrameReported += Touch_FrameReported;
TouchPanel.EnabledGestures = GestureType.HorizontalDrag;
}
TouchPoint first;
private const int detectRightGesture = 20;
private void Touch_FrameReported(object sender, TouchFrameEventArgs e)
{
TouchPoint mainTouch = e.GetPrimaryTouchPoint(this);
if (mainTouch.Action == TouchAction.Down)
first = mainTouch;
else if (mainTouch.Action == TouchAction.Up && TouchPanel.IsGestureAvailable)
{
if (mainTouch.Position.X - first.Position.X < -detectRightGesture)
{
if (myPivot.SelectedIndex < myPivot.Items.Count - 1) myPivot.SelectedIndex++;
else myPivot.SelectedIndex = 0;
}
else if (mainTouch.Position.X - first.Position.X > detectRightGesture)
{
if (myPivot.SelectedIndex > 0) myPivot.SelectedIndex--;
else myPivot.SelectedIndex = myPivot.Items.Count - 1;
}
}
}

epplus: How do I get a row's height after setting column's wraptext style to true?

After I set a column's WrapText=true, I want to see what the new height of the row will be (i.e. if the text wraps, for how many lines). It appears that the Height property of a row is not updated.
ExcelPackage pkg = new ExcelPackage();
ExcelWorksheet sheet = pkg.Workbook.Worksheets.Add("Test");
// height is 15.0
double heightBefore = sheet.Row(1).Height;
sheet.Cells[1, 1].Value = "Now is the time for all good men to come to the aid of their country";
ExcelColumn col = sheet.Column(1);
// this will resize the width to 60
col.AutoFit();
if (col.Width > 50)
{
col.Width = 50;
// this is just a style property, and doesn't actually execute any recalculations
col.Style.WrapText = true;
}
// so this is still 15.0. How do I get it to compute what the size will be?
double heightAfter = sheet.Row(1).Height;
// open the xls, and the height is 30.0
pkg.SaveAs(new System.IO.FileInfo("text.xlsx"));
In fact, a search for the Height property (or the underlying field _height) shows that it is only set by the property setter, and does not ever seem to be set based on anything else (like content in the row).
Any ideas on how I can get a refreshed Height for a row?
Thanks
The general pattern I've noticed with EPPlus is that it generates the framework of the document with the minimum amount of information necessary. Then, when you open the file, Excel fills out the remaining XML structure, which is why you always have to save the file after opening an EPPlus generated document.
For your question, I'm assuming that Excel is updating the row heights after you open the Excel file so EPPlus would not have the updated row height information. I'm not absolutely certain that the library doesn't support this, but like you I was unable to find a way to get the updated values.
One workaround however could be to just calculate what the value would be since you know your text length and column width:
ExcelPackage pkg = new ExcelPackage();
ExcelWorksheet sheet = pkg.Workbook.Worksheets.Add("Test");
// height is 15.0
double heightBefore = sheet.Row(1).Height;
var someText = "Now is the time for all good men to come to the aid of their country. Typewriters were once ground-breaking machines.";
sheet.Cells[1, 1].Value = someText;
ExcelColumn col = sheet.Column(1);
ExcelRow row = sheet.Row(1);
// this will resize the width to 60
col.AutoFit();
if (col.Width > 50)
{
col.Width = 50;
// this is just a style property, and doesn't actually execute any recalculations
col.Style.WrapText = true;
}
// calculate the approximate row height and set the value;
var lineCount = GetLineCount(someText, (int)col.Width);
row.Height = heightBefore * lineCount;
// open the xls, and the height is 45.0
pkg.SaveAs(new System.IO.FileInfo("text.xlsx"));
Here's the method to calculate the number of lines:
private int GetLineCount(String text, int columnWidth)
{
var lineCount = 1;
var textPosition = 0;
while (textPosition <= text.Length)
{
textPosition = Math.Min(textPosition + columnWidth, text.Length);
if (textPosition == text.Length)
break;
if (text[textPosition - 1] == ' ' || text[textPosition] == ' ')
{
lineCount++;
textPosition++;
}
else
{
textPosition = text.LastIndexOf(' ', textPosition) + 1;
var nextSpaceIndex = text.IndexOf(' ', textPosition);
if (nextSpaceIndex - textPosition >= columnWidth)
{
lineCount += (nextSpaceIndex - textPosition) / columnWidth;
textPosition = textPosition + columnWidth;
}
else
lineCount++;
}
}
return lineCount;
}
One thing to keep in mind is that Excel has a max row height of 409.5 so you'll want to make sure your column width is not so narrow that you'll reach this limit.
Also, another thing I noticed is that the column widths that you manually set with EPPlus don't actually set the columns to the expected value. For example, if you set your column width to 50, you'll notice that the actual column width is set to 49.29 so you may want to factor that in as well.

How to render a GWT widget with a clickhandler GWT with a custom table builder?

I'm trying to use a GWT 2.5rc1 custom tablebuilder to render a subtable for each row in my datagrid. I've followed the example in the 2.5 rc1 showcase (url: http://showcase2.jlabanca-testing.appspot.com/#!CwCustomDataGrid).
I'm able to see the newly added sub-rows, but the problem comes when I want to add a clickhandler to a subrow anchor element.. the clickhandler is never invoked, which it seems also quite clear to me since I'm not "registering" the event handler anywhere.
Here the code I'm using now, "relevant part":
private void buildRegRow(Registrazione rowValue,final int absRowIndex, boolean isCommentRow) {
// Calculate the row styles.
SelectionModel<? super Registrazione> selectionModel = cellTable.getSelectionModel();
boolean isSelected =
(selectionModel == null || rowValue == null) ? false : selectionModel
.isSelected(rowValue);
boolean isEven = absRowIndex % 2 == 0;
StringBuilder trClasses = new StringBuilder(rowStyle);
if (isSelected) {
trClasses.append(selectedRowStyle);
}
// Calculate the cell styles.
String cellStyles = cellStyle;
if (isSelected) {
cellStyles += selectedCellStyle;
}
if(isCommentRow)
cellStyles += childCell;
TableRowBuilder row = startRow();
row.className(trClasses.toString());
/*
* Checkbox column.
*
* This table will uses a checkbox column for selection. Alternatively,
* you can call dataGrid.setSelectionEnabled(true) to enable mouse
* selection.
*/
TableCellBuilder td = row.startTD();
td.className(cellStyles);
td.style().outlineStyle(OutlineStyle.NONE).endStyle();
if (!isCommentRow) {
renderCell(td, createContext(0), cellTable.getColumn(0), rowValue);
}
td.endTD();
/*
* View children column.
*
* Displays a link to "show children". When clicked, the list of friends is
* displayed below the contact.
*/
td = row.startTD();
td.className(cellStyles);
if(!isCommentRow) {
td.style().outlineStyle(OutlineStyle.NONE).endStyle();
if(rowValue.hasComments())
//td.className(CellTableResource.INSTANCE.dataGridStyle().showChildren());
renderCell(td, createContext(1), cellTable.getColumn(1), rowValue);
} else {
td.colSpan(getColumns().size() - 1);
// // Draw sub-table header
TableBuilder subTable = td.startTable();
TableSectionBuilder subTableSection = subTable.startTHead();
TableRowBuilder tr2 = subTableSection.startTR();
TableCellBuilder td2 = tr2.startTH();
td2.text(msgs.date());
tr2.endTH();
td2 = tr2.startTH();
td2.text(msgs.username());
tr2.endTH();
td2 = tr2.startTH();
td2.text(msgs.comment());
tr2.endTH();
td2 = tr2.startTH();
td2.text(msgs.actions());
tr2.endTH();
subTableSection.endTR();
subTable.endTHead();
subTableSection = subTable.startTBody();
for(final EntityComment ec : rowValue.getCommentList()) {
tr2 = subTableSection.startTR();
// Date
td2 = tr2.startTD();
td2.text(DateUtil.getDefaultDateTimeFormat().format(ec.getCreationDate()));
tr2.endTD();
// Username
td2 = tr2.startTD();
td2.text(ec.getUsername());
tr2.endTD();
// Text
td2 = tr2.startTD();
td2.text(ec.getText());
tr2.endTD();
// Actions
td2 = tr2.startTD();
// Remove
Anchor removeAnchor = new Anchor("remove");
removeAnchor.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
Window.alert("clicked");
}
});
td2.html(new SafeHtmlBuilder().appendHtmlConstant(removeAnchor.toString()).toSafeHtml());
tr2.endTD();
subTableSection.endTR();
}
subTable.endTBody();
td.endTable();
}
td.endTD();
for(int i = 2; i <= 6; i++) {
// Recorded, list name, callcenter, msisdn
td = row.startTD();
td.className(cellStyles);
td.style().outlineStyle(OutlineStyle.NONE).endStyle();
if(!isCommentRow) {
renderCell(td, createContext(i), cellTable.getColumn(i), rowValue);
}
td.endTD();
}
row.endTR();
}
The subtable shows up, with an anchor at the correct position, but the clickhandler is never invoked. I do not know how to write the handler code to the page, like I've done to render the anchor.
Thanks for any help.
I have tried custom tablebuilder and created a grid. You can add any element using the proper structure. Make sure you set the Unique Id to each element you create. Then through code access the element through the following code,
Element e = DOM.getElementById( id );
Cast the element to its proper widget i.e, if you are using text input element you can always cast it to textbox. To cast the element there is one more step which you can google out. Then add the clickhandler or whichever handler you want.

Refresh a dijit.form.Select

First, you have to know that I am developing my project with Struts (J2EE
Here is my problem :
I have 2 dijit.form.Select widgets in my page, and those Select are filled with the same list (returned by a Java class).
When I select an option in my 1st "Select widget", I would like to update my 2nd Select widget, and disable the selected options from my 1st widget (to prevent users to select the same item twice).
I succeed doing this (I'll show you my code later), but my problem is that when I open my 2nd list, even once, it will never be refreshed again. So I can play a long time with my 1st Select, and choose many other options, the only option disabled in my 2nd list is the first I've selected.
Here is my JS Code :
function removeSelectedOption(){
var list1 = dijit.byId("codeModif1");
var list2 = dijit.byId("codeModif2");
var list1SelectedOptionValue = list1.get("value");
if(list1SelectedOptionValue!= null){
list2.reset();
for(var i = 0; i < myListSize; i++){
// If the value of the current option = my selected option from list1
if(liste2.getOptions(i).value == list1SelectedOptionValue){
list2.getOptions(i).disabled = true;
} else {
list2.getOptions(i).disabled = false;
}
}
}
Thanks for your help
Regards
I think you have to reset() the Select after you've updated its options' properties. Something like:
function removeSelectedOption(value)
{
var list2 = dijit.byId("codeModif2"),
prev = list2.get('value');
for(var i = 0; i < myListSize; i++)
{
var opt = myList[i];
opt.disabled = opt.value === value;
list2.updateOption(opt);
}
list2.reset();
// Set selection again, unless it was the newly disabled one.
if(prev !== value) list2.set('value', prev);
};
(I'm assuming you have a myList containing the possible options here, and the accompanying myListSize.)