AdvancedDataGrid editable property issue - actionscript-3

I have an AdvancedDataGrid control with two columns UserName and eSigner. Which looks like:
Code for this:
<mx:AdvancedDataGrid id="UserGroupGrid" left="10" bottom="40" right="10" editable="true" height="226">
<mx:dataProvider>
<mx:GroupingCollection id="gc" source="{UserGroupList}">
<mx:Grouping>
<mx:GroupingField name="UserGroupName"/>
</mx:Grouping>
</mx:GroupingCollection>
</mx:dataProvider>
<mx:columns>
<mx:AdvancedDataGridColumn textAlign="left" headerText="UserName" dataField="UserName" editable="false"/>
<mx:AdvancedDataGridColumn width="100" dataField="eSignor" headerText="eSigner" editable="true" textAlign="center" rendererIsEditor="true" editorDataField="cbSelected" editorYOffset="30">
<mx:itemRenderer>
<mx:Component>
<mx:HBox horizontalAlign="center">
<mx:Script>
<![CDATA[
public var cbSelected:Boolean;
]]>
</mx:Script>
<mx:CheckBox id="SignorCk" width="10" selected="{data.eSignor}" enabled="true" click="cbSelected = SignorCk.selected;" visible="{data.eSignor == null ? false : true}"/>
</mx:HBox>
</mx:Component>
</mx:itemRenderer>
</mx:AdvancedDataGridColumn>
</mx:columns>
</mx:AdvancedDataGrid>
As you can see in the code I want the column UserName to be non-editable and column eSigner to be editable. When I load up the page I am running into an issue where the grouping header Accounts Payable becomes editable. This happens when I click on Accounts Payable and then click somewhere off the browser and then click back on Accounts Payable again. It looks like this:
I have tried this with less success. Since the column UserName has the editable set to false I wonder what is going on here.

itemEditBegin="preventEdit(event);"
The property above does the trick here. In the code posted, just add this property.
<mx:AdvancedDataGrid id="UserGroupGrid" itemEditBegin="preventEdit(event);" left="10" bottom="40" right="10" editable="true" height="226">
In the script tag add the function:
private function preventEdit(event:AdvancedDataGridEvent):void
{
if(event.itemRenderer.data.UserName == null)
event.preventDefault();
}
Whenever we focus out and focus back in, on the grouping header, this would call the preventEdit function and that would cancel the events' default behavior of editing. I think this is just a workaround, hope they've fixed all this in Flex 4.
Source: Adobe

Related

Flex - Set Editable propertie programmatically for a GridColumn

Is it possible to dynamically change the property "Editable" of a GridColumn regarding the value of an another Column.
Once I have filled my dataProvider I would like to loop ont he dataGrid rows, but I can't find how to it ?
Thanks.
I tried
editable="{if (data['Type']=='foo'){return true;} else {return false;}}"
but build failed.
How about to use itemRenderer?
<s:GridColumn dataField="Type" width="100" editable="false"/>
<s:GridColumn dataField="Name" width="100" editable="false"/>
<s:GridColumn dataField="Score" width="100" editable="true" rendererIsEditable="true">
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<fx:Script>
<![CDATA[
override public function set data(value:Object):void {
if (value != null && value != "") {
super.data = value;
if (super.data["Type"] == "foo"){
somefield.editable = true;
}
else{
somefield.editable = false;
}
}
}
]]>
</fx:Script>
<s:TextInput id="somefield" text="{data.Score}"/>
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
Run example on wonderfl
Thanks. In fact I use ItemEditor and/or ItemRenderer for some columns.
In my case I have
<s:GridColumn id="gcAmountEUR" labelFunction="amountFormat" dataField="AmountEUR" headerText="AMOUNT EUR" width="80" itemEditor="components.gieOrderAmount">
<s:itemRenderer>
<fx:Component>
<s:DefaultGridItemRenderer textAlign="right" />
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
<s:GridColumn dataField="CurrencyCode" headerText="CURRENCY" width="50" itemEditor="components.gieOrderCurrency" >
</s:GridColumn>
<s:GridColumn id="gcAmount" labelFunction="amountFormat" dataField="Amount" headerText="AMOUNT" width="120" itemEditor="components.gieOrderAmount">
<s:itemRenderer>
<fx:Component>
<s:DefaultGridItemRenderer textAlign="right" />
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
The datagrig has the property editable="true".
By default the column AmountEUR is Editable an the column Amount is not.
But if for a row the value of Currency is not "" so I want AmountEUR to be not Editable and Amount to be Editable. So I would like to programmatically change the property Editable of the column for each row.
So I would like to parse the datagrid to change, for each row, the property value "Editable" of AmountEUR and Amount if Currency is not Empty.
But perhaps it is not the good way to do it ?
I hope I made myself clear.
Antoine.

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;).

