<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tojio Lab &#187; Flex</title>
	<atom:link href="http://lab.tojio.com/category/flex/feed/" rel="self" type="application/rss+xml" />
	<link>http://lab.tojio.com</link>
	<description>"Tojio Labs is the place where little useful insights (and unimportant ones) from our everyday work as an interactive agency found their home."</description>
	<lastBuildDate>Fri, 14 May 2010 10:50:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Flex Data Management 03 &#8211; Storing data in a relational DB on a remote server [en]</title>
		<link>http://lab.tojio.com/2008/02/22/flex-data-management-03-storing-data-in-a-relational-db-on-a-remote-server/</link>
		<comments>http://lab.tojio.com/2008/02/22/flex-data-management-03-storing-data-in-a-relational-db-on-a-remote-server/#comments</comments>
		<pubDate>Fri, 22 Feb 2008 13:44:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Data Management]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://lab.tojio.com/2008/02/22/flex-data-management-03-storing-data-in-a-relational-db-on-a-remote-server/</guid>
		<description><![CDATA[The first and the second part of this tutorial covered the topics reading data from a relational DB and transforming the data into a suitable (XML) format so that Flex can use this data to establish a DataProvider setting up a (editable) DataGrid with the DataProvider and checking user input for consistency So now we’re [...]]]></description>
			<content:encoded><![CDATA[<p>The <a title="Flex Data Management 01" href="http://lab.tojio.com/2007/11/12/flex-data-management-01-reading-data-from-a-remote-db-using-the-httpservice-class/">first</a> and the <a title="Flex Data Management 02" href="http://lab.tojio.com/2007/11/16/flex-data-management-02-handling-datagrid-input/">second</a> part of this tutorial covered the topics</p>
<ul>
<li>reading data from a relational DB and transforming the data into a suitable (XML) format so that Flex can use this data to establish a <code>DataProvider</code></li>
<li>setting up a (editable) <code>DataGrid</code> with the DataProvider and checking user input for consistency</li>
</ul>
<p>So now we’re ready to send the updated data back to our server: whenever the user changes the row (either by typing ‘enter’or by clicking into another row) the entered data will be checked. If the new Values are OK, the method <code>sendData()</code> will be called in order to construct an Object that will hold our parameters for the <code>POST</code> request by means of the AS3 <code>HttpService</code> Class:</p>
<pre><code>
function sendData(id:int, field:String, value:String)
{
	var params:	Object 	= {};
	params.id 			= id;
	params.field 		= field;
	params.value		= value;
	var at:AsyncToken = updaterequest.send(params);
}
</code></pre>
<p>The <code>HTTPService updaterequest</code> which is called here is defined in<br />
our .mxml-file:</p>
<pre><code>
&lt;mx:HTTPService id="updaterequest"
			result="handleUpdateResponse(event)"
			showBusyCursor="true"
			method="POST"
			url="http://yourserver.com/yourscript.php"
			useProxy="false" /&gt;
</code></pre>
<p>So far, the entered data has been sent back to our server. After the request is<br />
done, the <code>HttpService</code> will call the<br />
<code>handleUpdateResponse()</code> method in wich we can control the further<br />
program behaviour acording to success or failure. But on the server side again,<br />
we have to check the data before any attempt to write it into the DB: the param<br />
id has to be numerical, the params field and value must be quoted to avoid<br />
possible SQL injections! Let’s have a look at the PHP script that processes the<br />
data and stores them in the mySQL Database:</p>
<pre><code>
if ($_SERVER['REQUEST_METHOD'] == 'POST' &amp;&amp; isset($_POST['id']))
{
	// check whether the id is numeric and quote the other fields
	// for security reasons so that there can be no sql injection
	$id 	 = is_numeric($_POST['id']) ? $_POST['id'] : 0;
	$field  = quoteInput($_POST['field']);
	$value = quoteInput($_POST['value']);

	updateUserList( $id, $field, $value );
}

function quoteInput($value)
{
	 // Stripslashes
	 if (get_magic_quotes_gpc())  $value = stripslashes($value);

	 // Quote if not integer
	 if (!is_numeric($value))
	 	$value = "'" . mysql_real_escape_string($value) . "'";

	 return $value;
}

function updateUserList($id, $field, $value)
{
	// open the connection to our DB host and select the DB we need
	// you have to define these constants for your needs..
	$link = mysql_connect(DB_HOST, DB_USER_ADMIN, DB_PASS_ADMIN)
    	or returnError('Could not connect: ' . mysql_error());

	mysql_select_db(DB_NAME) or returnError('Could not select database');

	// prepare the update statement for the user row in question
	$exec 	= "UPDATE `user` SET `$field` ='$value'
				WHERE `id`='$id'";

	// execute the update and close the connection
	$result = mysql_query($exec);
	mysql_free_result($result);
	mysql_close($link);

	// this is the response that the Flex HttpService
	// will get, so that the Flex program can inform
	// the user of an error if necessary
	if ($result) 	print('&lt;response&gt;success&lt;/response&gt;');
	else		print('&lt;response&gt;failed&lt;/response&gt;');
}

function returnError($err)
{
	// HTTP-header?
	print('&lt;response&gt;failed&lt;/response&gt;');
	print("&lt;message&gt;$err&lt;/message&gt;");
	exit();
}

</code></pre>
<p>So we have the complete cycle of communication between a Flex program and a<br />
relational database via Http-request and Webserver&#8230;<br />
enjoy building your applications!</p>
]]></content:encoded>
			<wfw:commentRss>http://lab.tojio.com/2008/02/22/flex-data-management-03-storing-data-in-a-relational-db-on-a-remote-server/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Flex Data Management 02 &#8211; handling DataGrid input [en]</title>
		<link>http://lab.tojio.com/2007/11/16/flex-data-management-02-handling-datagrid-input/</link>
		<comments>http://lab.tojio.com/2007/11/16/flex-data-management-02-handling-datagrid-input/#comments</comments>
		<pubDate>Fri, 16 Nov 2007 15:56:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Data Management]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://lab.tojio.com/2007/11/16/flex-data-management-02-handling-datagrid-input/</guid>
		<description><![CDATA[The previous part of this tutorial was all about reading data from a mysql database and reformatting this data so that we can easily load it into a DataGrid. This second part is about validating input data from the user. As some columns of our DataGrid are editable, we have to check whether the user&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p><a title="inputerror.jpg" href="http://lab.tojio.com/wp-content/uploads/2007/11/inputerror.jpg"><img style="margin: 0px 20px 10px 0px; float: left" src="http://lab.tojio.com/wp-content/uploads/2007/11/inputerror.thumbnail.jpg" alt="inputerror.jpg" /></a>The previous part of this tutorial was all about reading data from a mysql database and reformatting this data so that we can easily load it into a <code>DataGrid</code>. This second part is about validating input data from the user. As some columns  of our <code>DataGrid</code> are editable, we have to check whether the user&#8217;s input is acceptable at all before sending the new data back to our database (which will be covered in part 3 of the tutorial).</p>
<p><strong>Task #2: getting the data entered into the <code>DataGrid</code></strong><br />
Our <code>DataGrid</code> has three editable columns: credits, status and active. But we have some restrictions on them: credits must be a positive integer, status a positive integer from 1 to 4 and active can only be a boolean value.<br />
So when and how can we check the data that was entered and reject the input if necessary? The DataGrid is defined with the following argument: <code>itemEditEnd="checkInput(event)"</code>. That causes it to call the function <code>checkInput()</code> in our script when the editing of a cell has ended (i.e. the user has typed <code>enter</code> or switched the row or column).</p>
<p>Now let&#8217;s have a look at the function that is processing the input:</p>
<pre><code>

/**
 * This method is called when a DataGridEvent occurs. In case the user has
 * changed clumn or row, check whether new data was entered and send the new
 * value of the changed field to our PHP dataservice that will update the DB.
 *
 * @param e - the DataGridEvent that has just occured
 */

function checkInput(e:DataGridEvent):void
{
    if (e.reason == DataGridEventReason.NEW_COLUMN
        || e.reason == DataGridEventReason.NEW_ROW)
    {
        var newData:String;
        var selectedRow:Object = e.itemRenderer.data;
        var previous:String = new String(
            userCollection.getItemAt(usergrid.selectedIndex)[e.dataField]);

        for (var i:String in selectedRow)
        {
            if ( i == e.dataField )
            {
                // if the current field is the updated one,
                // get the editor and do some introspection to find out
                // which class we're using (TextInput or CheckBox)

                var editor:Object    = e.currentTarget.itemEditorInstance;
                var classInfo:XML    = describeType(editor);
                var className:String = classInfo.@name.toString();

                if (className == 'mx.controls::TextInput')
                    newData = TextInput(e.currentTarget.itemEditorInstance).text;

                else if (className == 'mx.controls::CheckBox')
                {
                    if(CheckBox(e.currentTarget.itemEditorInstance).selected)
                         newData = "1";
                    else newData = "0";
                }

                // this is the place to do some first consistency checks
                // on submitted fields [...]
                // if the data is not acceptable for any reason, you can
                // invoke the preventDefault()-Method on the Datagrid event
                // and make sure that the data will not be sent

                var dataOK:Boolean = checkData(previous, newData, e);
                // send the data if it's OK and different from previous value
                if ( dataOK &amp;&amp; newData != previous )
                    sendData(selectedRow.id, e.dataField, newData);
            }
        }
    }
}</code></pre>
<p>What the function does, in brief, is:</p>
<ol>
<li>having a look at the fields of the selected row until we reach the field that has been edited</li>
<li>for the edited field: doing some introspection to find out which class is used as editor for the field</li>
<li>type casting the <code>itemEditorInstance</code> to an instance of its actual class</li>
<li>retrieving the new data entered by the user and let another function validate the data</li>
</ol>
<p>Note that <strong>you won&#8217;t get the new data</strong> by the <code>itemEditorInstance.data</code> property! By accessing that, you&#8217;ll only get the data that the row previously held. In order <strong>to get the new data, you have to do the type cast</strong> as described above and retrieve the new value by the editor class&#8217; property in question.</p>
<p><strong>Task #3: validating the data and preventing wrong values</strong><br />
The following function is finally called to validate the data. If the data entered is not acceptable, the edited field will be reset and an alert message will pop up, showing the possible values:</p>
<pre><code>
/**
 * This function checks the user input on the fields 'credits' and 'status'
 * For the credits, only 0 or a positive integer will be accepted,
 * for status only integers from 1 to 4.
 * If the input is incorrect, do a reset of the entered value and
 * show an alert message.
 */
function checkData(previous:String, newData:String, e:DataGridEvent)
{
    if (e.dataField == "credits")
    {
        // try to cast string input to integer
        var val:int = int(newData);
        // if new value is negative
        // OR is not "0" as string BUT 0 as integer, then the input
        // has not been a valid integer -&gt; prevent this and show message
        if (val &lt; 0 || ( newData != "0" &amp;&amp;  val == 0))
        {
            // reset the entered input
            TextInput(e.currentTarget.itemEditorInstance).text
                = previous;
            e.preventDefault();
            Alert.show("Please enter a positive Number!");
            return false;
        }
    }
    else if (e.dataField == "status")
    {
        // we will only accept integers from 1 to 4 as status code
        // try to cast string input to integer
        var val:int = int(newData);
        if (val &gt;= 0 || val &gt; 4 )
        {
            // reset the entered input
            TextInput(e.currentTarget.itemEditorInstance).text
                = previous;
            e.preventDefault();
            Alert.show("Please enter a positive from 1 to 4 as status code!");
            return false;
        }
    }
    // if no error has occured until this point, we're safe. return true...
    return true;
}</code></pre>
<p>So that&#8217;s how entered data can be accessed and validated. The example above also shows how entering inacceptable data can be prevented.<br />
The third part of this tutorial will cover sending the data back to our DB and storing it there. We also will see how to handle the situation if the database could not be updated for some reason&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://lab.tojio.com/2007/11/16/flex-data-management-02-handling-datagrid-input/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Flex Data Management 01 &#8211; reading data from a remote DB using the HTTPService Class [en]</title>
		<link>http://lab.tojio.com/2007/11/12/flex-data-management-01-reading-data-from-a-remote-db-using-the-httpservice-class/</link>
		<comments>http://lab.tojio.com/2007/11/12/flex-data-management-01-reading-data-from-a-remote-db-using-the-httpservice-class/#comments</comments>
		<pubDate>Mon, 12 Nov 2007 17:28:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Data Management]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://lab.tojio.com/2007/11/12/flex-data-management-01-reading-data-from-a-remote-db-using-the-httpservice-class/</guid>
		<description><![CDATA[As the DataGrid class in Flex is the perfect tool for managing table data, we also need an efficient and reliable way to store these data. The example here uses an HTTPService to retrieve the data from a remote webserver and to send update packages back to it. This Tutorial uses an example user management [...]]]></description>
			<content:encoded><![CDATA[<p><a title="User Management Flex Application" href="http://lab.tojio.com/wp-content/uploads/2007/11/userlist.jpg"><img style="margin: 0px 20px 10px 0px; float: left" src="http://lab.tojio.com/wp-content/uploads/2007/11/userlist.thumbnail.jpg" alt="User Management Flex Application" /></a></p>
<p>As the DataGrid class in Flex is the perfect tool for managing table data, we also need an efficient and reliable way to store these data. The example here uses an HTTPService to retrieve the data from a remote webserver and to send update packages back to it.</p>
<p>This Tutorial uses an example user management tool for a community site. Users can be (de-)activated, their credits and status within the system can be changed. Any changes in the DataGrid lead to an instant update of the relational database in which the users are stored.</p>
<p><strong>Task #1: retrieving  and transforming data with PHP</strong><br />
In order to populate a DataGrid with data from a mysql database, we first have to get a suitable representation. A Flex DataProvider typically reads this sort of &#8220;flat&#8221; XML files consisting only of nodes representing table rows, e.g:</p>
<pre>&lt;dataset&gt;

  &lt;entry&gt;

    &lt;id&gt;2&lt;/id&gt;

    &lt;login_name&gt;hai_kai&lt;/login_name&gt;

    &lt;last_login&gt;2007-11-05 09:47:54&lt;/last_login&gt;

    &lt;credits&gt;8&lt;/credits&gt;

    &lt;status&gt;4&lt;/status&gt;

    &lt;active&gt;true&lt;/active&gt;

  &lt;/entry&gt;

  &lt;entry&gt;

    &lt;id&gt;4&lt;/id&gt;

    &lt;login_name&gt;Meerblick&lt;/login_name&gt;

    &lt;last_login&gt;2007-11-06 09:54:25&lt;/last_login&gt;

    &lt;credits&gt;14&lt;/credits&gt;

    &lt;status&gt;1&lt;/status&gt;

    &lt;active&gt;true&lt;/active&gt;

  &lt;/entry&gt;

    .

    .

    .

&lt;/dataset&gt;</pre>
<p>So this structure is pretty similar to a table (be it a table in a relational DB or the DataGrid) and easily created in PHP after we&#8217;ve got a result set by querying our relational database. The example DB used here holds a user table that is retrieved by a PHP script like this (using XML-functions of PHP5):</p>
<pre>
define('DB_TYPE', 'mysql');
define('DB_HOST', 'localhost');
define('DB_NAME', 'name_of_your_database');

// constants for accessing the DB
define('DB_USER', 'username_for_the_DB');
define('DB_PASS', 'your_DB_password');</pre>
<pre>// create a new dom structure that will
// be sent as XML result
$output 	= new DOMDocument();
$root_element 	= $output-&gt;createElement('dataset');
$output-&gt;formatOutput 	= true;
$output-&gt;appendChild($root_element);</pre>
<pre>// connect to mysql-Server and select our user DB
$link = mysql_connect(DB_HOST, DB_USER, DB_PASS)
	or die('Could not connect: ' . mysql_error());

mysql_select_db(DB_NAME) or die('Could not select database');</pre>
<pre>// prepare the query
$query = "SELECT `id`, login_name`, `last_login`,
		`credits`, `status`, `active`
          FROM 	 `user`";

$result = mysql_query($query) or die('Query failed: ' . mysql_error());
// for each entry in the result set...
while ($line = mysql_fetch_array($result, MYSQL_ASSOC))
{
        // create an entry-node and append it to the root element
	$entry = $output-&gt;createElement('entry');
	$root_element-&gt;appendChild($entry);

        // for each field in the entry
	foreach (array_keys($line) as $key)
	{
                // append a node with the field's name
                // and add the field's value as textnode
		$node = $output-&gt;createElement($key);

		// we have to convert mySQL booleans (0/1)
		// to explicit true/false- values for Flex
		if ($key == 'active')
		{
			$boo = ($line[$key]) ? "true" : "false";
			$content = $output-&gt;createTextNode($boo);
		}
		else $content = $output-&gt;createTextNode($line[$key]);

		$node-&gt;appendChild($content);
		$entry-&gt;appendChild($node);
		$root_element-&gt;appendChild($entry);
	}
}

// Free resultset, close connection
mysql_free_result($result);
mysql_close($link);

// return the xml
echo $output-&gt;saveXML();</pre>
<p>So that was the server-side data handling&#8230; to populate your DataGrid with this user data, you just have to define a <code>DataProvider</code> for it that reads the url by means of an <code>HTTPService</code> when the application is initialized. In your init code, invoke the <code>send()</code>-Method of the service.</p>
<pre>// define bindable ArrayCollection
[Bindable]
protected var userCollection:ArrayCollection =
			new ArrayCollection();

// define a HTTPService that requests the XML data
&lt;mx:httpservice&gt;
    id="userlistrequest"
    url="http://yourserver.com/yourdbscript.php"
    useProxy="false"
    result="userCollection=ArrayCollection(userlistrequest.lastResult.dataset.entry)"
/&gt;
&lt;/mx:httpservice&gt;</pre>
<p>The second part of this Tutorial will cover some Flex internal stuff like custom cell rendering / item editors and, of course, some of the nasty little problems that can (or will?) arise with this altogether&#8230;. The Third part finally shows how to send updated data instantly back to the DB&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://lab.tojio.com/2007/11/12/flex-data-management-01-reading-data-from-a-remote-db-using-the-httpservice-class/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
