How to prevent duplicate values in a combo box - php

I have a view in my codeigniter app that gets an array from the database.
I want to create several combo boxes based on the contents of the array.
Here's what the array looks like:
Array (
[0] => Array (
[L1ID] => 2
[L1Location] => USA
[L2ID] => 3
[L2Location] => New York
[L3ID] => 4
[L3Location] => Manhanttan
)
[1] => Array (
[L1ID] => 2
[L1Location] => USA
[L2ID] => 8
[L2Location] => New Jersey
[L3ID] => 7
[L3Location] => Bergen County
)
[2] => Array (
[L1ID] => 5
[L1Location] => Canada
[L2ID] => 12
[L2Location] => Ontario
[L3ID] => 50
[L3Location] => Toronto
)
[3] => Array (
[L1ID] => 6
[L1Location] => South Korea
[L2ID] => 22
[L2Location] => Gyungido
[L3ID] => 25
[L3Location] => Buchon
)
)
As you can see, each item in the array can have up to 3 locations defined within.
I would like to create a combo box that has all the Location 1's in it.
So, in other words, it will have "USA", "CANADA", "SOUTH KOREA" as options. When the user clicks on any location, i want to query the same array and get the next level down - all the location 2's - populated in a separate combo box.
So for example, when they select "USA" in location 1, location 2 combo will show "New York" and "New Jersey" as options.
I've written some code to start looping through the array and extract all L1's (location 1's) but I don't know how to prevent duplicates from being added.
Here's my code:
<select id="L1locationlist" name="L1locationlist">
<option value=""></option>
<?php
foreach ($locations as $location) {
echo ($location['L1ID'].'<BR>');
echo '<option value="' . $location['L1ID'] . '">' . $location['L1Location'].'</option>';
}
?>
</select>
I only want one USA entry in the combo box.
Can you tell me how I can do this? Do I have to create a separate function to check if it already exists in the combo box?
Thank you.
EDIT:
The original plan was to get all location information once from the database, and then on the client side, somehow dynamically drill down into the different locations depending on what the user clicks.
But I guess I should also ask whether this is a good design or not? Perhaps the code will be "cleaner" if I just make separate calls to the database. So for example, I will initially just get all location 1 values. Then if the user selects "USA" i will query the db again for all sublocations in USA.
I guess the initial thought was to save multiple trips to the db.
Any comments?

The first thing I would do is parse the array to get all the ocations in the format you want it:
$parsedLocations = array(1 => array(), 2 => array(), 3 => array());
foreach ($locations as $location) {
for($i = 1; $i < 4; $i++) {
$parsedLocations[i][$location['L' . $i . 'ID']] = $location['L' . $i . 'Location']
}
}
Once you have the array you need you can simply display the items and make them unique with array_unique():
<select id="L1locationlist" name="L1locationlist">
<option value=""></option>
<?php
$locations = array_unique($parsedLocations[1]);
foreach($locations as $key => $location) {
echo ' <option vaue="' . $key . '">' . $location . '</option>';
}
?>
</select>
If you want to do this dynamically for all three locations you could do something like the following (with the same parsed locations array):
<?php
for ($i = 1; $i < 4; $i++) {
echo '<select id="L' . $i . 'locationlist" name="L' . $i . 'locationlist">';
echo ' <option value=""></option>';
$locations = array_unique($parsedLocations[1]);
foreach($locations as $key => $location) {
echo ' <option vaue="' . $key . '">' . $location . '</option>';
}
echo '</select>';
}

Loop through the $locations array and generate a new array for each box, checking values as you go. Then, loop through each of those arrays and generate the boxes. (Demo.)
<?php
$countries = array();
$states = array();
$cities = array();
foreach ($locations as $location) {
if(!array_key_exists($location['L1ID'], $countries))
$countries[$location['L1ID']] = array(
'name' => $location['L1Location'],
'states' => array(),
);
if(!array_key_exists($location['L2ID'], $countries[$location['L1ID']]['states'])){
$countries[$location['L1ID']]['states'][$location['L2ID']] = array(
'name' => $location['L2Location'],
'cities' => array(),
);
}
if(!array_key_exists($location['L3ID'], $countries[$location['L1ID']]['states'][$location['L2ID']])){
$countries[$location['L1ID']]['states'][$location['L2ID']]['cities'][$location['L3ID']] = $location['L3Location'];
}
}
// Generate $countries box
foreach ($countries as $key => $country) {
echo ($key.'<BR>'."\n");
echo '<option value="' . $key . '">' . $country['name'].'</option>'."\n";
// Generate $states box
foreach ($country['states'] as $key => $state) {
echo ($key.'<BR>'."\n");
echo '<option value="' . $key . '">' . $state['name'].'</option>'."\n";
// Generate $city box
foreach ($state['cities'] as $key => $city) {
echo ($key.'<BR>'."\n");
echo '<option value="' . $key . '">' . $city.'</option>'."\n";
}
}
}
?>

try this
$i = 1;
foreach ($locations as $location) {
if(isset($locations[$i-1]['L1Location']) && $locations[$i-1]['L1Location'] != $location['L1Location'] && $i != 1){
echo ($location['L1ID'].'<BR>');
echo '<option value="' . $location['L1ID'] . '">' . $location['L1Location'].'</option>';
$i++;
}
}
Apart from this its better if you group by L1Location in your query then no need to code like above simple foreach loop

Related

Looping into a multidimensional array with PHP

I've got this array:
Array
(
[0] => Array
(
[name] => System
[order] => 1
[icon] => stats.svg
[0] => Array
(
[title] => Multilingual
)
[1] => Array
(
[title] => Coloring
)
[2] => Array
(
[title] => Team work
)
[3] => Array
(
[title] => Tutorials
)
)
)
I want to loop into this to show the section name and after all the features containing in the following array.
So, this is what I made:
foreach ($features as $feature => $info) {
echo '
'.$info['name'].'
<ul class="menu-vertical bullets">
';
foreach (array_values($info) as $i => $key) {
echo '
<li>'.$key['title'].'</li>
';
}
echo '
</ul>
';
}
It works except for the first third <li> where I have the first char of name, order and icon value.
Do you know why ?
Thanks.
array_values return value of array so for info values is name, order, icon, 0, 1, ...
Your values foreach is wrong if you just want print title you can use:
foreach ($features as $feature => $info) {
echo '
'.$info['name'].'
<ul class="menu-vertical bullets">
';
//Remove some keys from info array
$removeKeys = array('name', 'order', 'icon');
$arr = $info;
foreach($removeKeys as $key) {
unset($arr[$key]);
}
foreach (array_values($arr) as $i => $key) {
echo '
<li>'.$key['title'].'</li>
';
}
echo '
</ul>
';
}
In php, array_values means all the values of the array. So array_values($info) is array($info['name'], $info['order'], $info['icon'], $info[0], $info[1], $info[2], $info[3])
in your example, you can skip the non-integer keys of the $info to get your titles:
<?php
$features = array();
$info = array();
$info['name'] = 'System';
$info['order'] = 1;
$info['icon'] = 'stats.svg';
$info[] = array('title'=>'Multilingual');
$info[] = array('title'=>'Coloring');
$features[] = $info;
foreach ($features as $feature => $info) {
echo $info['name'] . PHP_EOL;
echo '<ul class="menu-vertical bullets">' . PHP_EOL;
foreach ($info as $k => $item) {
if(!is_int($k)) continue;
echo '<li>' . $item['title'] . '</li>' . PHP_EOL;
}
echo '</ul>' . PHP_EOL;
}
BUT, your original data structure is not well designed and hard to use. For a better design, you can consider the following code, move your items to a sub array of $info:
<?php
$features = array();
$info = array();
$info['name'] = 'System';
$info['order'] = 1;
$info['icon'] = 'stats.svg';
$info['items'] = array();
$info['items'][] = array('title'=>'Multilingual');
$info['items'][] = array('title'=>'Coloring');
$features[] = $info;
foreach ($features as $feature => $info) {
echo $info['name'] . PHP_EOL;
echo '<ul class="menu-vertical bullets">' . PHP_EOL;
foreach ($info['items'] as $item) {
echo '<li>' . $item['title'] . '</li>' . PHP_EOL;
}
echo '</ul>' . PHP_EOL;
}
Sample output of the two demos:
System
<ul class="menu-vertical bullets">
<li>Multilingual</li>
<li>Coloring</li>
</ul>
It works except for the first third li where I have the first char of name, order and icon value. Do you know why ?
Why you see first chars of the values of 'name', 'order', 'icon'? Let see how PHP works.
Take the first loop as an example: foreach (array_values($info) as $i => $key)
Then $i == 0, $key == 'System'
We know that $key[0] == 'S', $key[1] == 'y', $key[2] == 's', etc.
Then you try to access $key['title'], but the string 'title' is not valid as a string offset, so it is converted to an integer by PHP: intval('title') == 0.
Then $key['title'] == $key[intval('title')] == 'S'
That's what you see.
array_value() returns the values of the array, here you will get the value of the array $info and what I understand is that is not what you need. See details for array_value().
You can check if the key for the $info is an integer. if yes, echo the title. Give this a try.
foreach ($features as $feature => $info) {
echo $info['name'].'<ul class="menu-vertical bullets">';
foreach ($info as $key => $value) {
if (is_int($key)) {
echo '<li>'.$key['title'].'</li>';
}
}
echo '</ul>';
}

The UTF-8 sorted array doesn't work with foreach in PHP

Only the collator (UTF-8 sorted array) works without foreach and with only one value in an array.
But I am using foreach and multiple values in an array.
Here is the code:
<select name="courses">
<?php
$list_courses =
array(
array("course" => "Management",
"value" => "course1",
"emoji" => "test1"),
array("course" => "Éducation Physique",
"value" => "course2",
"emoji" => "test2"),
array("course" => "Électrotechnique",
"value" => "course3",
"emoji" => "test3"),
array("course" => "Géographie",
"value" => "course4",
"emoji" => "test4"),
);
$coll = new Collator('fr_FR');
$coll->sort($list_courses);
foreach ($list_courses as $key => $value)
{
echo ('<option value="' . "$value[value]" . '" data-icon="' . "$value[emoji]" . '">' . "$value[course]" . '</option>');
}
?>
</select>
<label for="courses">Cours</label>
With collator, it is still the same order, but with foreach, then here is the actual behaviour in the output:
Management
Géographie
Éducation Physique
Électromécanique
Collator::sort works on an array of strings - if you're passing it a multi-dimensional array then the output is going to be undefined.
You can work round this by re-indexing your array into a key->value structure instead, and then making a slight change to your loop:
// Re-index array to key=>value
$list_courses = array_column($list_courses, 'course', 'value');
// Sort by values (note asort, to maintain keys)
$coll = new Collator('fr_FR');
$coll->asort($list_courses);
foreach ($list_courses as $key => $value) {
echo '<option value="' . $key . '">' . $value . '</option>';
}
If your arrays are more complicated than this, you'll need to use a native sorting function like uasort, and make use of the Collator to do the actual comparison:
$collator = new Collator('fr_FR');
uasort($list_courses, function ($a, $b) use($collator) {
return $collator->compare($a['course'], $b['course']);
});
foreach ($list_courses as $value) {
echo '<option value="' . $value['value'] . '" data-icon="' . $value['emoji'] . '">' . $value['course'] . '</option>', PHP_EOL;
}
Here, we deal with the array objects in their entirety, so there's no need to re-index.

select a specific value from multi array by the first row

I'm pulling 3 colummns from one table and storing them in an array as such to populate a dropdown menu. The ref_code is used to decide which dropdown it will go to ('Module','Customer','Application') while id is the select value and ref_desc is the display text.
foreach ($test as $t) {
$aa[] = array($t->ref_code => array('id'=>$t->id, 'ref_desc'=>$t->ref_desc));
};
I've been trying to retrieve them using $aa['ref_code'] but have not been getting any success. Help please.
This question is similar, but I am unable to retrieve the values I want.
I found a solution on another forum but I will also give your solutions a try later. Thank you very much!
foreach ($aa as $a => $d) {
foreach ($d as $ref_code => $dd) {
echo "<p>". $ref_code ."</p>";
echo "<p>". $dd['ref_desc'] ."</p>";
echo "<p>". $dd['id'] ."</p>";
};
};
Why don't you write it like this? The ref_code (if it's unique) is the key of the array.
foreach ($test as $t) {
$aa[$t->ref_code] = array('id'=>$t->id, 'ref_desc'=>$t->ref_desc);
};
you need a three dimensional array:
dropdown => ids => displaytext
here we go:
// fill in:
$aa = array();
foreach ($test as $t) {
if ( !isset($aa[$t->ref_code]) )
$aa[$t->ref_code] = array();
$aa[$t->ref_code][$t->id] = $t->ref_desc;
};
// have a drop down:
$myDropDown = 'Customer';
foreach ( $aa[$myDropDown] as $id => $displaytext )
{
echo "<option value=\"" . $id . "\">" . $displaytext . "</option>";
}
.... etc.

