Displaying a UI List of Strings (Adobe Flex/Actionscript) - arrays

Im making an application for a person search. I get the results in the form of a string (each line representing one person). I want to display these lines of text in a List, how do I do this?
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="PersonSearchResults">
<fx:Script>
<![CDATA[
import model.PersonSummary;
import mx.collections.ArrayCollection;
public var listOfPeople:Array;
public function populate():void{
trace("Populating");
listOfPeople = String(data).split("\n");
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:List id="results">
<s:ArrayList source="{listOfPeople}"/>
</s:List>
The problem I am having is that the listOfPeople array populates AFTER the list has displayed on screen... how do I resolve this?
Thanks
phil

You can't do bindings with an Array. Use ArrayCollection instead.
[Bindable]
public var listOfPeople:ArrayCollection;
public function populate():void{
listOfPeople = new ArrayCollection(String(data).split("\n"));
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:List id="results" dataProvider="{listOfPeople}" />

Related

How to augment multiple XML child elements Camel?

I have a use case where I need to take an existing XML document and augment it from a database, for an integration process.
I'm starting with something like:
<parent>
<child>
<data>A</data>
</child>
<child>
<data>B</data>
</child>
<parentData>
<data/>
</parentData>
</parent>
What I am trying to do is add a <moreData .../> tree to each of the child elements.
I could just write a custom bean that does everything, but that doesn't feel the right approach. I've considered using a splitter based on the xpath for child, followed by a content-enricher, which will allow me to fetch the additional data, but I can't see how to reassemble everything afterwards.
At the moment, I'm thinking I need to use a loop, but that feels clunky too, and will require a custom aggregation strategy for the content-enricher.
from("direct:a")
.loop().xpath("count( parent/child )", Integer.class )
.setHeader("Key")
.xpath( "parent/child[function:properties('CamelLoopIndex')]/data", String.class )
.enrich("sql:SELECT xmldata FROM dataTable WHERE key = :#Key?dataSource=myDS",
new MyCustomAggregationStrategy() )
This must be an everyday occurrence in the world of Camel but I can't find any examples of how to do it.
If I were doing this in a custom bean, I'd get an xpath for the child element, then iterate through the nodeset performing the query and attaching the result as a new child to node. I just can't see how to do this "nicely" in Camel.
Any ideas or hints would be great! Thanks!
You can try prepare map of new nodes , and then transform parent xml with xslt and get prepared new nodes using java inside xsl. Here some example. Route:
#Override
public void configure() throws Exception {
from("timer://foo?period=30s")
.setBody(constant("<parent>\n" +
" <child>\n" +
" <data>A</data>\n" +
" </child>\n" +
" <child>\n" +
" <data>B</data>\n" +
" </child>\n" +
" <parentData>\n" +
" <data/>\n" +
" </parentData>\n" +
"</parent>"))
.convertBodyTo(org.w3c.dom.Document.class)
.setProperty("oldBody", simple("body"))
.split(xpath("//child"), (oldExchange, newExchange) -> {
Map<String, String> map = oldExchange != null ? oldExchange.getProperty("map", Map.class) : new HashMap<>();
map.put(newExchange.getIn().getHeader("Key", String.class), newExchange.getIn().getBody(String.class));
newExchange.setProperty("map", map);
return newExchange;
})
.setHeader("Key", xpath("//data/text()"))
// .to("sql:SELECT xmldata FROM dataTable WHERE key = :#Key?dataSource=#myDS")
//emulate result of your sql
.process(exchange -> {
exchange.getIn().setBody("<someNewData>".concat(exchange.getIn().getHeader("Key", String.class).concat("Result")).concat("</someNewData>"));
})
.end()
.setBody(exchangeProperty("oldBody"))
.to("xslt:xslt/result.xsl?transformerFactory=#nsTF")
.log(LoggingLevel.INFO, "Body:${body}");}
public static String getElement(Object map, String key) {
return (String) ((Map) map).get(key);
}
nsTF is bean of class:
public class NonSecureTransfomerFactory extends TransformerFactoryImpl {
#Override
//for using java inside xsl
public boolean isSecureProcessing()
{
return false;
}
}
xslt stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:getter="my.package.RouteHelper">
<xsl:output method="xml" version="1.0" encoding="UTF-8"/>
<xsl:strip-space elements='*'/>
<xsl:param name="map"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="child">
<xsl:copy>
<xsl:variable name="key" select="data/text()"/>
<xsl:value-of disable-output-escaping="yes" select="getter:getElement($map,$key)"/>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
Output xml:
<parent>
<child>
<someNewData>AResult</someNewData>
<data>A</data>
</child>
<child>
<someNewData>BResult</someNewData>
<data>B</data>
</child>
<parentData>
<data/>
</parentData>
</parent>

Flash Builder - Customizing comboBox

I'm populating items to a comboBox from an xml file. I'm trying to customize the font-color of each item that appears in the comboBox. Any suggestions?
Thanks!
--Moe
The process is simple if you are using Flash Builder. Each item in your ComboBox is made of an ItemRenderer. Create a custom item render (file - > new -> mxml component) extending that basic ItemRenderer class then assign this new ItemRenderer to your ComboBox. Now inside your custom ItemRenderer you can change values, font sizes, etc ...
You will need to use an ItemRenderer. Though you have not mentioned but it seems you are using Flex 3. The way of using ItemRenderer is slightly different in Flex 3 vs Flex 4. So here is the version for Flex 3:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" minWidth="955" minHeight="600">
<mx:XMLList id="statesXMLList" xmlns="">
<state abbrev="AK" name="Alaska" />
<state abbrev="AZ" name="Arizona" />
<state abbrev="AR" name="Arkansas" />
<state abbrev="CA" name="California" />
<state abbrev="CO" name="Colorado" />
<state abbrev="CT" name="Connecticut" />
</mx:XMLList>
<mx:ComboBox id="comboBox"
prompt="Please select a State..."
dataProvider="{statesXMLList}"
rowCount="3"
labelField="#name"
itemRenderer="ComboBoxItemRenderer"
/>
</mx:Application>
The class for ItemRenderer is ComboBoxItemRenderer which is shown below:
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
override public function set data(value:Object):void
{
super.data = value;
lbl.text = value.#name;
if(value.#abbrev == "AK") {
lbl.setStyle("color","#FF0000");
}
else if(value.#abbrev == "AR") {
lbl.setStyle("color","#FF00FF");
}
else {
lbl.setStyle("color","#000000");
}
}
]]>
</mx:Script>
<mx:Label id="lbl"/>
</mx:VBox>
Do not forget the last if (default case) whenever you override set data method.

Populating a listview contents with an array

I have created a function that would be able to place the array contents into a listview, Here is my progress so far.
<div id="MainPage" data-role="page" >
<div data-role="content">
RENAME
</div>
</div>
<div id="ViewPage" data-role="page" >
<div data-role="content">
<ul id="viewlist" data-role="listview" data-filter="true" data-filter-placeholder="Sample Contents" data-inset="true">
<!-- array contents goes here -->
</ul>
</div>
</div>
<script>
var sampleContent = new Array( );
displayArray( )
{
for(var scan=0; scan<sampleContent.length; detect++)
{
$('#viewlist').append('<li>' + sampleContent[scan] + '</li>');
}
}
</script>
My code works during the first press of the button but when i pressed it the second time, the list view becomes messed up.
Any help or advice will be glady accepted thanks in advance.
edited, i have figured out how to do it but I am having problems during the second press of the button.
First of i don't want to be rude but i think you should start first to read some basics about android.
Like:
Android Activities , life cycle of activities
Layout in Android (how to add button on an activity then respond to a click etc) , different existing Layout in android and android widget (like the listView for example)
of course there are a lot more to read but it s a good way to start.
However i will provide you codes that will do what you are asking for and i will try to explain as much as i can
First of all you need to create the other activity and inside the layout of that activity insert a listview
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_gravity="center_horizontal" />
</LinearLayout>
then the java code of the other activity will look like this
public class MainActivity2 extends Activity {
//create the array adapter that will input your array and convert it into a list of view
ArrayAdapter<String> arrayAdapter;
String[] list;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
listView = (ListView)findViewById(R.id.listView);
// get the array from ressource and insert them on an array
list = getResources().getStringArray(R.array.listArray);
// then create the arrayadpater with input your array of string if you dont get //anything here just read android documentation about arrayAdapter
arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,list );
//then set the adapter to your listView
listView.setAdapter(arrayAdapter);
}
}
res xml file
<resources>
<string-array name="listArray">
<item>Apple</item>
<item>Banana</item>
<item>Cherry</item>
<item>Cranberry</item>
<item>Grape</item>
<item>Grape</item>
</string-array>
</resources
>
Hope it will help
Just add .listview('refresh') after you have added all items.
$('#viewlist').listview('refresh');
If you want to empty the list each time and refill it, call .empty() before the for loop:
$('#viewlist').empty();
To use better jquery mobile coding, structure your code like this:
Take the onclick out of the anchor tag and add an id:
<a id="viewPageBtn" href="#ViewPage" data-role="button" >RENAME</a>
In your script tag, handle pagecreate on the main page, and within it handle the click event of the anchor:
$(document).on("pagecreate", "#MainPage", function(){
var sampleContent = ["item 1", "item 2", "item 3"];
$("#viewPageBtn").on("click", function(){
$('#viewlist').empty();
for(var scan=0; scan < sampleContent.length; scan++)
{
$('#viewlist').append('<li>' + sampleContent[scan] + '</li>').listview('refresh');
}
$('#viewlist').listview('refresh');
});
});

