Yii2: Kartik DepDrop widget without child value show up - php

I'm new in Yii2. I am using the DepDrop widget provide by Kartik. Now, I can pick data from column1, however, the related data in column2 doesn't show up. I can't even click on it.
Here is partial of the content of mysql table.
ID | name | sub_ID | category
1 | up | 11 | T-shirt
1 | up | 12 | jet
2 | shoe | 21 | nike
2 | shoe | 22 | adidda
Here is my _form.php code
<?= $form->field($model, 'category')->dropDownlist(
ArrayHelper::map(itemcategory::find()->all(), 'ID', 'name'), ['id' => 'cat_id', 'prompt' => 'Select…']
);?>
<?= $form->field($model, 'subcategory')->widget(
DepDrop::classname(), [
'options' => ['id' => 'subcategory', 'placeholder' => 'Select…'],
'pluginOptions' => [
'depends' => ['cat_id'],
'url'=>\yii\helpers\Url::to(['/positemcategory/Subcat'])
]
]
)?>
Here is my model ItemCategory.php code
public function getSubCatList($cat_id)
{
$data = self::find()->where(['ID' => $cat_id])->select(['sub_ID AS id', 'subcategory AS name'])->asArray()->all();
return $data;
}
And here is the controller Itemcategory.php code
public function actionSubcat()
{
$out = [];
if (isset($_POST['depdrop_parents'])) {
$parents = $_POST['depdrop_parents'];
if ($parents != null) {
$cat_id = $parents[0];
// $out = \app\models\ItemCategory::getSubCategoryList($cat_id);
$out = self::getSubCatList($cat_id);
echo Json::encode(['output'=>$out, 'selected'=>'']);
return;
}
}
echo Json::encode(['output'=>'', 'selected'=>'']);
}
I want to let user pick the item by its name, and save only the ID in another table in mysql instead of the full name.

Use ArrayHelper of Yii2.
$out = self::getSubCatList($cat_id);
echo Json::encode(['output'=>ArrayHelper::map($out,'id','name'),'selected'=>'']);
As a result you will get array with id as key and name as value.

Related

PHP Navigation with MySQL database

i made a navigation where a MySQL Database is needed.
This is my connection to the database to get all informations.
$stmt = $pdo->prepare("SELECT * FROM navigation");
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_OBJ);
if($stmt->rowCount() > 0){
$primary_nav = [];
foreach ($results as $result){
if($result->sub == 0){
$primary_nav[] = array(
'name' => $result->name,
'url' => $result->url,
'icon' => $result->icon,
);
}elseif($result->sub == 1){
$primary_nav[] = array(
'name' => $result->name,
'icon' => $result->icon,
'sub' => array(
array(
'name' => $result->name_sub,
'url' => $result->url_sub
)
)
);
}
}
}
This works fine, if I add the navigation into the database everything looks perfect and works amazing.
Now the problem i've now is when I want to a new sub menu than everytime I get a new top menu entrie with just 1 sub menu.
So my question is, how do I get this part working without breaking the code.
Normally the code looks like this:
// first sub
array(
'name' => 'Test1',
'icon' => 'fa fa-bullhorn',
'sub' => array(
array(
'name' => 'First Sub 1',
'url' => 'sub1.php'
),
array(
'name' => 'First Sub 2',
'url' => 'sub2.php'
)
)
),
// second sub
array(
'name' => 'Test3',
'icon' => 'fa fa-bullhorn',
'sub' => array(
array(
'name' => 'Second Sub',
'url' => 'sub1_1.php'
)
)
)
database structure:
|-----name-----|----url----|----icon----|----sub----|----name_sub----|----url_sub----|----category----|
| Dashboard | index.php | icon | 0 | | | |
------------------------------------------------------------------------------------------------------
| Test | test.php | icon | 0 | | | |
------------------------------------------------------------------------------------------------------
| Test1 | | icon | 1 | First Sub 1 | sub1.php | 1 |
------------------------------------------------------------------------------------------------------
| | | icon | 1 | First Sub 2 | sub2.php | 1 |
------------------------------------------------------------------------------------------------------
| Test3 | | icon | 1 | Second Sub | sub1_1.php | 2 |
------------------------------------------------------------------------------------------------------**
So if the category equals the same number as the other it should be doing this:
Test1
-- First Sub 1
-- First Sub 2
Test3
-- Second Sub
but with my code it looks like this:
Test1
-- First Sub 1
Test2 (it would be empty because in the database it is empty just for example I puted Test2)
-- First Sub 2
Test3
-- Second Sub
maybe someone understand what I need, because my english is not the best to explain it. Thanks for any help/solution for this problem.
$stmt = $pdo->prepare("SELECT * FROM navigation");
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_OBJ);
if($stmt->rowCount() > 0){
$categories = [];
$primary_nav = [];
foreach ($results as $result){
if ($result->name) {
if ($result->category) {
$categories[$result->category] = sizeof($primary_nav);
}
$primary_nav[] = array(
'name' => $result->name,
'url' => $result->url,
'icon' => $result->icon,
);
}
if ($result->name_sub) {
$primary_nav[$categories[$result->category]]['sub'][] = array(
'name' => $result->name_sub,
'url' => $result->url_sub
);
}
}
}
I've added an extra $categories array.
For each "parent" entry with a category, the $categories array stores the category value from the database and the key of the "parent" entry in the $primary_nav array.
The $categories array can then be used to add subsequent subcategories to the correct parent entry using their category value.
In your current setup however, the database allows you to have subcategories without a parent category and (sub)categories without a name.
So I would suggest using a table setup like this instead:
id name url icon parent
1 Dashboard index.php icon null
2 Test test.php icon null
3 Test1 null icon null
4 First sub 1 sub1.php null 3
5 First sub 2 sub2.php null 3
6 Test3 null icon null
7 Second sub Sub1_1.php null 6
Parent categories have the column "parent" set to null, and subcategories have their "parent" column set to the id of their parent entry.
This also allows you to have sub-sub-(and so on)-categories.
You would need to query it recursively:
function buildNav($pdo, $id = null) {
$array = [];
if ($id) {
$stmt = $pdo->prepare("SELECT * FROM navigation WHERE parent = :id");
$stmt->bindValue('id', $id);
} else {
$stmt = $pdo->prepare("SELECT * FROM navigation WHERE parent IS NULL");
}
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_OBJ);
if ($stmt->rowCount() > 0){
foreach ($results as $result){
$array[] = array(
'name' => $result->name,
'url' => $result->url,
'icon' => $result->icon,
'sub' => buildNav($pdo, $result->id)
);
}
}
return $array;
}
$primary_nav = buildNav($pdo);

