Link to home
Start Free TrialLog in
Avatar of KCTechNet
KCTechNetFlag for United States of America

asked on

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:
https://www.experts-exchange.com/questions/25913497/read-xml-into-an-HTML-table.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

Avatar of Bardobrave
Bardobrave
Flag of Spain image

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.
Avatar of Swafnil
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

Avatar of KCTechNet

ASKER

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.
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.
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

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.
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

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

also, it looks like the sort is not even working as the resulting combobox is not in alphabetical order
ASKER CERTIFIED SOLUTION
Avatar of Swafnil
Swafnil
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Worked like a charm.  Thanks for your time!