Using sortItemsOn() to change the order data appears on datagrid - actionscript-3

I am attemtping to use the sortItemsOn() function as shown in the code below to make it so that after the DataProvider changes data and triggers a CollectionEvent, that the order the datagrid displays the data is descending instead of ascending.
<fx:Script>
<![CDATA[
private function onDataGridDataChange(evt:CollectionEvent):void
{
Alert.show("I made it here");
table.sortItemsOn("feature1",Array.DESCENDING)
}
]]>
</fx:Script>
<mx:DataGrid id="table" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn dataField="#feature1`" headerText="col1" />
<mx:DataGridColumn dataField="#feature2" headerText="col2" />
</mx:columns>
<mx:dataProvider>
{xmllist_changesEvery30Seconds}
</mx:dataProvider>
</mx:DataGrid>
The Alert in the function will show when the XMLList gets updated automatically, however, the sort is still the same. My end goal is to make it so that the order of the sort is descending instead of ascending. I am under the impression I might not be passing in the correct parameters. However I can't be certain. How do I use the function to have it sort in descending order after the dataProvider when the function is called in response to a change of data?

Related

Actionscript 3 setStyle is not a function

I am trying to style a Flex 4 GridItem using actionscript, I have tried the following:
<mx:VBox
height="878" width="1920"
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:s="library://ns.adobe.com/flex/spark" xmlns:local="*" creationComplete="addStyles()">
<mx:Script>
<![CDATA[
public var selectedLot:String = "";
private function addStyles():void
{
testBorder.setStyle("borderThickness", "3");
}
but I get the following error:
setStyle is not a function.
Am I missing something?
The GridItem is inside a repeater.
Here is my GridItem:
<mx:GridItem id="testBorder" width="101" height="52.25" horizontalAlign="center" verticalAlign="middle" borderStyle="solid" borderColor="gray">
<mx:Image source="assets/ruler-icon.png" />
<s:Label text="{r.currentItem.sqft}" fontSize="10" color="#808080" fontFamily="Helvetica" />
</mx:GridItem>
When using a repeater the GridItem's id will not be the same. To access any item inside a repeater you have to specify an index which is correspondent to the repeated item.
Example: Array consists of ["Audi", "BMW"], we set this array to your repeater's dataProvider, then to access "Audi"'s grid item and set its style, we have to use:
testBorder[0].setStyle("borderThickness", "3");
Additionally, an important point to consider, the VBox "creationComplete" can be executed before the repeater is fully built, therefore, the best place to call your function "addStyles" is in the repeater's "repeatEnd" event i.e (repeatEnd="setTransactionPropertyType()").
Hope this helps,
Goodluck.

Items in DataGrid not initialized as expected

I seem to have a problem of items not being created as expected, resulting in event-listeners not being fired.
I am using a DataGrid column of checkboxes as seen here:
<mx:DataGrid id="gridComponents" height="100%">
<mx:columns>
<fwctrl:DataGridCheckBoxColumn id="colChkBox" width="20" selectionChanged="onGridChbBoxChange(event)" />
<mx:DataGridColumn headerText="Components" dataField="name" width="250"/>
</mx:columns>
</mx:DataGrid>
(fwctrl is the namespace of an internal library.)
And here is what the mxml of fwctrl:DataGridCheckBoxColumn looks like:
<mx:DataGridColumn xmlns:mx="http://www.adobe.com/2006/mxml" resizable="false" xmlns:grid="fwctrl.grid.*" xmlns:CheckBoxColumn="fwctrl.grid.CheckBoxColumn.*">
<mx:Metadata>
[Event(name="selectionChanged", type="fwctrl.grid.CheckBoxColumn.DataColumnCheckBoxEvent")]
</mx:Metadata>
<mx:Script>
<![CDATA[
...
]]>
</mx:Script>
<mx:headerRenderer>
<mx:Component>
<CheckBoxColumn:CheckBoxHeaderRenderer textAlign="center" click="checkboxheaderrenderer1_clickHandler(event)">
<mx:Script>
...
</mx:Script>
</CheckBoxColumn:CheckBoxHeaderRenderer>
</mx:Component>
</mx:headerRenderer>
<mx:itemRenderer>
<mx:Component>
<mx:Box horizontalAlign="center"
verticalAlign="middle" enabled="{outerDocument.isEnabled}">
<mx:Script>
<![CDATA[
...
protected function checkBox_initializeHandler(event:FlexEvent):void
{
trace("init checkbox");
}
]]>
</mx:Script>
<mx:CheckBox id="checkBox" click="onCheckBoxClick()" change="onChange(event)" initialize="checkBox_initializeHandler(event)"/>
</mx:Box>
</mx:Component>
</mx:itemRenderer>
CheckBoxHeaderRenderer is a class that inherits from checkbox.
using the mxml above I bind an ArrayCollection to the data provide by doing: gridComponents.dataProvider = coll;
Having the checkBox_initializeHandler event bound, I expect to see a message printed for each element in my collection.
In reality, the message will only be displayed for element that don't "fall off the grid", i.e. if there is a scroll bar (due to a lot of items being rendered), the items that are below the bottom of the grid (i.e. the ones that need to be scrolled to) will not print a message.
This also means that they are not created correctly and that the click="onCheckBoxClick()" is not hooked correctly and that onCheckBoxClick() does not get triggered.
Why is this happening and how can I fix this?
In Flex, itemRenderers aren't created on a one-to-one basis with your underlying data collection. You only get enough instances to display one screen's worth of data, and those instances get reused as you scroll.
To handle this in your code, refactor so that your click handler in the itemRenderer updates a property in your dataCollection (e.g. data.foo = true;).

Sorting an Advanced DataGrid with Grouping Collection

I crate an avanced datagrd and grouping option to display data.
In my case, I'd like to display list of author with their books.
<mx:AdvancedDataGrid height="350"
displayItemsExpanded="true">
<mx:dataProvider>
<mx:GroupingCollection2 id="groupingCollection"
source="{bookList}">
<mx:grouping>
<mx:Grouping>
<mx:GroupingField name="author"
/>
</mx:Grouping>
</mx:grouping>
</mx:GroupingCollection2>
</mx:dataProvider>
<mx:columns>
<mx:AdvancedDataGridColumn dataField="author"
width="150"/>
<mx:AdvancedDataGridColumn dataField="birthday"
width="100"/>
<mx:AdvancedDataGridColumn dataField="title"
width="250"/>
<mx:AdvancedDataGridColumn dataField="dateOfPublication"
width="150"
/>
</mx:columns>
But even if my dataprovider is order by dateOfPublication at the beginning, after grouping, order is lost in each group.
Do you know how to force re order by dateOfPublication each group?
Thanks
Yeah, the GroupingCollection2 seems to mangle the existing sort of the data source.
You need to define a sort function for each of the GroupFields - check out the documentation for GroupFields compareFunction. For example:
<mx:GroupingField name="author" compareFunction="sortByDate"/>
The compare function takes two objects (elements of your data source), and returns -1/0/1 if the first item is less-than/equals/greater-than the second item:
private function sortByDate(item1:Object, item2:Object) : int
{
// Whatever comparison function you want
}

How to get selectedItem from comboBox itemrenderer in datagrid and display value in another column

I am having an issue with itemRender in a datagrid. Actually I have a dataProvider which populates 2 columns in my datagrid. The first column data is rendered in a TextInput and the second column data is rendered in a comboBox. What I want now is that when I selected an element from the comboBox of a row in the grid. I want to show the selectedItem value in the corresponding TextInput on the same row of the first column.
I want to know if there is any datagrid property that can help me do this? Or if someone can guide me what to code in the change handler of the comboBox? See my codes below.
I need help. Pls sort this out for me someone.
<mx:DataGrid id="myDG" rowHeight="25" dataProvider="{my_arrayColl}" width="100%" height="205" chromeColor="#D0CCAF" headerHeight="0" showHeaders="false">
<mx:columns>
<mx:DataGridColumn headerText="My Header 1"
editable="true"
dataField="LBL"
>
<mx:itemRenderer>
<fx:Component>
<mx:HBox horizontalAlign="left" horizontalScrollPolicy="off" verticalScrollPolicy="off">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.controls.Text;
import spark.events.TextOperationEvent;
protected function label_txt_changeHandler(event:TextOperationEvent):void
{
data.LBL = label_txt.text;
}
]]>
</fx:Script>
<s:TextInput id="label_txt" change="label_txt_changeHandler(event)" text="{data.LBL}" width="98%"/>
</mx:HBox>
</fx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn headerText="My Header 2"
editable="true"
rendererIsEditor="true"
dataField="ALIAS"
>
<mx:itemRenderer>
<fx:Component>
<mx:ComboBox height="80%" change="mycb_changeHandler(event)" labelField="ALIAS" dataProvider="{outerDocument.mycb_array}">
<fx:Script>
<![CDATA[
import mx.events.ListEvent;
protected function mycb_changeHandler(event:ListEvent):void
{
}
]]>
</fx:Script>
</mx:ComboBox>
</fx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
If I understand it correctly, you want to update the dataprovider of DataGrid, based on selection in your ComboBox component in itemRenderer. You can do that by going to the owner object and updating the respective object in data. Just keep itemRenderer in a separate mxml and put your debug pointer in label_txt_changeHandler method.
Hope it helps..