Flex 3.2: FlexPrintJob outputs PrintDataGrid one row per page

I am trying to print a table in Flex 3.2 using FlexPrintJob. I need normal printing behavior - one page if all rows fit on a single page, full page(s) of rows followed by a partially filled page if there is enough data to fill more than one page. Somehow, I get a page per row, where each page has a table header, followed by one row of data, followed by empty space.
Table with 15 rows results in a 15 page document. I get the same behavior in Firefox and IE8.
What can be causing this behavior?
Thanks for your help!
Here's the code:
// The function to print the output.
public function onPrint():void {
var printJob:FlexPrintJob = new FlexPrintJob();
printJob.start();
var thePrintView:FormPrintView = new FormPrintView();
addChild(thePrintView);
thePrintView.initPrintDataGrid(openSequences);
// thePrintView.printOpenTimeGrid.dataProvider = printOpenTime.dataProvider;
thePrintView.validateNow();
thePrintView.width=printJob.pageWidth;
thePrintView.height=printJob.pageHeight;
printJob.addObject(thePrintView, FlexPrintJobScaleType.MATCH_WIDTH);
while (thePrintView.printOpenTimeGrid.validNextPage) {
//Put the next page of data in the view.
thePrintView.printOpenTimeGrid.nextPage();
//Queue the additional page.
printJob.addObject(thePrintView, FlexPrintJobScaleType.MATCH_WIDTH);
}
printJob.send();
removeChild(thePrintView);
this.onClose();
}
PrintDataGrid is located directly in the TitleWindow object:
<!-- The data grid. The sizeToPage property is true by default, so the last
page has only as many grid rows as are needed for the data. -->
<mx:PrintDataGrid id="printOpenTimeGrid" dataProvider="{openSequences}" sizeToPage="true" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn dataField="startDate" headerText="Seq Date" width="70">
<mx:itemRenderer>
<mx:Component>
<mx:VBox>
<mx:DateFormatter id="startDateFormatter" formatString="M/D/YYY"/>
<mx:Label fontWeight="bold" text="{startDateFormatter.format(data.startDate)}"/>
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn dataField="equipCode" headerText="EQP" width="40" />
<mx:DataGridColumn dataField="base" headerText="BSE" width="40" />
<mx:DataGridColumn dataField="sequenceNumber" headerText="SEQNO" width="45" />
<mx:DataGridColumn dataField="seat" headerText="ST" width="40" />
<mx:DataGridColumn headerText="DPRT" width="40">
<mx:itemRenderer>
<mx:Component>
<mx:VBox>
<mx:DateFormatter id="departTimeFormatter" formatString="JJNN"/>
<mx:Label fontWeight="bold" text="{departTimeFormatter.format(data.startDate)}"/>
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn dataField="terminationDate" headerText="ARVL/DT" width="60" >
<mx:itemRenderer>
<mx:Component>
<mx:VBox>
<mx:DateFormatter id="arvDateFormatter" formatString="JJNN/DD"/>
<mx:Label fontWeight="bold" text="{arvDateFormatter.format(data.startDate)}"/>
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn dataField="tripValue" headerText="TTL" width="50" />
<mx:DataGridColumn dataField="blockType" headerText="Block Type" width="170" />
</mx:columns>
</mx:PrintDataGrid>
Printout looks like this
The problem is solved by adding a 'height' parameter to the TitledWindow object (the wrapper of the PrintDataGrid). When height is set to 800, content prints onto a full page, and does't show a scroll bar.
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" title="Open Time" height="800">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.core.*;
[Bindable]
private var openSequences:ArrayCollection;
public function initPrintDataGrid(sequences:ArrayCollection):void {
openSequences = sequences;
}
]]>
</mx:Script>
<!-- The data grid. The sizeToPage property is true by default, so the last
page has only as many grid rows as are needed for the data. -->
<mx:PrintDataGrid id="printOpenTimeGrid" dataProvider="{openSequences}" sizeToPage="true"
width="100%" height="100%">
<mx:columns>

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.