I have a several datagrids (with data being retrieved from some map service).
I want to place these data grids within seperate tabs of a tab navigator. All works fine apart from the first tab which always ends up without any datagrid in it.
I have tried creation policy="all" and stuff but the first tab always is empty. Does anybody have any ideas as to why the first tab is always empty.
Any workarounds.
Thanks
var box:HBox=new HBox();
var dg:DataGrid = new DataGrid();
dg.dataProvider = newAC;
box.label=title.text;
box.addChild(dg);
tabNaviId.addChild(box);
tabNaviId.selectedIndex=2;
resultsArea.addChild(tabNaviId);
dg is datagrid that is being filled up. The above code is in a loop, in each loop i am creating an Hbox+datagrid. then i am adding the Hbox to the navigator and final adding the navigator to resultsArea (which is a canvas).
The above code works great apart from first time.
The end result i get is, having a tab navigator with first tab without any datagrid but the remaining tabs all have the datagrids. Any ideas as to why this is happening.
Call to a function called createDatagrid is made:
dgCollection.addItem(parentApplication.resultsPanel.createDatagrid( token.name.toString() + " (" + recAC.length + " selected)", recAC, false, callsToMake ));
In another Mxml component this function exists
public function createDatagrid(titleText:String, recACAll:ArrayCollection, showContent:Boolean, callsToMake:Number):DataGrid
{
var dg:DataGrid = new DataGrid();
var newAC:ArrayCollection = new ArrayCollection();
var newDGCols:Array = new Array();
for( var i:Number = 0; i < recACAll.length; i ++)
{
var contentStr:String = recACAll[i][CONTENT_FIELD];
var featureGeo:Geometry = recACAll[i][GEOMETRY_FIELD];
var iconPath:String = recACAll[i][ICON_FIELD];
var linkStr:String = recACAll[i][LINK_FIELD];
var linkNameStr:String = recACAll[i][LINK_NAME_FIELD];
var featurePoint:MapPoint = recACAll[i][POINT_FIELD];
var titleStr:String = recACAll[i][TITLE_FIELD];
if( contentStr.length > 0)
{
var rows:Array = contentStr.split("\n");
var tmpObj:Object = new Object();
if(!showContent)
{
for( var j:Number = 0; j < rows.length; j++)
{
var tmpStr:String = rows[j] as String;
var header:String = tmpStr.substring(0,tmpStr.indexOf(":"));
var val:String = tmpStr.substring(tmpStr.indexOf(":") + 2);
if(header.length > 0)
{
tmpObj[header] = val;
if(newDGCols.length < rows.length - 1)
{
newDGCols.push( new DataGridColumn(header));
}
}
}
}
else
{
if(newDGCols.length == 0)
{
newDGCols.push(new DataGridColumn(CONTENT_FIELD));
newDGCols.push(new DataGridColumn(GEOMETRY_FIELD));
newDGCols.push(new DataGridColumn(ICON_FIELD));
newDGCols.push(new DataGridColumn(LINK_FIELD));
newDGCols.push(new DataGridColumn(LINK_NAME_FIELD));
newDGCols.push(new DataGridColumn(POINT_FIELD));
newDGCols.push(new DataGridColumn(TITLE_FIELD));
}
}
tmpObj[CONTENT_FIELD] = contentStr;
tmpObj[GEOMETRY_FIELD] = featureGeo;
tmpObj[ICON_FIELD] = iconPath;
tmpObj[LINK_FIELD] = linkStr;
tmpObj[LINK_NAME_FIELD] = linkNameStr;
tmpObj[POINT_FIELD] = featurePoint;
tmpObj[TITLE_FIELD] = titleStr;
newAC.addItem(tmpObj);
}
if( showHidePic.source == minSourceI )
{
showHidePic.source = minSource;
}
else if( showHidePic.source == maxSourceI )
{
showHidePic.source = maxSource;
}
curResults = curResults + recACAll.length;
if (curResults == 1)
{
showInfoWindow(tmpObj);
if(showContent)
{
parentApplication.maps.map.extent = featureGeo.extent;
}
}
else
{
showInfoWindow(null);
// Added to avoid the overview button problem (needs checking)
this.removeEventListener(MouseEvent.MOUSE_OVER, handleMouseOver, false);
this.removeEventListener(MouseEvent.MOUSE_MOVE,handleMouseOver,false);
this.removeEventListener(MouseEvent.MOUSE_OUT,handleMouseOut,false);
this.removeEventListener(MouseEvent.MOUSE_DOWN,handleMouseDrag,false);
this.removeEventListener(MouseEvent.MOUSE_UP,handleMouseDragStop,false);
this.parent.removeEventListener(MouseEvent.MOUSE_MOVE,handleParentMove,false);
this.parent.removeEventListener(MouseEvent.MOUSE_UP,handleMouseDragStop2,false);
maximizePanel();
}
}
dg.dataProvider = newAC;
dg.columns = newDGCols;
dg.rowCount = newAC.length;
var totalDGCWidth:Number = 0;
for( var m:Number = 0; m < dg.columns.length; m++)
{
var dgc2:DataGridColumn = dg.columns[m];
/*if(dgc2.headerText.toUpperCase()==LINK_FIELD.toUpperCase()){
//dgc.itemRenderer=new ClassFactory(CustomRenderer);
dgc2.itemRenderer=new ClassFactory(CustomRenderer);
}*/
var dgcWidth2:Number = dgc2.headerText.length * CHAR_LENGTH;
for( var l:Number = 0; l < newAC.length; l++)
{
var row2:Object = newAC.getItemAt(l) as Object;
var rowVal2:String = row2[dgc2.headerText];
if( rowVal2 != null)
{
var tmpLength2:Number = rowVal2.length * CHAR_LENGTH;
if(tmpLength2 < CHAR_MAX_LENGTH)
{
if(tmpLength2 > dgcWidth2)
{
dgcWidth2 = tmpLength2;
}
}
else
{
dgcWidth2 = CHAR_MAX_LENGTH
break;
}
}
}
// Added by FT:to change the item renderer for link field
if( dgc2.headerText == GEOMETRY_FIELD || dgc2.headerText == CONTENT_FIELD ||
dgc2.headerText == ICON_FIELD || dgc2.headerText == LINK_FIELD ||
dgc2.headerText == POINT_FIELD || dgc2.headerText == TITLE_FIELD ||
dgc2.headerText == LINK_NAME_FIELD)
{
if(dgc2.headerText == CONTENT_FIELD && showContent)
{
//something
}
else
{
dgcWidth2 = 0;
}
}
totalDGCWidth += dgcWidth2;
}
dg.width = totalDGCWidth;
for( var k:Number = 0; k < dg.columns.length; k++)
{
var dgc:DataGridColumn = dg.columns[k];
var dgcWidth:Number = dgc.headerText.length * CHAR_LENGTH;
for( var n:Number = 0; n < newAC.length; n++)
{
var row:Object = newAC.getItemAt(n) as Object;
var rowVal:String = row[dgc.headerText];
if(rowVal != null)
{
var tmpLength:Number = rowVal.length * CHAR_LENGTH;
if(tmpLength < CHAR_MAX_LENGTH)
{
if(tmpLength > dgcWidth)
{
dgcWidth = tmpLength;
}
}
else
{
dgcWidth = CHAR_MAX_LENGTH
break;
}
}
}
if( dgc.headerText == GEOMETRY_FIELD || dgc.headerText == CONTENT_FIELD ||
dgc.headerText == ICON_FIELD || dgc.headerText == LINK_FIELD ||
dgc.headerText == POINT_FIELD || dgc.headerText == TITLE_FIELD ||
dgc.headerText == LINK_NAME_FIELD)
{
if(dgc.headerText == CONTENT_FIELD && showContent)
{
dgc.visible = true;
}
else
{
dgc.visible = false;
dgcWidth = 0;
}
}
if( dgc.headerText == LINK_COL_NAME)
{
dgcWidth = LINK_COL_WIDTH;
}
dgc.width = dgcWidth;
}
dg.addEventListener(ListEvent.ITEM_CLICK,rowClicked);
dg.addEventListener(ListEvent.ITEM_ROLL_OVER,mouseOverRow);
dg.addEventListener(ListEvent.ITEM_ROLL_OUT,mouseOutRow);
var title:Text = new Text();
title.text = titleText;
title.setStyle("fontWeight","bold");
//resultsArea.addChild(title);
return dg;
//tabNaviId.selectedIndex=2;
}
public function populateGrid(dgCollection:ArrayCollection):void{
for( var k:Number = 0; k < dgCollection.length; k++)
{
var box:HBox=new HBox();
var dg2:DataGrid=dgCollection.getItemAt(k) as DataGrid;
box.label="some";
box.addChild(dg2);
tabNaviId.addChild(box);
}
resultsArea.addChild(tabNaviId);
}
and the tab navigator declared as
<mx:Image id="showHidePic" click="toggleResults()"/>
<mx:VBox y="20" styleName="ResultsArea" width="100%" height="100%">
<mx:HBox>
<mx:Button label="Export to Excel" click="downloadExcel()"/>
<mx:Button label="Clear" click="clear()" />
</mx:HBox>
<mx:VBox id="resultsArea" styleName="ResultsContent" paddingTop="10" paddingLeft="10" paddingRight="10" verticalScrollPolicy="off" horizontalScrollPolicy="off">
<mx:TabNavigator id="tabNaviId" width="622" height="274" creationPolicy="all">
</mx:TabNavigator>
</mx:VBox>
</mx:VBox>
Abstract, can we get the full code including the loop you mention, as well as the code where you create the TabNavigator?
It's possible that the TabNavigator already has an initial child, and all the children you're creating are being added after that.
Related
I am Working on a Shop page where I want the Dropdownlist show the available Quantity . (Eg: if stock contains 2 items then Dropdownlist contains Items 1 followed by 2..)
Here's the code I attempted , I have no idea in which event i should put it.
`
Code:
connect cu = new connect();
System.Web.UI.WebControls.Label Label8 = (System.Web.UI.WebControls.Label)DataList1.FindControl("modelnoLabel");
//Modelnolabel contains model no
cu.cmd.CommandText = "select qty from stock where modelno=#mod";
//qty is retrived based on modelnolabel text of datalist
cu.cmd.Parameters.Clear();
cu.cmd.Parameters.AddWithValue("#mod", Label8.Text);
int qty = Convert.ToInt16(cu.cmd.ExecuteScalar());
if (qty < 5 && qty > 0)
{
(DataList1.FindControl("DropDownList1") as DropDownList).Items.Clear();
for (int i = 1; i < qty + 1; i++)
{
(DataList1.FindControl("DropDownList1") as DropDownList).Items.Add(Convert.ToString(i));
}
}
else
{
(DataList1.FindControl("DropDownList1") as DropDownList).Visible = false;
}`
Thanks in advance
Thanks for the silence ,It really helped me figure out on my own :)
protected void DataList1_Load(object sender, EventArgs e)
{
for(int j=0;j<DataList1.Items.Count;j++)
{
System.Web.UI.WebControls.Label Label8 = (System.Web.UI.WebControls.Label)DataList1.Items[j].FindControl("modelnoLabel");
connect cu = new connect();
cu.cmd.CommandText = "select qty from stock where model=#mod";
cu.cmd.Parameters.Clear();
cu.cmd.Parameters.AddWithValue("#mod", Label8.Text);
int qty = Convert.ToInt16(cu.cmd.ExecuteScalar());
if (qty <= 5 && qty > 0)
{
(DataList1.Items[j].FindControl("DropDownList1") as DropDownList).Items.Clear();
for (int i = 1; i < qty+1; i++)
{
(DataList1.Items[j].FindControl("DropDownList1") as DropDownList).Items.Add(Convert.ToString(i));
(DataList1.Items[j].FindControl("qtylab") as System.Web.UI.WebControls.Label).Text = "Only "+qty+" Left";
(DataList1.Items[j].FindControl("qtylab") as System.Web.UI.WebControls.Label).ForeColor = Color.OrangeRed;
(DataList1.Items[j].FindControl("Button1") as System.Web.UI.WebControls.Button).Visible= true;
(DataList1.Items[j].FindControl("Button3") as System.Web.UI.WebControls.Button).Visible= true;
}
}
else if (qty > 5)
{
(DataList1.Items[j].FindControl("DropDownList1") as DropDownList).Items.Clear();
for (int i = 1; i < 6; i++)
{
(DataList1.Items[j].FindControl("DropDownList1") as DropDownList).Items.Add(Convert.ToString(i));
(DataList1.Items[j].FindControl("qtylab") as System.Web.UI.WebControls.Label).ForeColor = Color.GreenYellow;
(DataList1.Items[j].FindControl("qtylab") as System.Web.UI.WebControls.Label).Text = "Available";
(DataList1.Items[j].FindControl("Button1") as System.Web.UI.WebControls.Button).Visible = true;
(DataList1.Items[j].FindControl("Button3") as System.Web.UI.WebControls.Button).Visible= true;
}
}
else
{
(DataList1.Items[j].FindControl("DropDownList1") as DropDownList).Visible = false;
(DataList1.Items[j].FindControl("qtylab") as System.Web.UI.WebControls.Label).Text = "Out of Stock";
(DataList1.Items[j].FindControl("qtylab") as System.Web.UI.WebControls.Label).ForeColor = Color.Red;
(DataList1.Items[j].FindControl("Button1") as System.Web.UI.WebControls.Button).Visible= false;
(DataList1.Items[j].FindControl("Button3") as System.Web.UI.WebControls.Button).Visible = false;
(DataList1.Items[j].FindControl("Label1") as System.Web.UI.WebControls.Label).Visible = false;
}
}
}
For example:
IP Address: 130.45.34.36
Mask: 255.255.240.0
What would be Net ID/Subnet Address, and
Broadcast Address?
Let's write both in binary:
130.45.34.36 = 10000010.00101101.00100010.00100100
255.255.240.0 = 11111111.11111111.11110000.00000000
A bitwise AND between the two would give us the network address:
10000010.00101101.00100010.00100100 (ip address)
AND
11111111.11111111.11110000.00000000 (subnet mask)
=
10000010.00101101.00100000.00000000 = 130.45.32.0 (the resulting network address)
A bitwise OR between the network address and the inverted subnet mask would give us the broadcast address:
10000010.00101101.00100000.00000000 (netadress)
OR
00000000.00000000.00001111.11111111 (inverted subnet mask)
=
10000010.00101101.00101111.11111111 = 130.45.47.255 (broadcast address)
var network = calculateNetworkIP("192.168.0.101", "255.255.255.0");
var broadcast = calculateBroadcastIP("192.168.0.101", "255.255.255.0");
function calculateNetworkIP(ipAddress, maskIP){
var binaryIP = convertIPToBinaryIP(ipAddress);
var maskBinaryIP = convertIPToBinaryIP(maskIP);
var binaryNetwork = [];
for (var j = 0; j < maskBinaryIP.length; j++) {
binaryNetwork.push(bitwiseAND(binaryIP[j], maskBinaryIP[j]));
}
var NetworkIPArr = convertBinaryIPToDecIP(binaryNetwork);
var NetworkIPStr = "";
for (var k = 0; k < NetworkIPArr.length; k++) {
NetworkIPStr += NetworkIPArr[k]+".";
}
return NetworkIPStr.slice(0, -1);
}
function calculateBroadcastIP(ipAddress, maskIP){
var binaryIP = convertIPToBinaryIP(ipAddress);
var maskBinaryIP = convertIPToBinaryIP(maskIP);
var invertedMark = [];
for (var i = 0; i < maskBinaryIP.length; i++) {
invertedMark.push(invertedBinary(maskBinaryIP[i]));
}
var binaryBroadcast = [];
for (var j = 0; j < maskBinaryIP.length; j++) {
binaryBroadcast.push(bitwiseOR(binaryIP[j], invertedMark[j]));
}
var broadcastIPArr = convertBinaryIPToDecIP(binaryBroadcast);
var broadcastIPStr = "";
for (var k = 0; k < broadcastIPArr.length; k++) {
broadcastIPStr += broadcastIPArr[k]+".";
}
return broadcastIPStr.slice(0, -1);
}
function invertedBinary(number){
var no = number+"";
var noArr = no.split("");
var newNo = "";
for(var i = 0; i < noArr.length; i++){
if(noArr[i] == "0"){
newNo += "1";
}else{
newNo += "0";
}
}
return newNo;
}
function bitwiseAND(firstBinary, secondBinary){
var firstArr = [];
var secondArr = [];
firstArr = firstBinary.split("");
secondArr = secondBinary.split("");
var newAdded = "";
for(var i = 0; i < firstArr.length; i++){
if(firstArr[i]+"+"+secondArr[i] == "1+0"){
newAdded += "0";
}else if(firstArr[i]+"+"+secondArr[i] == "0+1"){
newAdded += "0";
}else if(firstArr[i]+"+"+secondArr[i] == "1+1"){
newAdded += "1";
}else if(firstArr[i]+"+"+secondArr[i] == "0+0"){
newAdded += "0";
}
}
return newAdded;
}
function bitwiseOR(firstBinary, secondBinary){
var firstArr = [];
var secondArr = [];
firstArr = firstBinary.split("");
secondArr = secondBinary.split("");
var newAdded = "";
for(var i = 0; i < firstArr.length; i++){
if(firstArr[i]+"+"+secondArr[i] == "1+0"){
newAdded += "1";
}else if(firstArr[i]+"+"+secondArr[i] == "0+1"){
newAdded += "1";
}else if(firstArr[i]+"+"+secondArr[i] == "1+1"){
newAdded += "1";
}else if(firstArr[i]+"+"+secondArr[i] == "0+0"){
newAdded += "0";
}
}
return newAdded;
}
function convertBinaryIPToDecIP(binaryIPArr){
var broadcastIP = [];
for (var i = 0; i < binaryIPArr.length; i++) {
broadcastIP.push(parseInt(parseInt(binaryIPArr[i]), 2));
}
return broadcastIP;
}
function convertIPToBinaryIP(ipAddress) {
var ipArr = ipAddress.split(".");
var binaryIP = [];
for (var i = 0; i < ipArr.length; i++) {
var binaryNo = parseInt(ipArr[i]).toString(2);
if(binaryNo.length == 8){
binaryIP.push(binaryNo);
}else{
var diffNo = 8 - binaryNo.length;
var createBinary = '';
for (var j = 0; j < diffNo; j++) {
createBinary += '0';
}
createBinary += binaryNo;
binaryIP.push(createBinary);
}
}
return binaryIP;
}
Code example based on Malt's answer:
const
ipadr = '130.45.34.36',
subnet = '255.255.240.0',
ipadrs = ipadr.split('.'),
subnets = subnet.split('.');
let networks = [],
broadcasts = [];
for (let i in ipadrs) {
networks[i] = ipadrs[i] & subnets[i];
}
console.log('netaddress: ', networks.join('.')) // netaddress: 130.45.32.0
for (let i in networks) {
broadcasts[i] = networks[i] | ~subnets[i] + 256;
}
console.log('broadcast address: ', broadcasts.join('.')) // broadcast address: 130.45.47.255
Another short cut for broadcast address calculation after getting netwotk address is:
calculate total no of hosts (in this case it is 2^12 = 4096)
Divide it by 256(in this case it is 16) and add the result - 1(in this case 15) in *corresponding octet(in this case second octet i.e.
32+15=47) and make other octet 255
*we can get the corresponding octet by looking at the no of hosts. e.g if the no of hosts are greater than 256 then we have to add it to the 2nd octet of network address and so on
typescript version
function getBroadcastAddress({ address, netmask }: NetworkInterfaceInfo) {
const addressBytes = address.split(".").map(Number);
const netmaskBytes = netmask.split(".").map(Number);
const subnetBytes = netmaskBytes.map(
(_, index) => addressBytes[index] & netmaskBytes[index]
);
const broadcastBytes = netmaskBytes.map(
(_, index) => subnetBytes[index] | (~netmaskBytes[index] + 256)
);
return broadcastBytes.map(String).join(".")
}
/*
// test
getBroadcastAddress({ address: "192.168.1.93", netmask: "255.255.255.0" }) == '192.168.1.255'
*/
In my web application i need to draw shapes in the image using mouse.But i was struck draw and resize polygon..i have dawned polygon..How to resize it?
i can able to draw polygon using the above code.
But i need to resize it..any idea to resize the drowned polygon?
Please refer the below code.
private function onDrawTriangle() : void {
var ui:UIComponent = new UIComponent();
drawPanel = new Sprite();
drawPanel.graphics.clear();
drawPanel.graphics.lineStyle(2, 0xFF0000);
drawPanel.graphics.beginFill(0xDEFACE);
drawPanel.graphics.drawRect(0,0,300,300);
drawPanel.graphics.endFill();
ui.addChild(drawPanel);
addChild(ui);
ui.x = 20;
ui.y = 20;
_lineArr = new Array();
line = new Shape();
drawPanel.addEventListener(MouseEvent.CLICK,onAddPoint);
}
private function onAddPoint(evt:MouseEvent) : void {
if(numSpot <= 10) {
var point:Sprite = new Sprite();
point.graphics.clear();
point.graphics.lineStyle(0,0x0000FF);
point.graphics.beginFill(0x0000FF);
point.graphics.drawCircle(0,0,5);
point.graphics.endFill();
point.x = evt.localX;
point.y = evt.localY;
_lineArr.push({x:point.x,y:point.y});
drawPanel.addChild(point);
if(numSpot > 0) drawLine();
numSpot++;
}
}
private function drawLine() : void {
line.graphics.clear();
line.graphics.lineStyle(2,0x000000);
if(_lineArr.length > 2) line.graphics.beginFill(0xFF0000,0.5);
line.graphics.moveTo(_lineArr[0].x,_lineArr[0].y);
for(var i:int=1;i<_lineArr.length;i++) {
line.graphics.lineTo(_lineArr[i].x,_lineArr[i].y);
}
line.graphics.lineTo(_lineArr[0].x,_lineArr[0].y);
if(_lineArr.length > 2) line.graphics.endFill();
drawPanel.addChildAt(line,0);
}
Rather pushing points to array you may push the point(sprite variable).
Have a look on the modified codes for the above codes where I added some more events to re size the polygon
Here is the sample code:
private function onDrawTriangle() : void {
var ui:SpriteVisualElement = new SpriteVisualElement();
//ui.x = 20;
//ui.y = 20;
addElement(ui);
drawPanel = new Sprite();
drawPanel.graphics.clear();
drawPanel.graphics.lineStyle(2, 0xFF0000);
drawPanel.graphics.beginFill(0xDEFACE);
drawPanel.graphics.drawRect(0,0,300,300);
drawPanel.graphics.endFill();
ui.addChild(drawPanel);
_lineArr = new Array();
line = new Shape();
drawPanel.addEventListener(MouseEvent.CLICK,onAddPoint);
}
private function onAddPoint(evt:MouseEvent) : void {
if(numSpot <= 10) {
var point:Sprite = new Sprite();
point.graphics.clear();
point.graphics.lineStyle(0,0x0000FF);
point.graphics.beginFill(0x0000FF);
point.graphics.drawCircle(0,0,5);
point.graphics.endFill();
point.x = mouseX;
point.y = mouseY;
point.addEventListener(MouseEvent.MOUSE_DOWN , onDown);
_lineArr.push(point);
drawPanel.addChild(point);
if(numSpot > 0) drawLine();
numSpot++;
}
}
private function drawLine() : void {
line.graphics.clear();
line.graphics.lineStyle(2,0x000000);
if(_lineArr.length > 2) line.graphics.beginFill(0xFF0000,0.5);
line.graphics.moveTo(_lineArr[0].x,_lineArr[0].y);
for(var i:int=1;i<_lineArr.length;i++) {
line.graphics.lineTo(_lineArr[i].x,_lineArr[i].y);
}
line.graphics.lineTo(_lineArr[0].x,_lineArr[0].y);
if(_lineArr.length > 2) line.graphics.endFill();
drawPanel.addChildAt(line,0);
}
protected function onDown(event:MouseEvent):void
{
var point:Sprite = event.currentTarget as Sprite;
point.addEventListener(Event.ENTER_FRAME , onResize);
point.addEventListener(MouseEvent.MOUSE_UP , onUp);
drawPanel.removeEventListener(MouseEvent.CLICK,onAddPoint);
}
protected function onResize(event:Event):void
{
var point:Sprite = event.currentTarget as Sprite;
point.x = mouseX;
point.y = mouseY;
drawLine();
}
protected function onUp(event:MouseEvent):void
{
var point:Sprite = event.currentTarget as Sprite;
point.removeEventListener(Event.ENTER_FRAME , onResize);
point.removeEventListener(MouseEvent.MOUSE_UP , onUp);
drawPanel.addEventListener(MouseEvent.CLICK,onAddPoint);
}
I need following result.
All numbers use numeric sorting and all strings use alphanumeric sort. Further more , the numeric values should be listed before the string values:
Example:
before "i","9","89","0045","b","x"
after "9","0045","89","b","i","x"
My current code looks like this: (numeric sort works but my strings are distributed to the top and bottom?! -> "b","x","9","0045","89","i")
public function compareFunction(obj1:Object, obj2:Object):int {
var id1:String = (obj1 as WdProblem).id;
var id2:String = (obj2 as WdProblem).id;
if(id1.replace(' ', '') == "n") {
var sdld:int = 0;
}
var num1:int = Number(id1);
var num2:int = Number(id2);
if(stringIsAValidNumber(id1) && stringIsAValidNumber(id2)) {
if(num1 == num2) {
return 0;
} else {
if(num1 > num2) {
return 1;
} else {
return -1;
}
}
} else if(!stringIsAValidNumber(id1) && !stringIsAValidNumber(id2)) {
return ObjectUtil.compare(id1, id2);
//return compareString(id1, id2);
} else if(!stringIsAValidNumber(id1) && stringIsAValidNumber(id2)) {
return 1;
} else if(stringIsAValidNumber(id1) && !stringIsAValidNumber(id2)) {
return -1;
}
return -1;
}
private function stringIsAValidNumber(s:String):Boolean {
return Boolean(s.match("[0-9]+(\.[0-9][0-9]?)?"));
}
My suggestion is to break it down into it's constituent parts especially if you have a scenario like this with 1 or more priority sorts. The key is to move onto the next sort only when the first sort returns they are equal.
For your case, I would build 2 sorts, one for numeric and the other for alpha-numeric, then your main sort can prioritize these by calling the sub-sort.
For example I have something similar:
private function sort2DimensionsByIncomeVsTime(a:OLAPSummaryCategory, b:OLAPSummaryCategory, fields:Array = null):int
{
var sort:OLAPSort = new OLAPSort();
var incomeSort:int = sort.sortIncome(a, b);
var nameSort:int = sort.sortName(a, b);
var yrSort:int = sort.sortYear(a, b);
var moSort:int = sort.sortMonth(a, b);
if (incomeSort == 0)
{
if (nameSort == 0)
{
if (yrSort == 0)
{
//trace(a.name, a.year, a.month, 'vs:', b.name, b.year, b.month, 'month sort:', moSort);
return moSort;
}
else return yrSort;
}
else return nameSort;
}
else return incomeSort;
}
I use following sort function for AlphaNumeric sorting:
<?xml version="1.0" encoding="utf-8"?>
<s:Application
creationComplete="onCC()"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.utils.ObjectUtil;
import mx.utils.StringUtil;
import spark.collections.Sort;
import spark.collections.SortField;
public function onCC():void
{
var acAlphaNumericString:ArrayCollection = new ArrayCollection();
acAlphaNumericString.addItem({ name: "NUM10071" });
acAlphaNumericString.addItem({ name: "NUM9999" });
acAlphaNumericString.addItem({ name: "9997" });
acAlphaNumericString.addItem({ name: "9998" });
acAlphaNumericString.addItem({ name: "9996" });
acAlphaNumericString.addItem({ name: "9996F" });
acAlphaNumericString.addItem({ name: "i" });
acAlphaNumericString.addItem({ name: "9" });
acAlphaNumericString.addItem({ name: "89" });
acAlphaNumericString.addItem({ name: "0045" });
acAlphaNumericString.addItem({ name: "b" });
acAlphaNumericString.addItem({ name: "x" });
var sf:SortField = new SortField("name");
sf.compareFunction = function(o1:Object, o2:Object):int
{
return compare(o1.name, o2.name);
}
var sort:Sort = new Sort();
sort.fields = [ sf ];
acAlphaNumericString.sort = sort;
acAlphaNumericString.refresh();
for each (var o:Object in acAlphaNumericString)
trace(o.name);
}
public static function compare(firstString:String, secondString:String):int
{
if (secondString == null || firstString == null)
return 0;
var lengthFirstStr:int = firstString.length;
var lengthSecondStr:int = secondString.length;
var index1:int = 0;
var index2:int = 0;
while (index1 < lengthFirstStr && index2 < lengthSecondStr)
{
var ch1:String = firstString.charAt(index1);
var ch2:String = secondString.charAt(index2);
var space1:String = "";
var space2:String = "";
do
{
space1 += ch1;
index1++;
if (index1 < lengthFirstStr)
ch1 = firstString.charAt(index1);
else
break;
} while (isDigit(ch1) == isDigit(space1.charAt(0)));
do
{
space2 += ch2;
index2++;
if (index2 < lengthSecondStr)
ch2 = secondString.charAt(index2);
else
break;
} while (isDigit(ch2) == isDigit(space2.charAt(0)));
var str1:String = new String(space1);
var str2:String = new String(space2);
var result:int;
if (isDigit(space1.charAt(0)) && isDigit(space2.charAt(0)))
{
var firstNumberToCompare:int = parseInt(StringUtil.trim(str1));
var secondNumberToCompare:int = parseInt(StringUtil.trim(str2));
result = ObjectUtil.numericCompare(firstNumberToCompare, secondNumberToCompare);
}
else
result = ObjectUtil.compare(str1, str2);
if (result != 0)
return result;
}
return lengthFirstStr - lengthSecondStr;
function isDigit(ch:String):Boolean
{
var code:int = ch.charCodeAt(0);
return code >= 48 && code <= 57;
}
}
]]>
</fx:Script>
</s:Application>
I am working on the platform confirmit, which creates online surveys. This is a script node that results in the runtime error "object required", I would be grateful if you could help me fix it.. It is supposed to check whether certain codes hold 1 or 2 in the questions q2b and q3a (questions are referenced with the function f() - f(question id)[code]) - the
'//skip ?' part. Then it recodes a maximum of four of the codes into another question (h_q4) for further use.
var flag1 : boolean = false;
var flag2 : boolean = false;
//null
for(var i: int=0; i <9; i++)
{
var code = i+1;
f("h_q4")[code].set(null);
}
f("h_q4")['95'].set(null);
//skip ?
for(var k: int=1; k <16; k+=2)
{
var code = k;
if(f("q2b")[code].none("1", "2"))
flag1;
else
{
flag1 = 0;
break;
}
}
if(f("q3a")['1'].none("1", "2"))
flag2;
if(flag1 && flag2)
f("h_q4")['95'].set("1");
//recode
else
{
var fromForm = f("q2b");
var toForm = f("h_q4");
const numberOfItems : int = 4;
var available = new Set();
if(!flag1)
{
for( i = 1; i < 16; i+=2)
{
var code = i;
if(f("q2b")[i].any("1", "2"))
available.add(i);
}
}
if(!flag2)
{
available.add("9");
}
var selected = new Set();
if(available.size() <= numberOfItems)
{
selected = available;
}
else
{
while(selected.size() < numberOfItems)
{
var codes = available.members();
var randomNumber : float = Math.random()*codes.length;
var randomIndex : int = Math.floor(randomNumber);
var selectedCode = codes[randomIndex];
available.remove(selectedCode);
selected.add(selectedCode);
}
}
var codes = fromForm.domainValues();
for(var i = 0;i<codes.length;i++)
{
var code = codes[i];
if(selected.inc(code))
{
toForm[code].set("1");
}
else
{
toForm[code].set("0");
}
}
}
the first part of the code (//null) empties the 'recepient' question to ease testing
.set(), .get(), .any(), .none() are all valid