How to access other panels in Flex 3 ViewStack?

I have a ViewStack with 2 panels:
<mx:ViewStack id="viewstack1" height="243">
<mx:Panel id="gridPanel">
<mx:DataGrid id="grid" right="10" left="10" top="10" bottom="10" width="300" height="150" itemClick="showDetails(event)">
<mx:columns>
<mx:DataGridColumn headerText="ID" dataField="Id"/>
<mx:DataGridColumn headerText="Summary" dataField="Summary"/>
</mx:columns>
</mx:DataGrid>
</mx:Panel>
<mx:Panel id="detailsPanel">
<mx:HBox width="100%" height="100%">
<mx:VBox height="100%" width="228" id="detailsVbox">
<mx:Label text="Label" id="itemTitle"/>
<mx:Text text="Text" id="itemSummary"/>
<mx:DataGrid height="97">
<mx:columns>
<mx:DataGridColumn headerText="Property" dataField="col1"/>
<mx:DataGridColumn headerText="Value" dataField="col2"/>
</mx:columns>
</mx:DataGrid>
</mx:VBox>
<mx:Image source="images/BackButton.png" width="50" height="50" click="viewstack1.selectedChild = gridPanel"/>
</mx:HBox>
</mx:Panel>
</mx:ViewStack>
I want to have the user click a grid item in the first panel and then load the data in a panel in the second panel. I can grab the value of the index for the clicked item in the itemClicked handler, but how do I access the detailsPanel to set the values based on the row info from the Grid?
I'm not sure if this is what you want, but you can do something like this:
private function showDetails(event:ListEvent):void {
itemTitle.text = event.itemRenderer.data.Id;
itemSummary.text = event.itemRenderer.data.Summary;
//assuming that the datagrid ID from the details panel is: detailsDatagrid
detailsDatagrid.dataProvider = event.itemRenderer.data.Properties;
viewstack1.selectedChild = detailsPanel;
}
In order for this to work you will also have to add a creation policy to the viewstack.
<mx:ViewStack id="viewstack1" height="243" creationPolicy="all">
This way all panels are going to be created when the viewstack is created (by default they are created only when they are needed). This ensures that you will have a reference the detailsPanel, itemTitle, itemSummary, etc... before the panel is visible.
As for me the best way is to use data binding. Just introduce additional field
[Bindable]
private var detailsDataProvider:ArrayCollection;
And fill it with details in showDetails method. If details data need to be obtained asynchronously (from server, for example) you can reset current details value until data received:
detailsDataProvider = null;
And then populate it with server data.
The final changes are in details data grid:
<mx:DataGrid height="97" dataProvider="{detailsDataProvider}">
Hope it helps.
Here this code will explain 'stackview' simple example. Using this can call panel as same.