Pass array values into select option fields within a form?

This is based in PHP.
Is it possible to take an array like this:
$SELECT_INDUSTRY = array("Medical" => "Specialty", "Dental" => "Specialty", "Pediatrics" => "Specialty");
And have that pass those two values into something simple like this:
<select>
<option value="$SELECT_INDUSTRY[]">$SELECT_INDUSTRY[]</option>
</select>
Where Medical would be the value being passed, and Specialty would be the public facing text.
This is the function I'm using to build the actual select boxes:
$SELECT_INDUSTRY = array("Medical", "Dental", "Pediatrics");
$FORM_SELECT_SIZE = 'input-min';
function get_options_industry( $arr = array() ) {
global $FORM_SELECT_SIZE;
echo '<div class="control-group"><label class="control-label" for="industry">Industry</label><div class="controls"><select name="industry" id="industry" class="'.$FORM_SELECT_SIZE.'"><option value=>Select an Industry</option>';
foreach( $arr as $option ) {
echo '<option>'.$option.'</option>';
}
echo '</select></div></div>';
}
$FORM_FIELD_INDUSTRY = $SELECT_INDUSTRY;
And this is how I'm displaying the select:
<?php get_options_industry( $FORM_FIELD_INDUSTRY ) ?>
I feel like I'm close, or at least on the right track, just can't figure out how to pull the first array value into the value field, then the second into the actual name.
The goal is to get the value being passed in the form, is different than the public facing name. I realize that the above array definition I gave may not be the correct way to do this.
SOLUTION
Thanks to a couple responses below, here is the final answer to solve my problem:
$SELECT_INDUSTRY = array("Medical" => "Medical", "Dental" => "Medical", "Pediatrics" => "Medical");
$FORM_SELECT_SIZE = 'input-min';
function get_options_industry( $arr = array() ) {
global $FORM_SELECT_SIZE;
echo '<div class="control-group"><label class="control-label" for="industry">Industry</label><div class="controls"><select name="industry" id="industry" class="'.$FORM_SELECT_SIZE.'"><option value=>Select an Industry</option>';
foreach( $arr as $key => $value ) {
echo '<option value="'.$value.'">'.$key.'</option>';
}
echo '</select></div></div>';
}
$FORM_FIELD_INDUSTRY = $SELECT_INDUSTRY;
I then have to make sure that my key is unique so no duplicates are erased.
How about this?
$SELECT_INDUSTRY = array("Medical" => "Specialty", "Dental" => "Specialty", "Pediatrics" => "Specialty");
.... other stuff you already have ....
foreach( $arr as $val => $option ) {
echo '<option value="'.$val.'">'.$option.'</option>';
}
Quick example...
$SELECT_INDUSTRY = array("Medical" => "Specialty", "Dental" => "Specialty", "Pediatrics" => "Specialty");
echo '<select>';
foreach ($SELECT_INDUSTRY as $key => $value) {
echo '<option value="' . $value . '">' . $key . '</option>';
}
echo '</select>';
You can reverse $key and $value depending on which you want displayed as the text and which you would like passed as the value. The way I displayed it in my example made the most sense to me.
This one works fine
$SELECT_INDUSTRY = array("Medical", "Specialty", "Dental", "Specialty", "Pediatrics", "Specialty");
echo '<select>';
foreach ($SELECT_INDUSTRY as $key => $value) {
echo '<option value="' . $value . '">' . $key . '</option>';
}
echo '</select>';

