How to show items in dropdown by cascading in laravel 5.6?

How to show items in dropdown by cascading in laravel 5.6?



I have 3 tables i.e. menu, submenu and page.



Menu Table


Schema::create('menu', function (Blueprint $table)
$table->increments('parent_id')->primary();
$table->string('name');
$table->timestamps();
);



Submenu Table


Schema::create('submenu', function (Blueprint $table)
$table->increments('submenu_id')->primary();
$table->integer('parent_id');
$table->foreign('parent_id')
->references('id')
->on('menu')
->onDelete('cascade');
$table->string('title');
$table->timestamps();
);



Page Table


Schema::create('page', function (Blueprint $table)
$table->increments('page_id');
$table->integer('menu_id');
$table->integer('submenu_id');
$table->text('description');
$table->integer('status')->default('1');
$table->softDeletes();
$table->timestamps();
);



addpage.blade.php


<div class="control-group">
<label class="control-label">Menu Name</label>
<div class="controls">
<?php $menu = DB::table('menu')->where('status',1)->get(); ?>
<select name="parent_id" id="parent_id">
<option selected disabled>Select Menu Name</option>
@foreach($menu as $data)
<?php if($data->deleted_at==null) ?>
<option value=" $data->parent_id "> strtoupper($data->name) </option>
<?php ?>
@endforeach
</select>
</div>
</div>
<div class="control-group">
<label class="control-label">Submenu Title</label>
<div class="controls">
<?php //$menu = DB::table('submenu')->where('deleted_at',null)->where('status',1)->get(); ?>
<select name="submenu_id" id="submenu_id">
<option selected disabled>Select Submenu Title</option>
<!-- @foreach($menu as $test)
<?php// $submenu = DB::table('submenu')->where('deleted_at',null)->where('status',1)->where('parent_id',$test->parent_id)->get(); ?>
<?php// print_r($submenu);die; ?>
@endforeach *-->
<?php $submenu = DB::table('submenu')->where('status',1)->get(); ?>
@foreach($submenu as $data)
<?php if($data->deleted_at==null) ?>
<option value=" $data->submenu_id "> $data->title </option>
<?php ?>
@endforeach
</select>
</div>
</div>



How cascade value in dropdown in laravel 5.6?
When i add new page, i want to show submenu according to menu in dropdown...
So, I want to have solution of this...






Any particular reason why you have primary key as parent_id under menu and then submenu_id under submenu? Also - really not a good idea to fetch records from within the view. I'll try to help, but you have to give me some time to re-create it locally - I will however use just id columns for primary - unless you confirm there was a particular reason for this naming.

– Sebastian Sulinski
Sep 16 '18 at 7:30


parent_id


menu


submenu_id


submenu


id






ok, you can take your time..

– Crazy Programmer
Sep 16 '18 at 7:39






Can I just check - is Page only going to display a single sub-menu or list of submenus associated with the given menu?

– Sebastian Sulinski
Sep 16 '18 at 7:46






a menu can have no any submenu or single submenu or multiple submenu ..a menu can display list of submenus

– Crazy Programmer
Sep 16 '18 at 7:50







Will Page record only be valid if it has both - menu and sub-menu?

– Sebastian Sulinski
Sep 16 '18 at 7:51





2 Answers
2



The best way is to use the eager loading. Create a relation with both the models and get the value by using this model query.


$menus= Menu::with('submenu')->get();

<select name="parent_id" id="parent_id">
<option selected disabled>Select Menu Name</option>
@foreach($menu as $key=>$value)
<option value=" $key "> strtoupper($value) </option>