Codeigniter 4 query builder join display only 1 time from first table

I have done up a query builder using join. I would like to show table 2, 3, 4, 5, 6 and so on based on the user id on table 1. I tried to query the result, it is showing like this :
My Tables
Table users
user_id | username | email
1 | userA | userA#email.com
2 | userB | userB#gmail.com
Table add_game
game_id | user_id | ign | acc_id
1 | 1 | ignA | accA
2 | 1 | ignB | accB
1 | 2 | ignB | accB
3 | 2 | ignD | accD
I will be using foreach loop and I believe it will display out multiple times based on the records in the database. What should I do if I only want to display the information highlighted in the red box (which is from users table) just 1 time and all the records associated with user id in add_game table?
This is my current code :
Controller
public function login()
{
$data = [];
helper(['form']);
$validation = \Config\Services::validation();
$db = db_connect();
$model = new LoginModel($db);
$user = $model->login($this->request->getVar('userlogin'));
$this->setUserSession($user[0]);
echo view('templates/header', $data, $user);
echo view('account/login', $data, $user);
echo view('templates/footer', $data, $user);
}
private function setUserSession($user){
$data = [
'user_id' => $user['user_id'],
'username' => $user['username'],
'email' => $user['email'],
'firstname' => $user['firstname'],
'lastname' => $user['lastname'],
'dob' => $user['dob'],
'country' => $user['country'],
'country_code' => $user['c_code'],
'contact' => $user['contact'],
'game_id' => $user['game_id'],
'ign' => $user['ign'],
'acc_id' => $user['acc_id'],
'isLoggedIn' => true
];
session()->set($data);
return true;
}
Model:
return $this->db->table('users')
->groupStart()
->where('username', $str)
->orWhere('email', $str)
->groupEnd()
->join('add_game', 'add_game.user_id = users.user_id')
->get()
->getResultArray();
I have a few more tables but not yet created for now so I have only joined 1 table for the time being. What am I missing? Or do I have to loop twice? Is there a way that I just need to loop 1 time? Hope someone can help me out here. Thanks in advance guys!
the easiest way to achieve this (display 2 records from add_game table and 1 record from users table) you need to create a foreach loop in your view, and exclude duplicated data from users table to be shown.
controller:
$data['my_data']=$this->Your_model->your_method(); // your query example
$this->load->view('your_view',$data)
view:
<?php $my_id=0;foreach($my_data as $row):?>
<?php if($my_id!=$row->user_id):?>
<div><?=$row->username?></div> <!--data from table user-->
<div><?=$row->created_at?></div> <!--data from table add_game-->
<?php else:?>
<div><?=$row->created_at?></div> <!--only data from table add_game-->
<?php endif;?>
<?php $my_id=$row->user_id;endforeach;?>

