populate combo box from xml

I had posted a previous question which contained a sample xml file.  The solution I received was perfect.  That post with the sample xml file can be found at:
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_25913497.html

Now, besides a name search I want the user to be able to filter by 'Location'.  I would like a combo box to be populated with a unique list of Locations used in the XML document.  Is this possible?  So if there were 20 entries with 'Acctg', 15 entries with 'IT Dept', the combobox would only have 2 entries, Acctg and IT Dept showing only once each.

Is this possible?

Attached you will find some code I tried.
<?php
   $xml = simplexml_load_file("PhoneList.xml");
?>

<form action="PhoneList.php" method="post">
   <label for="LastName">Name Contains:</label>
   <input type="text" id="LastName" name="LastName" />
   <input type="submit" value="Search" name="submit" />
	<select name="LocationFilter" id="SelectLocation">
	<?php
		foreach ($xml->Location as $record) 
		{
			echo "<option value=\"" . $record->Location . "\"";
				if ($_POST['LocationFilter'] == $record->Location)
				{
					echo "selected";
				}
			echo ">" . $record->Location . "</option>";
		} 
	?>
		<option value="0">All</option>
	</select>
</form>

Open in new window

KCTechNetAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

BardobraveCommented:
Ok, I think your problem here is that you get a combo with many repeated values isn't it? You need to find some way to don't add an option when an option with this value already exists in your select.

To do that you could try many ways. One that comes to my mind now is this:
Use a string variable to store the locations you're adding, your string starts being a null string.

when you read a location from the xml, make a substring search of this location in your string variable. If the location is there you've added it to the select already, if not, you can generate an option with this location and add it to the string variable (use some type of separator in the variable, "|" for example).

If you have locations that are part of others like 'IT Dep' and 'Advanced IT Dep' this system would need some refination to work ok.

I hope this help you.
0
SwafnilCommented:
The trick is to store each already displayed node value in an array and before displaying the currently read node value, check if it has been stored in the array before.

See if this works for you!
<?php
   $xml = simplexml_load_file("PhoneList.xml");
?>

<form action="PhoneList.php" method="post">
   <label for="LastName">Name Contains:</label>
   <input type="text" id="LastName" name="LastName" />
   <input type="submit" value="Search" name="submit" />
        <select name="LocationFilter" id="SelectLocation">
        <?php
			// add an array holding all found locations
			$storedLocations = array();
			
			foreach ($xml->Location as $record) 
			{
				// check if we already displayed this location (if shown before, it would have been stored in $storedLocations)
				if (!array_key_exists($record->Location, $storedLocations)){
					echo "<option value=\"" . $record->Location . "\"";
							if ($_POST['LocationFilter'] == $record->Location)
							{
									echo "selected";
							}
					echo ">" . $record->Location . "</option>";
					// store the location name in the $storedLocations array
					$storedLocations[$record->Location] = true;
				}	
			} 
        ?>
                <option value="0">All</option>
        </select>
</form>

Open in new window

0
KCTechNetAuthor Commented:
Thanks for the replies.  

It looked like the first issue was foreach($xml->Location as $record).  I say this because I am only getting 'All' in my combo box, as if it is not looping through the records.  I changed it to $xml->tblPhoneList and it seemed to now list all the Departments.  However, even with the code above, I am still getting an item for all the records, it is not giving a Distinct list.
0
OWASP: Forgery and Phishing

Learn the techniques to avoid forgery and phishing attacks and the types of attacks an application or network may face.

SwafnilCommented:
could you post what you got in your script where you are printing the option values to the select list? It's line 23 in my code. I guess there's just a minor change necessary to remove the dupes.
0
KCTechNetAuthor Commented:
Are you asking for me to repost my code?  If so, here it is.  Sorry, I have modified it since my original post but I kept your code intact.
<?php
   $xml = simplexml_load_file("PhoneList.xml");
?>

<form action="EESample.php" method="post">
	<fieldset>
		<legend> Search Criteria</legend>
		<table>
			<tr>
				<td><label for="LastName">Name Contains:</label></td>
				<td><label for="SelectLocation">Department:</label></td>
				<td></td>
			</tr>
			<tr>
				<td>
                    <input type="text" id="LastName" name="LastName" value="<?php echo $_POST['LastName'] ?>" />
                </td>
				<td>
                    <select name="LocationFilter" id="SelectLocation">
                    <?php
                        // add an array holding all found locations
                        $storedLocations = array();
                        
                        foreach ($xml->tblPhoneList as $record) 
                        {
                            // check if we already displayed this location (if shown before, it would have been stored in $storedLocations)
                            if (!(array_key_exists($record->Location, $storedLocations)))
                            {
                                echo "<option value=\"" . $record->Location . "\"";
                                if ($_POST['LocationFilter'] == $record->Location)
                                {
                                    echo "selected";
                                }
                                echo ">" . $record->Location . "</option>";
                                // store the location name in the $storedLocations array
                                $storedLocations[$record->Location] = true;
                            }       
                        } 
                    ?>
                            <option value="0">All</option>
                    </select>                
				</td>
				<td><input type="submit" value="Search" name="submit" /></td>
			</tr>
		</table>
	</fieldset>