php array and foreach?

Below is my code I am trying to get to work but I really have very little knowledge of array and foreach. So it doesn't work correctly
I need to show a dropdown select form to the browser with the contents of the array
I also need to have the item selected if it is == to $mycountry
Lastly, I would like to show the USA and UK at the top of my list
Can anyone tell me how I can do al this
<?PHP
$countries = array(
"217" => "Turkenistan",
"218" => "Turks and Caicos Islands",
"219" => "Tuvalu",
"220" => "Uganda",
"221" => "Ukraine",
"222" => "United Arab Emirates",
"223" => "United Kingdom (Great Britain)",
"224" => "United States");
$mycountry = 224;
?>
<select name="country" style="width:180px;" onChange="do_get_rest_popup(this.value)" />
<?php
$countryCounter = 1;
$amtOfCountries = count($countries);
//foreach ($country as $id => $c) {
for( $_top=0; $_top < $amtOfCountries; $_top++ ){
if ($countryCounter == $amtOfCountries) {
echo "<option value=\"$countries[0]\" SELECTED>$countries[1]</option>";
} else {
echo "<option value=\"$countries[0]\">$countries[1]</option>";
$countryCounter++;
}
}
?>
</select>
foreach ($countries as $key => $country) {
$selected = ""
if ($key == $mycountry) $selected = ' selected="selected" ';
print '<option value=' . $key . $selected . '>' . $country . '</option>';
}
Basically, for every element within the array, you are breaking it into its key and its value (ie $countreis[key] = value). Once you get your head around arrays (and they can be very confusing) it will make coding a million times easier.
(For some reason the syntax highlighting / formatting is not working in my code...)
I'm going to guess you are looking for:
foreach($countries as $id => $country) {
echo '<option value="$id"' . ($mycountry==$id?'selected="selected"':'') . '>' . $country . '</option>';
}
As for making sure that the U.S. and U.K. are on top, make sure that those 2 are on top of your array (that would be the very easiest).
You should put US and UK at the top of your array and then use something like:
foreach($countries as $row => $value) {
echo "<option value=\"$row\"" + ($row == 'usa' ? 'SELECTED') + ">$value</option>";
}
and you should use selected="selected" instead of SELECTED

Categories