@foreach($key->submenu as $subkey=>$subValue) { ?>
<option value=" $subkey->parent_id "> strtoupper($subValue->name) </option>
@endforeach
@endforeach
</select>






how can i show in addpage.blade.php

– Crazy Programmer
Sep 16 '18 at 10:26



Here's what I've come up with. I've amended migrations a bit:


Schema::create('menus', function (Blueprint $table)
$table->increments('id');
$table->tinyInteger('status')->default(1);
$table->string('name');
$table->timestamps();
);

Schema::create('sub_menus', function (Blueprint $table)
$table->increments('id');
$table->tinyInteger('status')->default(1);
$table->unsignedInteger('menu_id');
$table->string('title');
$table->timestamps();

$table->foreign('menu_id')
->references('id')
->on('menus')
->onDelete('cascade');
);

Schema::create('pages', function (Blueprint $table)
$table->increments('id');
$table->integer('menu_id');
$table->integer('submenu_id');
$table->integer('status')->default(1);
$table->text('description');
$table->softDeletes();
$table->timestamps();
);



Then from within controller


$menus = Menu::where('status', 1)->orderBy('name')->get()->map(function(Menu $menu)
return [
'name' => $menu->name,
'value' => $menu->id,
];
);

$subMenus = SubMenu::where('status', 1)->orderBy('title')->get()->map(function(SubMenu $subMenu)
return [
'name' => $subMenu->title,
'value' => $subMenu->id,
'menu_id' => $subMenu->menu_id,
];
)->groupBy('menu_id');

return view('menu.index')
->with('menus', $menus)
->with('subMenus', $subMenus);



You can see that I've grouped sub-menus using menu_id field, which will represent index of each collection of sub-menus - this way we can then easily replace them in the view.


menu_id



I've added 2 simple VueJs components


VueJs



Form.vue


<script>
export default
props:
inputs:
type: Object,
required: true,

,
data()
return
fields: this.inputs

,

</script>



DependableMenu.vue


<template>
<div>
<slot :options="options"></slot>
</div>
</template>
<script>
export default
props:
parentValue:
type: [Number, String],
default: null,
,
records:
type: [Object, Array],
default: () => ,

,
data()
return
options:

,
mounted()
this.filterRecords(this.parentValue);
,
methods:
filterRecords(parent_id)
if (!parent_id)
this.options = ;

this.options = this.records[parent_id]
,
watch:
parentValue(parent_id)
this.filterRecords(parent_id);



</script>



Registered them within the resources/assets/js/app.js


resources/assets/js/app.js


Vue.component('form-wrapper', require('./components/Form'));
Vue.component('dependable-menu', require('./components/DependableMenu'));



And finally menu/index.blade.php view with the form


menu/index.blade.php


<form-wrapper :inputs=" menu_id: '', submenu_id: '' " inline-template>
<form action="/" method="post">
csrf_field()
<select name="menu_id" v-model="fields.menu_id">
<option value="">Select menu</option>
@foreach($menus as $menu)
<option value=" $menu['value'] "> $menu['name'] </option>
@endforeach
</select>
<dependable-menu :parent-value="fields.menu_id" :records=" $subMenus ">
<div slot-scope="props">
<select name="submenu_id">
<option value="">Select sub-menu</option>
<option v-for="option in props.options" :key="option.value" :value="option.value" v-text="option.name"></option>
</select>
</div>
</dependable-menu>
<button type="submit">SUBMIT</button>
</form>
</form-wrapper>



Tested locally - all works, but give it a try your end and see how it goes.






Did you try it?

– Sebastian Sulinski
Sep 17 '18 at 9:37






i didn't understood the vue.js

– Crazy Programmer
Sep 17 '18 at 10:12






How are you planning on replacing records in the menu after first selection - page reload?

– Sebastian Sulinski
Sep 17 '18 at 11:08






can we use ajax?

– Crazy Programmer
Sep 18 '18 at 8:50






You can use ajax to fetch data for each menu after selection, but you need some sort of javascript to actually make that ajax call - whether it is using vanilla js or some library such as jQuery, Vue etc.

– Sebastian Sulinski
Sep 18 '18 at 10:06



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Popular posts from this blog

PHP code is not being executed, instead code shows on the page

Administrative divisions of China

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