</form>

Open in new window

0
KCTechNetAuthor Commented:
now that i think about it I may want to do things differently anyway.  I'm thinking perhaps they should be loaded into an array first, doing a SORT_STRING, then loop them into the Select list.  But one hang up would still be how to make sure the array only contains unique values.
0
SwafnilCommented:
Good morning,

If you are using arrays, it's really simple to check for duplicates, in fact this will be done automatically if you are using the right keys (see below code).
If you don't want to overwrite values or keys, there are two functions available for testing if values exist:

array_search (returns the first element matching the search)
http://us.php.net/array_search

array_key_exists (returns true in case key is found)
http://us.php.net/manual/en/function.array-key-exists.php


<?php
// init. empty array
$arrValues = array();
// add some unique values
$arrValues["IT"] = "IT Department";
$arrValues["HR"] = "Human Resources";
// now imagine that your script continues to add values to the array and finds the IT department with short name IT again
$arrValues["IT"] = "IT Department";
// the above statement would overwrite the previous "IT" entry so you'd have "IT Department" only once

Open in new window

0
KCTechNetAuthor Commented:
I'm guessing I have something wrong, because it seems to be allowing duplicate values.  Here is my revised code
<?php
   $xml = simplexml_load_file("PhoneList.xml");
    $storedLocations = array();   
    foreach ($xml->tblPhoneList as $record) 
    {
        $storedLocations[]=$record->Location;
    }
    sort($storedLocations);
?>

<form action="PhoneList.php" method="post">
	<fieldset>
		<legend> Search Criteria</legend>
		<table>
			<tr>
				<td><label for="NameSearch">Name Contains:</label></td>
				<td><label for="SelectLocation">Department:</label></td>
				<td></td>
                <td></td>
			</tr>
			<tr>
				<td>
                    <input type="text" id="NameSearch" name="NameSearch" value="<?php echo $_POST['NameSearch'] ?>" />
                </td>
				<td>
                    <select name="LocationFilter" id="SelectLocation">
                        <option value="All">Show All</option>
                        <?php
                            foreach($storedLocations as $value) 
                            {
                                echo "<option value=\"" . $value . "\"";
                                if ($_POST['LocationFilter'] == $value)
                                {
                                    echo "selected";
                                }
                                echo ">" . $value . "</option>";
                            }
                        ?>                            
                    </select>                
				</td>
				<td><input type="submit" name="submit"  value="Search"/></td>
                <td><input type="reset"  name="reset"   value="Reset"></td>
			</tr>
		</table>
	</fieldset>
</form>

Open in new window

0
KCTechNetAuthor Commented:
also, it looks like the sort is not even working as the resulting combobox is not in alphabetical order
0
SwafnilCommented:
In your above example, you would have had to use array_search() before adding the value to the array, because you were using a numeric index instead of self-defined array keys. I modified your script to use the location names as array key (lowercased for correct sorting) and used ksort to sort the array according to the keys, not values.
<?php
	$xml = simplexml_load_file("PhoneList.xml");
    $storedLocations = array();   
    foreach ($xml->tblPhoneList as $record) 
    {
		// use the location as array key, convert all keys to lowercase, otherwise mixed capitals wouldn't be sorted correctly
        $storedLocations[strtolower($record->Location)]=$record->Location;
    }
	// sort the array keys instead of array values;
    ksort($storedLocations);
?>

<form action="PhoneList.php" method="post">
        <fieldset>
                <legend> Search Criteria</legend>
                <table>
                        <tr>
                                <td><label for="NameSearch">Name Contains:</label></td>
                                <td><label for="SelectLocation">Department:</label></td>
                                <td></td>
                <td></td>
                        </tr>
                        <tr>
                                <td>
                    <input type="text" id="NameSearch" name="NameSearch" value="<?php echo $_POST['NameSearch'] ?>" />
                </td>
                                <td>
                    <select name="LocationFilter" id="SelectLocation">
                        <option value="All">Show All</option>
                        <?php
                            foreach($storedLocations as $value) 
                            {
                                echo "<option value=\"" . $value . "\"";
                                if ($_POST['LocationFilter'] == $value)
                                {
                                    echo "selected";
                                }
                                echo ">" . $value . "</option>";
                            }
                        ?>                            
                    </select>                
                                </td>
                                <td><input type="submit" name="submit"  value="Search"/></td>
                <td><input type="reset"  name="reset"   value="Reset"></td>
                        </tr>
                </table>
        </fieldset>
</form>

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
KCTechNetAuthor Commented:
Worked like a charm.  Thanks for your time!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.