Sunday, January 2, 2011

Search through XML database using AS3: Part 3

Today we will make our search function more advanced using Regular Expressions.

Now, the search is less strict than in the previous tutorial. For example, we can write "J" in the first name search field, and we will get users that have "J" in their name. In our example - it is two Johns and one Justin.


We will be using regular expressions for this. First, let's define 3 variables for 3 search fields:

var pattern_firstname:RegExp;
var pattern_secondname:RegExp;
var pattern_job:RegExp;

Why are there 3 but not 5? Because we don't want this kind of feature for age, because it is a number, and for sex, because it is a ComboBox.

Here is the updated search function:

function search(MouseEvent):void
{
currentUserbase = [];

pattern_firstname = new RegExp(search_firstname.text);
pattern_secondname = new RegExp(search_secondname.text);
pattern_job = new RegExp(search_job.text);

for (var n:int = 0; n<allUserbase.length; n++)
{
if ((pattern_firstname.test(allUserbase[n].firstname) || search_firstname.text=="") && (pattern_secondname.test(allUserbase[n].secondname) || search_secondname.text=="") && (allUserbase[n].sex == search_sex.selectedItem.data || search_sex.selectedItem.data=="Any") && (allUserbase[n].age == search_age.text || search_age.text=="") && (pattern_job.test(allUserbase[n].job) || search_job.text==""))
{
currentUserbase.push(allUserbase[n]);
}
}
updateList();
}

As you can see, first we update all the 3 pattern regular expression variables. So, if we write "J" in the first name text field, the pattern_firstname variable will now be /J/. And that's exactly what we need to start checking if the first name of allUserbase[n] in the for..loop contains this "J" in it:

(pattern_firstname.test(allUserbase[n].firstname) || search_firstname.text=="") 

If it contains the part that is specified in the RegEx or if the textfield is empty, then it goes true. We need this kind of conditional for 3 parameters - firstname, secondname and job. The sex and age conditionals remain the same as in the previous tutorial.

The full code:

import fl.data.DataProvider;

var allUserbase:Array = [];// contains all users like in xml
var currentUserbase:Array = [];// contains users that need to be displayed

var _loader:URLLoader = new URLLoader();
var _data:XML = new XML();

_loader.addEventListener(Event.COMPLETE, readXML);
_loader.load(new URLRequest("userbase.xml"));

function readXML(event:Event):void
{
_data = new XML(event.target.data);
for each (var usr in _data.user)
{
allUserbase.push({id: usr.@id, firstname: usr.@firstname, secondname: usr.@secondname, sex: usr.@sex, age: usr.@age, job: usr.@job});
}
currentUserbase = allUserbase.concat();
updateList();
}

function updateList():void
{
userList.dataProvider = new DataProvider ();

for (var i:int = 0; i<currentUserbase.length; i++)
{
userList.addItem({label:currentUserbase[i].firstname + "  " + currentUserbase[i].secondname + "       " + currentUserbase[i].sex + "        " + currentUserbase[i].age + "       " + currentUserbase[i].job, data: currentUserbase[i].id});
}
}

// sorting buttons:

s_firstname.addEventListener(MouseEvent.CLICK, sortFirstname);
s_secondname.addEventListener(MouseEvent.CLICK, sortSecondname);
s_sex.addEventListener(MouseEvent.CLICK, sortSex);
s_age.addEventListener(MouseEvent.CLICK, sortAge);
s_job.addEventListener(MouseEvent.CLICK, sortJob);

function sortFirstname(MouseEvent):void
{
currentUserbase.sortOn("firstname");
updateList();
}
function sortSecondname(MouseEvent):void
{
currentUserbase.sortOn("secondname");
updateList();
}
function sortSex(MouseEvent):void
{
currentUserbase.sortOn("sex");
updateList();
}
function sortAge(MouseEvent):void
{
currentUserbase.sortOn("age");
updateList();
}
function sortJob(MouseEvent):void
{
currentUserbase.sortOn("job");
updateList();
}

// Search:

search_firstname.text = "";
search_firstname.restrict = "A-Za-z";
search_secondname.text = "";
search_secondname.restrict = "A-Za-z";
search_sex.dataProvider = new DataProvider([{label:"Any",data:"Any"},{label:"Male",data:"Male"},{label:"Female",data:"Female"}]);
search_age.text = "";
search_age.restrict = "0-9";
search_job.text = "";
search_job.restrict = "A-Za-z ";

var pattern_firstname:RegExp;
var pattern_secondname:RegExp;
var pattern_job:RegExp;

bt_search.addEventListener(MouseEvent.CLICK, search);

function search(MouseEvent):void
{
currentUserbase = [];

pattern_firstname = new RegExp(search_firstname.text);
pattern_secondname = new RegExp(search_secondname.text);
pattern_job = new RegExp(search_job.text);

for (var n:int = 0; n<allUserbase.length; n++)
{
if ((pattern_firstname.test(allUserbase[n].firstname) || search_firstname.text=="") && (pattern_secondname.test(allUserbase[n].secondname) || search_secondname.text=="") && (allUserbase[n].sex == search_sex.selectedItem.data || search_sex.selectedItem.data=="Any") && (allUserbase[n].age == search_age.text || search_age.text=="") && (pattern_job.test(allUserbase[n].job) || search_job.text==""))
{
currentUserbase.push(allUserbase[n]);
}
}
updateList();
}

Thanks for reading!

Related:

Search through XML database using AS3: Part 1
Search through XML database using AS3: Part 2
Search through XML database using AS3: Part 4
Search through XML database using AS3: Part 5
Search through XML database using AS3: Part 6

2 comments:

tmcanally said...

First off, my supervisors love me because of you and your code in this tutorial.

We use this code (slightly tweaked) to display an equipment list that we send to our clients for their project.

My supervisors came back to me with a concern that they said I MUST find a solution for; they won't accept a no from me. I was hoping you could help me out. I have been working on this for probably 4 months now and I can't get it to work right.

What we want to do: I have already applied a text format to the datagrid component. We want to have a different font color on different rows. I would like to put the hex triplet color code, or any other color format, in the userbase.xml file and use that as THAT row's font color. Different rows will have different colors (or else I would have just applied it to the whole grid).

I saw this done in a different tutorial on another site, but he was unable to help me. I can provide more details if I need to as well as copies of our code, xml, and url to the other tutorial.

PLEASE PLEASE PLEASE help me. My supervisor say I HAVE to do this. Since it's your code, you have a better understanding of it than I do.

Thanks in advance,
Taylore M.

tmcanally said...

Maybe it's even possible this way:

In your example above, let's pretend that "driver", "shop assistant", "manager", etc. was the hex triplet I wanted to use for that row and that row only. Is there a way to use the value in that column on that row (respectively)?

Again keeping in mind that it has to have the ability to be different on each row.

Post a Comment