I decided to try out Laravel and wanted to create dropdowns for my form. I created a convinience method inside my BaseController that I use to get the data from the database. Below is the function listing:
protected function getList( $model, array $fields, $empty = 'Select option below' )
{
$options = array();
$owner = strtolower( $model ) . 's';
$records = $model::lists($fields[1], $fields[0]);
if( !empty( $records ) ){
foreach( $records as $key => $value ){
$options[$owner][$value] = $key;
}
}
$options[$owner][''] = $empty;
return $options;
}
And then in the controller you can just use it like:
//Get groups
$groups = $this->getList( 'Group', array(
'name', 'id'
));
//Get Project Managers
$project_managers = $this->getList( 'ProjectManager', array(
'name', 'id'
));
The output of the select form control has an optgroup that references the owner of the list or the model rather. How can I remove the optgroup such that its not part of the contents of the dropdown?
Below is the output of the form:
<div class="input select">
<label for="project_manager">Project Manager</label>
<select name="project_manager_id">
<optgroup label="projectmanagers">
<option value="1">Riyaadh</option>
<option value="2">Luyanda</option>
<option selected="selected" value="">Select option below</option>
</optgroup>
</select>
</div>
You are adding another level within your getLists method with this line; $options[$owner][$value] = $key;, this is what is adding your optgroup, to get rid of this change the line to $options[$value] = $key;.
Optionally you can reduce the code of your getLists function to the following;
protected function getList( $model, array $fields, $empty = 'Select option below' )
{
$options = array();
$owner = strtolower( $model ) . 's';
$records = $model::lists($fields[1], $fields[0]);
if( !empty( $records ) ){
$options = array_flip($records);
}
$options[''] = $empty;
return $options;
}
This uses the array_flip method, which exchanges the keys as values and values as keys.
Try this...
$SchoolDetails = GeneralSettingModel::lists('SchoolName', 'id');
or
$SchoolDetails = DB::table('tablename')->lists('SchoolName', 'id');
{{ Form::select('SchoolName',array(''=>'Select School')+$SchoolDetails,null, array('id'=> 'SchoolName'))}}
Output:
<select id="SchoolName" name="SchoolName">
<option value="" selected="selected">Select School</option>
<option value="1">test</option>
<option value="2">test355wrew</option>
<option value="3">GOVT</option>
<option value="4">Kumaraguru</option>
<option value="5">valavan</option>
</select>
you can remove using JQuery by adding ID to select
$(function () {
$("#mySelect").children().remove("optgroup");
});
As Matt Burrow suggested it turned out that I was creating a multi-dimentional array which is translated to a list with optgroup.
I modified my function to rather exclude the owner which the records belong to. Below is my perfectly working function (excerpt):
...
if( !empty( $records ) ){
foreach( $records as $key => $value ){
$options[$value] = $key;
}
}
$options[''] = $empty;
...
Related
I need to add a drop-down menu that filtrates with enum values from the table. Instead of that it gets the values from the rows. Any and all help gratefully received.
This is what I have managed to get so far.
View:
<div>
<span>
<select class="mb-2">
<option value="Status" disabled selected>Status</option>
#foreach ($status_filter as $key => $status)
<option value="{{ $key }}">
{{$status}}
</option>
#endforeach
</select>
</span>
</div>
Controller:
$status_filter = Competition::pluck('status');
$request->flash();
return view('competition.index', compact('competitions', 'status_filter'));
This is what I need to get from the migration:
$table->enum('status',['inactive','to_push','active'])->default('inactive');
You can grab those enum values from the table. But there is no direct way. You have to use laravel query builder using raw.
$statusValues = DB::select(DB::raw("SHOW COLUMNS FROM competitions WHERE Field = 'status' "))[0]->Type;
$matches = array();
preg_match('/^enum\((.*)\)$/', $statusValues, $matches);
$enumValues = array();
foreach( explode(',', $matches[1]) as $value )
{
$v = trim( $value, "'" );
$enumValues = $v;
}
print_r($enumValues)
If i got it right you want to make a filter for status like listing all active ou inactive. I think the easiest way to do this is add a query on your variable $status_filter on the controller. Something like: $status_filter = Competition::where('status', 'active')->pluck('status');
As #SazzadHussain suggested adding this block of code inside my model class solved the issue.
public static function getPossibleEnumValues($table, $column) {
$type = DB::select(DB::raw("SHOW COLUMNS FROM $table WHERE Field = '{$column}'"))[0]->Type ;
preg_match('/^enum\((.*)\)$/', $type, $matches);
$enum = array();
foreach( explode(',', $matches[1]) as $value )
{
$v = trim( $value, "'" );
$enum = Arr::add($enum, $v, $v);
}
return $enum;
}
After that getting it from my Controller like that:
$enumoption = Competition::getPossibleEnumValues('competitions','status');
I have this function that allows me to select a category (from a select combo) to associate with a product while I'm creating it. It works well but when I modify the product, I would like that the category assigned during creation, remain selected and visible at the beginning of the combo.
I suppose that i have to change something into the function when i update the product.
Any suggestion?
Thanks
Function:
function CategoryTree(&$output=null, $cat_parent_id=0, $indent=null){
global $con;
try {
// prepare select query
$query = "SELECT * FROM category WHERE cat_parent_id=:parentid AND cat_lang = '{$_SESSION['lang']}'";
$stmt = $con->prepare($query);
// this is the first question mark
$stmt->bindParam(2, $id);
// execute our query
$stmt->execute(array( 'parentid' => $cat_parent_id));
while($c = $stmt->fetch(PDO::FETCH_ASSOC)){
$disable= "";
if($cat_parent_id==0 ){
$disable= 'disabled="disabled" style="color:black;font-weight:bold;font-style:oblique"';
}
$output .= '<option '. $disable.' value=' . $c['cat_id'] . '>' . $indent . $c['cat_name'] . "</option>\n";
if($c['cat_id'] != $cat_parent_id){
CategoryTree($output, $c['cat_id'], $indent . " ");
}
}
// return the list of categories
return $output;
}
// show error
catch(PDOException $exception){
die('ERROR: ' . $exception->getMessage());
}
}
HTML:
<select name="category" class="form-control" id="category" required />
<option value="">Select a category</option>
<?php
echo CategoryTree();
?>
</select>
I think what you need (if I have understood your problem correctly) is to make use of the 'selected' attribute of the option you can say which option is marked as selected when the page loads by saying
'<option '. $disable.' value=' . $c['cat_id'] . ' selected>'
(https://www.w3schools.com/tags/att_option_selected.asp)
You can then use the value in the $_POST['category'] when the form is submitted and compare it to the category value ($c['cat_id']) in the loop to decide which element is selected.
When the form is submitted and the page reloaded then the last selected value will remain selected.
Forgive me if I haven't understood your question properly, but I THINK this is what you mean
Ok, I'll rewrite my question here, since I can't explain myself. I have to rewrite this code from the old mysql_ to PDO.
Perhaps by writing code directly it is better understood.
The main function:
/*
Generate combo box options containing the categories we have.
if $catId is set then that category is selected
*/
function buildCategoryOptions($catId = 0)
{
$sql = "SELECT cat_id, cat_parent_id, cat_name
FROM tbl_category WHERE cat_lang = '{$_SESSION['lang']}'
ORDER BY cat_id";
$result = dbQuery($sql);
$categories = array();
while($row = dbFetchArray($result)) {
list($id, $parentId, $name) = $row;
if ($parentId == 0) {
// we create a new array for each top level categories
$categories[$id] = array('name' => $name, 'children' => array());
} else {
// the child categories are put int the parent category's array
$categories[$parentId]['children'][] = array('id' => $id, 'name' => $name);
}
}
// build combo box options
$list = '';
foreach ($categories as $key => $value) {
$name = $value['name'];
$children = $value['children'];
$list .= "<optgroup label=\"$name\">";
foreach ($children as $child) {
$list .= "<option value=\"{$child['id']}\"";
if ($child['id'] == $catId) {
$list.= " selected";
}
$list .= ">{$child['name']}</option>\r\n";
}
$list .= "</optgroup>";
}
return $list;
}
Create.php:
$catId = (isset($_GET['catId']) && $_GET['catId'] > 0) ? $_GET['catId'] : 0;
$categoryList = buildCategoryOptions($catId);
and then
<select name="cboCategory" id="cboCategory" class="width-50">
<option value="" selected>-- Choose Category --</option>
<?php
echo $categoryList;
?>
</select>
update.php
// get category list
$sql = "SELECT cat_id, cat_parent_id, cat_name
FROM tbl_category
ORDER BY cat_id";
$result = dbQuery($sql) or die('Cannot get Product. ' . mysql_error());
$categories = array();
while($row = dbFetchArray($result)) {
list($id, $parentId, $name) = $row;
if ($parentId == 0) {
$categories[$id] = array('name' => $name, 'children' => array());
} else {
$categories[$parentId]['children'][] = array('id' => $id, 'name' => $name);
}
}
// build combo box options
$list = '';
foreach ($categories as $key => $value) {
$name = $value['name'];
$children = $value['children'];
$list .= "<optgroup label=\"$name\">";
foreach ($children as $child) {
$list .= "<option value=\"{$child['id']}\"";
if ($child['id'] == $cat_id) {
$list .= " selected";
}
$list .= ">{$child['name']}</option>";
}
$list .= "</optgroup>";
}
?>
and then
<select name="cboCategory" id="cboCategory" class="box">
<option value="" selected>-- Choose Category --</option>
<?php
echo $list;
?>
</select>
The functions are:
dbQuery() = global $dbConn;
$result = mysqli_query($dbConn, $sql) or die(mysqli_error($dbConn));
return $result;
dbFetchArray = function dbFetchArray($result, $resultType = MYSQL_NUM) {
return mysqli_fetch_array($result, $resultType);
}
I have this kind of array shown in Picture. How can i insert the values in the select option as
<option value="7">7</option>
<option value="13000">13000</option>
<option value="19AAAAA">19AAAAA</option>
<option value="sdsdas">sdsdas</option>
<option value="dasdasdasd">dasdasdasd</option>
Simply flatten the multi-dimensional array, and then loop through it.
Suppose $arr in your original multi-dimensional array
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));
foreach($it as $value){
?>
<option value="<?php echo $value; ?>"><?php echo $value; ?></option>
<?php
}
Here are the relevant references:
http://php.net/manual/en/class.recursiveiteratoriterator.php
http://php.net/manual/en/class.recursivearrayiterator.php
<?php
foreach($arr as $val){
foreach($val as $val2){
foreach($val2 as $val3){ ?>
<option value="<?php echo $val3;?>"><?php echo $val3 ;?></option><?php
}
}
}
?>
You need to flat array. You can do it with recursive function. Here you have general function for that.
/**
* Get multilevel array convert to single-level array
* #param $array
* #return array
*/
function getFlattened($array) {
$flattened = [];
foreach ($array as $flat) {
if (is_array($flat)) {
$flatArray = array_merge($flatArray, getFlattened($flat));
} else {
$flattened[] = $flat;
}
}
return $flattened;
}
Of course you can use that approach to recursively display select - not only to flat array.
<?php foreach($array as $inner): ?>
<?php foreach($inner as $innerTwo): ?>
<?php foreach($innerTwo as $item): ?>
<option value="<?= $item ?>"><?= $item ?></option>
<?php endforeach; ?>
<?php endforeach; ?>
<?php endforeach; ?>
you may try this.
<?php
$input = Array(
Array
(
0 => 7,
1 => 13000
),
Array
(
0 => '19AAAAA',
1 => 'sdsdas'
)
);
$options = "";
$result = call_user_func_array("array_merge", $input);
for($i = 0;$i< count($result);$i++ ){
$options .="<option value='".$result[$i]."'>".$result[$i]."</option>";
}
echo $options;
I have a SQL table for a menu system. It has "id" as an index, a "display" field and a "parent" field. These are the data:
id, display, parent
1, File, 0
2, View, 0
3, Window, 0
4, Open, 1
5, Save, 1
6, Export, 1
7, Export to Image, 6
8, Export to PDF, 6
9, JPEG, 7
10, PNG, 7
I wanted to have a function to return the menu hierarchy in an HTML select format. The desired output would look like this:
<option value='1'>File</option>
<option value='4'>-- Open</option>
<option value='5'>-- Save</option>
<option value='6'>-- Export</option>
<option value='7'>---- Export to Image</option>
<option value='9'>------ JPEG</option>
<option value='10'>------ PNG</option>
<option value='8'>---- Export to PDF</option>
<option value='2'>View</option>
<option value='3'>Window</option>
This is the function I came up with:
function SelectPage($pdo, $default = "", $depth = 0, $id = 0, $opts = "") {
$sql = $pdo->prepare("SELECT id,display FROM pages WHERE parent = ?");
$sql->execute(array($id));
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
$opts .= "<option value='{$row["id"]}'>";
$opts .= trim(str_repeat("--", $depth) . " ");
$opts .= "{$row["display"]}</option>";
$tmp = SelectPage($pdo, $default, ($depth + 1), $row["id"], $opts);
$opts = $tmp;
}
return $opts;
}
It works, but I have doubts as to how efficient that is. I was wondering if there was a way to make a SQL query that returns them already in the correct order so that I could avoid doing looping calls to itself?
Dont use recursive with your sql statement. In one query take all categories to array like this:
$categories = array(
array(
'id' => 1,
'name' => 'File',
'parent' => 0
),
... etc.
);
next use this simple function. You can modify if You want.
function isSubCategory( $id, $cats )
{
foreach( $cats as $cat )
{
if( $id != $cat['id'] && $id == $cat['parent'] )
return true;
}
return false;
}
echo '<select>';
function getRecursiveTree( $parent, $cats, $level = -1 )
{
$separator = '-';
foreach( $cats as $i => $cat )
{
if( $cat['parent'] == $parent )
{
$level++;
if( isSubCategory( $cat['id'], $cats ) )
{
echo '<option value="',$cat['id'],'">', str_repeat( $separator, $level ) , $cat['name'],'</option>' . PHP_EOL;
getRecursiveTree( $cat['id'], $cats, $level );
}
else
{
echo '<option value="',$cat['id'],'">', str_repeat( $separator, $level ) , $cat['name'],'</option>' . PHP_EOL;
}
$level--;
}
}
}
echo ( getRecursiveTree( 0, $k ) );
echo '</select>';
code snippet from html_form_class
<?php
$frmStr = $frm->addSelectList(
'city',
$city,
true,
'',
'--- Select City ---',
array(
'class' => 'dropdown-style5',
'id' => 'city'));
echo $frmStr; ?>
code snippet from seachcar.php
$city = $db->select('City','City_Name');
foreach($city as $row)
{
$row;
}
"Array" is displaying in dropdown instead of values fetched from database
Please Advice!
function addSelectList($name, $option_list, $bVal = true, $selected_value = NULL,
$header = NULL, $attr_ar = array() ) {
$str = "<select name=\"$name\"";
if ($attr_ar) {
$str .= $this->addAttributes( $attr_ar );
}
$str .= ">\n";
if ( isset($header) ) {
$str .= " <option value=\"\">$header</option>\n";
}
foreach ( $option_list as $val => $text ) {
$str .= $bVal? " <option value=\"$val\"": " <option";
if ( isset($selected_value) && ( $selected_value === $val || $selected_value === $text) ) {
$str .= $this->xhtml? ' selected="selected"': ' selected';
}
$str .= ">$text</option>\n";
}
$str .= "</select>";
return $str;
}
html output of addSelectList function is
<select name="city" class="dropdown-style5" id="city">
<option value="">--- Select City ---</option>
<option value="0">Array</option>
<option value="1">Array</option>
<option value="2">Array</option>
<option value="3">Array</option>
You need to rebuild the array of cities:
$city = $db->select('City','City_Name');
$city_rebuild = array();
foreach($city as $row) {
$city_rebuild[] = $row['City_Name'];
}
$city = $city_rebuild;
You do echo of array. Something is wrong in your abstraction objects. You must iterate on array to show up its values.
function addSelectList creates a "dropdown" (actually a select element)
You need to remove the html from the function output.
Edit 1
I was confused as to what you were going for. In your foreach($option_list... you need to know what keys are available in the $option_list array and what you want to appear in the select dropdown.