Filter table with a column in Laravel Backpack

I have a Employee table which display like this:
+-------------------------------+
| id | name | code |
---------------------------------
| 1 | Employee 1 | A1 |
| 2 | Employee 2 | A2 |
| ... | ... | ... |
+-------------------------------+
And I want to create a filter by code column in this table. My query will be like this:
SELECT name FROM employee WHERE code LIKE .% $filter %.
I searched in backpack document and trying to do like this
$this->crud->addFilter(
[
'type' => 'select2',
'name' => 'code',
'label' => 'Filter',
],
function () {
return Employee::select('code')->distinct()->get()->toArray();
},
function ($value) {
$this->crud->addClause('where', 'code', $value);
}
);
But it got error: htmlspecialchars() expects parameter 1 to be string, array given. How I can fix this?
Thank you very much!
Your code to generate the list of employee codes is returning an array like this at the moment, while the package is expecting an array of strings.
[
['code' => 'A1'],
['code' => 'A2'],
];
To fix the issue, you need to pluck the code column from the array, and key it by the code:
$this->crud->addFilter([
'type' => 'select2',
'name' => 'code',
'label' => 'Filter',
],
function() {
return Employee::select('code')->distinct()->get()->pluck('code', 'code')->toArray();
},
function($value) {
$this->crud->addClause('where', 'code', $value);
});
This will result in something like:
[
'A1' => 'A1',
'A2' => 'A2',
];

codeigniter : How to store product selection in the database

In my shopping cart. There are products that have 2 types of options that have been selected. Namely color and size. How to save to database?
my controller :
foreach ($this->cart->contents() as $item)
{
if(empty($items['before']))
{
$harga_fix_diskon_atau_non_diskon = $this->cart->format_number($item['price']);
}
else
{
$harga_fix_diskon_atau_non_diskon = $this->cart->format_number($item['before']);
}
foreach ($this->cart->product_options($item['rowid']) as $option_name => $option_value)
{
if(empty($option_value))
{
$option_value = "";
}
else
{
$option_value;
}
$option = $option_value;
}
$data_order[] = array(
'invoice' => $invoice,
'name_product' => $item['name'],
'size' => $item['option'],
'color' => $item['option'],
'qty' => $item['qty'],
'price' => $harga_fix_diskon_atau_non_diskon,
'weight' => $item['berat'],
);
}
$this->db->insert_batch('order_product', $data_order);
I have saved all the data except in the product selection section
The result of my database process is a matter of size and color :
----------------------------------------------------------------
| invoice | name_product | size | color | qty | price | weight |
----------------------------------------------------------------
| ST5623 | Nike | 42 | 42 | 2 | 28 | 0,5 |
*Should be in color columns containing colors.
If i use print_r (); And managed to show me what I wanted. Namely the color is color and size is size
foreach ($this->cart->product_options($item['rowid']) as $option_name => $option_value)
{
if(empty($option_value))
{
$option_value = "";
}
else
{
$option_value;
}
$option = $option_value;
print_r($option);
}
please for help. thank you.
because your setting same value for color and size
'size' => $item['option'], 'color' => $item['option']
Or you need to check $item for color parameter

Doesn't choose records

author id | name
1 Mike
2 Dive
3 Stiv
book id | title
1 ABC
2 War
book_author id_book | id_author
1 1
1 2
2 3
app/models/Book.php
public function getAuthors()
{
return $this->hasMany(Authors::className(), ['id' => 'id_author'])->viaTable('book_author',['id_book' => 'id']);
}
In view:
foreach (Books::findAll([1, 2]) as $book)
{
echo sprintf('%s | %s',
$book->title,implode(', ',
$book->getAuthors()));
}
Always returned implode(): Invalid arguments passed in $book->getAuthors()));
getAuthors() - doesn't choose author, why?
Need:
ABC | Mike, Dive
War | Stiv
$book->getAuthors() get object arrays. You should get simple array. Try this code:
foreach (Books::findAll([1, 2]) as $book)
{
$authors = ArrayHelper::toArray($book->getAuthors()->all(), [
'app\models\Authors' => [
'name', 'id'
]
]);
echo sprintf('%s | %s',
$book->title,implode(', ',
ArrayHelper::map($authors, 'id', 'name')));
}

Categories