flex error 1137: Incorrect number of arguments. Expected no more than 0

I am trying to create a mobile app in flash builder. I wanted to use the text field to search the list but I keep getting this error in my function list_creation complete handler
edit:
I am using wamp php server to retrieve data in my program and then view them, as list wordsService2 class was generated automatically when I created linked my database.
error 1137: Incorrect number of arguments. Expected no more than 0.
This is what program looks like:
<s:View>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected function list_creationCompleteHandler():void
{
getAllWordsResult.token = wordsService2.getAllWords(txt.text);
}
]]>
</fx:Script>
<fx:Declarations>
<s:CallResponder id="getAllWordsResult"/>
<wordsservice2:WordsService2 id="wordsService2"/>
</fx:Declarations>
<s:actionContent>
<s:Button label="Search" click="list_creationCompleteHandler()"/>
</s:actionContent>
<s:navigationContent>
<s:TextInput id="txt" width="242"/>
</s:navigationContent>
<s:List id="list" width="100%" height="100%"
labelField="term">
<s:AsyncListView list="{getAllWordsResult.lastResult}"/>
</s:List>
</s:View>
getallwords
public function getAllWords() {
$stmt = mysqli_prepare($this->connection, "SELECT * FROM $this->tablename");
$this->throwExceptionOnError();
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
$rows = array();
mysqli_stmt_bind_result($stmt, $row->id, $row->term, $row->defin, $row->term1, $row->defin1);
while (mysqli_stmt_fetch($stmt)) {
$rows[] = $row;
$row = new stdClass();
mysqli_stmt_bind_result($stmt, $row->id, $row->term, $row->defin, $row->term1, $row->defin1);
}
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
return $rows;
}
WordsService2.getAllWords() does not take any arguments. You are calling it with a string; the content of the textinput. That's why you get the Error 1173.

How to dynamically assign displayName in lineseries - tooltip & displayName shows [object Object]

This flashbuilder 4.6 application displays a single lineSeries on a line chart based on a chosen name from a dropdown list and the lineseries data shows fine. However, the tooltip shows [object Playername_returntype] instead of the dropdown chosen name.
I also want to dynamically assign the same chosen name from the dropdown to the displayName of the lineseries but have been unable to achieve this. Result shows [object Playername_returntype] as in the tooltip.
Any help would be much appreciated.
Thanks.
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:pool_ratings_yr1service="services.pool_ratings_yr1service.*"
xmlns:pool_playerservice="services.pool_playerservice.*"
minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.FlexEvent;
protected function linechart1_creationCompleteHandler(event:FlexEvent):void
{
getpool_ratings_yr1Result.token = pool_ratings_yr1Service.getpool_ratings_yr1('Greenleaf');
}
protected function dropDownList_creationCompleteHandler(event:FlexEvent):void
{
getAllpool_playerResult.token = pool_playerService.getAllpool_player();
}
private function comboBoxChange():void
{
var selectedName:String = dropDownList.selectedItem.lname;
getpool_ratings_yr1Result.token = pool_ratings_yr1Service.getpool_ratings_yr1(selectedName);
}
]]>
</fx:Script>
<fx:Declarations>
<s:CallResponder id="getpool_ratings_yr1Result"/>
<pool_ratings_yr1service:Pool_ratings_yr1Service id="pool_ratings_yr1Service"
fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"
showBusyCursor="true"/>
<s:CallResponder id="getAllpool_ratings_yr1Result"/>
<s:CallResponder id="getAllpool_playerResult"/>
<pool_playerservice:Pool_playerService id="pool_playerService"
fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"
showBusyCursor="true"/>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<mx:LineChart id="linechart1" x="151" y="88" width="800"
creationComplete="linechart1_creationCompleteHandler(event)"
dataProvider="{getpool_ratings_yr1Result.lastResult}" showDataTips="true">
<mx:verticalAxis>
<mx:LinearAxis id="v1" minimum="2000" maximum="2500" title="Average Elo Rating" />
</mx:verticalAxis>
<mx:series>
<mx:LineSeries id="lineSeries" displayName="{dropDownList.selectedItem}" yField="avg_rating"/>
</mx:series>
<mx:horizontalAxis>
<mx:CategoryAxis id="categoryAxis" categoryField="yr"/>
</mx:horizontalAxis>
</mx:LineChart>
<mx:Legend dataProvider="{linechart1}"/>
<s:DropDownList id="dropDownList" x="10" y="88"
creationComplete="dropDownList_creationCompleteHandler(event)"
labelField="lname"
change="comboBoxChange()">
<s:AsyncListView list="{getAllpool_playerResult.lastResult}"/>
</s:DropDownList>
Not entirely sure what you're after, but for the LineSeries displayName, here's what I did:
Created a [Bindable] String variable for each Line Series, and then whenever the data changed, just assign whatever value you want to the variable. In your example:
private function comboBoxChange():void
{
var selectedName:String = dropDownList.selectedItem.lname;
getpool_ratings_yr1Result.token = pool_ratings_yr1Service.getpool_ratings_yr1(selectedName);
// Private Bindable String variable(myString) assigned earlier
myString = selectedName;
}
And then in your mxml:
displayName="{myString}"
Hope that's clear enough!

Resources