How to Display a selected grade with its subject? - laravel

I want to when a user select a dropdown from the list, a group of subjects available for that grade must be displayed with checkboxes next to them
My controller
public function create()
{
$grades = Grade::with('subjects')->orderBy('slug', 'asc')->get();
return view('admin.users.create', compact( 'grades'));
}
Blade file
<div class="form-group">
<select id="grade" name="grade" class="form-control #error('grade') is-invalid #enderror" v-model="selectedSubjects">
<option value="">Choose a Grade...</option>
#foreach($grades as $grade)
<option value="{{ $grade->id }}" {{ old('grade', $grade) == $grade->name ? 'selected' : "" }}>{{ $grade->name }}</option>
#endforeach
</select>
</div>
<div class="custom-control custom-checkbox mt-2">
#foreach($grade->subjects as $subject)
<input type="checkbox" class="custom-control-input" id="{{$subject->slug}}" name="subjects[]" :value="selectedSubjects" />
<label class="custom-control-label" for="{{$subject->slug}}">{{$subject->name}}</label>
#endforeach
</div>
vue
<script>
window.addEventListener('load',function(){
var app = new Vue({
el: '#app',
data:{
selectedSubjects: {!! $grade->subjects->pluck('name') !!},
}
});
});
</script>
THIS IS IMPOSSIBLE... I GIVE UP

As per I have understood, you want to select grades from dropdown & show its corresponding checkbox as per subjects for the grades.
I would suggest to create a vue component for that lets say grades-component,
in your blade you can add,
<form action="" class="form-control">
#csrf
<grade-component :grades='#json($grades)'></grade-component>
</form>
here in blade, $grades is the object(or array) you are passing via compact. Basically it is to pass your data to the component, we will use that with help of props.
Now you can add your GradeComponent.vue in resources->js->components->GradeComponent.vue
GradeComponent.vue
<template>
<div class="container">
<select v-model="selected_grade" #change="onChange($event)">
<option v-for="grade in grading" :value="grade.slug">{{grade.name}}</option>
</select>
<div class="custom-control custom-checkbox mt-2" v-if="subjects !== null" v-for="subject in subjects">
<input type="checkbox" :id="subject.slug" :value="subject.slug"/>
<label :for="subject.slug">{{subject.name}}</label>
</div>
</div>
</template>
<script>
export default{
props: ['grades'],
data: function() {
return {
grading: this.grades,
selected_grade: null,
subjects : null
}
},
methods: {
onChange(event) {
this.grading.forEach((obj, index) => {
if (obj.slug === event.target.value){
this.subjects = obj.subjects;
}
})
}
}
}
</script>
Now finally you can add it in app.js
Vue.component('grade-component', require('./components/GradeComponent.vue').default);
Then compile your vuejs code, I would use npm run watch
A similar one but with fake data, you can see https://jsfiddle.net/bhucho/2yu4nmws/3/,

Related

Select2 not showing dropdown list after changing page - livewire

Hi i have a problem about select2 and livewire, after go to another page and back to dashboard the dropdown list of select2 dissapeared, i checked the source the list still on there and not loaded
<script>
$(document).ready(function() {
$('.live-search').select2({
placeholder: 'Search Services',
// allowClear: true,
});
$('.live-search').on('change', function(e) {
Livewire.emit('servicesId', e.target.value);
});
});
</script>
<div class="form-group" wire:ignore>
<label>Services :</label>
<select class="form-control live-search" wire:model='servicesId'>
#foreach ($data as $service)
<option value="{{ $service->id }}">{{ Str::ucfirst($service->service_name) }} -
Rp.{{ $service->price }}
</option>
#endforeach
</select>
<hr />
</div>

select options based on another select VueJS Laravel

I am using VueJs with laravel, I am new in VueJs and i want to display the Categories dynamically whenever i choose any Collection, i am sending API and using Axios, but i cant seem to figure out how to make this work.
Any help will be highly appreciated
<div class="form-group">
<label for="">Collection</label>
<select
class="form-control"
v-model="collection"
#change="getCategory()"
>
<option
v-for="datas in data"
:key="datas.collection_name"
:value="datas.collection_id"
>
{{ datas.collection_name }}
</option>
</select>
</div>
<div class="form-group">
<label for="">Category</label>
<select class="form-control" v-model="category">
<option :value="category">
{{ category_name }}
</option>
</select>
</div>
data() {
return {
category_name: "",
collection: null,
category: null,
};
},
methods: {
getCategory() {
console.log(this.collection);
axios
.get("/api/products")
.then((response) => {
console.log(response.data[0].category_id);
this.category = response.data[0].category_id;
this.category_name = response.data[0].category_id;
})
.catch((err) => {
console.log(err);
});
},
Controller:
public function create(){
$collection = Collection::join('categories','collections.id','=','categories.collection_id')
->select('categories.name as category_name','categories.id as category_id','collections.name as collection_name','collections.id as collection_id')
->get();
return response()->json($collection);
}
Axios response.data output is :
if I got your question very well. You want to dynamically display your categories after choosing collection data that are in laravel backend API.
in your script in vue js
data(){
return {
form: {
collection:'',category: '' //define your v-models here
},
categories:{},
errors: [],
}
},
method:{
getCategories(){
axios.get('/categories/' + this.form.collection).then(response => {
this.categories = response.data
}).catch(errors => {
this.errors = error.response.data.errors
})
},
},
in your template now (html)
<div class="col-lg-6">
<div class="mb-3">
<label class="form-label">collection</label>
<select v-model="form.collection" class="form-control" #change="getCategories()">
<option value="">Select Collection</option>
<option :value="collection.id" v-for="collection in collections" :key="country.id">{{ country.name }}</option>
</select>
<div v-if="errors.collection" class="text-small text-danger"> {{ errors.collection[0] }}</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Category</label>
<div class="form-icon position-relative">
<select class="form-control" v-model="form.category">
<option value="">Select Category</option>
<option :value="category.id" v-for=" categories" :key="city.id">{{ category.name }}</option>
</select>
<div v-if="errors.category" class="text-small text-danger">{{ errors.city_id[0] }}</div>
</div>
</div>
</div>
you better define your v-models with form as I did above it will help you not confusing yourself. example form.collection
This should work.
<template>
<div>
<div class="form-group">
<label for="">Collection</label>
<select
class="form-control"
v-model="collection"
#change="getCategory()"
>
<option
v-for="datas in data"
:key="datas.collection_name"
:value="datas.collection_id"
>
{{ datas.collection_name }}
</option>
</select>
</div>
<div class="form-group">
<label for="">Category</label>
<select class="form-control" v-model="category" v-if="category_list.length > 0">
<option v-for="(category, index) in category_list" :key="index" :value="category.id">
{{ category.category_name }}
</option>
</select>
</div>
</div>
</template>
<script>
export default{
data() {
return {
category: null,
category_list: null
};
},
methods: {
getCategory() {
axios
.get("/api/products")
.then((response) => {
this.category_list = response.data;
})
.catch((err) => {
console.log(err);
});
},
}
</script>

How to use select2 multiselect with livewire

What I am trying to achieve is, there are two models A and B with a relationship of One to many, where A has many B. So if the records for A and B have already been created, A can be assigned to many B. So I started this current project with livewire, and now I am at a loss. Normal select with multiple works just fine and populates the array in the backend of livewire. But when I use select2 nothing is stored in the array, and when I dd it, it shows an empty array.
Even though livewire provides wonderful set of tools, I am starting to realize that there is a lot of gray areas where things are missing or lacks external support, like select2 here.
Here is what I have done so far:
<div>
<div class="tab-pane fade show active" id="card1" role="tabpanel" aria-labelledby="card1-tab">
<div class="pt-3"></div>
<div class="row" >
<div class="form-group col">
<label for="cards">Enter Cards</label>
<select class="form-control select2" id="cards" multiple="multiple" onchange="this.dispatchEvent(new InputEvent('input'))>
<option disabled="">Select Cards</option>
#foreach($cardsUnassigned as $card)
<option value="{{ $card->id }}">{{ $card->imei_number }}</option>
#endforeach
</select>
</div>
<div class="form-group col">
<label for="technicians" class="">Technicians</label>
<select class="form-control select2" id="technicians" wire:model='techies.'>
<option disabled="">Select Technicians</option>
#foreach($technicians as $tech)
<option value="{{ $tech->id }}">{{ $tech->first_name }}</option>
#endforeach
</select>
</div>
</div>
#foreach($cardSelect as $key => $value)
{{$value}}
#endforeach
<button wire:click="assignCardToTech()" class="btn btn-primary">Submit</button>
</div>
</div>
#push('scripts')
<script>
$('#cards').select2({
placeholder: 'Select Cards to assign'
});
//send data to livewire
$('#technicians').select2({
placeholder: 'Select Technicians'
});
</script>
#endpush
And the backend:
<?php
namespace App\Http\Livewire\Stock\Assigns;
use App\Models\Card;
use App\Models\Sim;
use App\Models\Technician;
use Livewire\Component;
use Livewire\WithPagination;
use Illuminate\Support\Facades\Auth;
class Assigns extends Component
{
public $sortBy_card = 'imei_number';
public $sortBy_sim = 'ip';
public $sortDirection = 'asc';
public $search = '';
public $perPage = 10;
public $cardSelect = [];
public $techies;
public function render()
{
$simsUnassigned = Sim::query()
->whereNull('technician_id')
->searchUnassigned($this->search)
->get();
$cardsUnassigned = Card::query()
->whereNull('technician_id')
->searchUnassignedCard($this->search)
->get();
// dd($cardsUnassigned);
$simsAssigned = Sim::query()
->searchAssigned($this->search)
->orderBy($this->sortBy_sim, $this->sortDirection)
->paginate($this->perPage);
$cardsAssigned = Card::query()
->searchAssignedCard($this->search)
->orderBy($this->sortBy_card, $this->sortDirection)
->paginate($this->perPage);
$technicians = Technician::query()->get();
return view('livewire.stock.assigns.assigns',compact('simsUnassigned','cardsUnassigned','simsAssigned','cardsAssigned','technicians'))
->extends('layouts.base')
->section('content');
}
public function assignCardToTech(){
dd($this->cardSelect);
if($this->cards){
foreach($this->cards as $card){
}
}
}
}
Hopefully this helps.
######## INSIDE LIVEWIRE COMPONENT
public array $locationUsers = [];
protected $listeners = ['locationUsersSelected'];
public function locationUsersSelected($locationUsersValues)
{
$this->locationUsers = $locationUsersValues;
}
######## INSIDE LIVEWIRE BLADE
<div class="col-md-12 mb-3" wire:ignore>
<label for="locationUsers">Select Users</label>
<select id="locationUsers" class="form-control select2" multiple="multiple">
<option value="">--select--</option>
#foreach($this->users as $id => $name)
<option value="{{ $id }}">{{ $name }}</option>
#endforeach
</select>
</div>
######## INSIDE LIVEWIRE SCRIPTS
document.addEventListener('livewire:load', function () {
$('#locationUsers').on('select2:close', (e) => {
#this.emit('locationUsersSelected', $('#locationUsers').select2('val'));
});
$('#locationUsers').val(#this.get('locationUsers')).trigger('change');
});
Your could try adding this to your html
<div class="form-group col-md-6" wire:ignore>
<label for="manager" class="mb-0 h5">Assign Managers:</label>
<select wire:model="reporting_managers" id="manager" class="select-2 multiple='multiple' data-placeholder="Assign Managers">
#foreach ($managers as $manager)
<option value="{{ $manager->id }}" data-name="{{ $manager->name }}">{{ $manager->name }}</option>
#endforeach
</select>
</div>
and then in your javaScript section
$('#manager').on('select2:select', function (e) {
#this.set('reporting_managers', $('#manager').select2('val'));
});
$('#manager').on('select2:unselect', function (e) {
#this.set('reporting_managers', $('#manager').select2('val'));
});
This will directly store your selection in variable in livewire and won't get deselected on render.

select2 on Laravel Livewire does not work

I implemente select2 in a select as the official documentation indicates and I can't get it to work in full.
<div>
<div wire:ignore>
<select class="js-example-basic-single" name="state">
<option value="AL">Alabama</option>
<option value="WY">Wyoming</option>
</select>
<!-- Select2 will insert it's DOM here. -->
</div>
#push('scripts')
<script>
$(document).ready(function() {
$('.js-example-basic-single').select2();
$('.js-example-basic-single').on('change', function (e) {
#this.set('foo', e.target.value);
});
});
</script>
#endpush
if I remove the following script in the view the select2 component renders fine
$('.js-example-basic-single').on('change', function (e) {
#this.set('foo', e.target.value);
});
but of course I lose the desired functionality.
The selct2 add links I use are as follows
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="{{asset('SitioWeb/assets/select2/js/select2.min.js')}}"></script>
what am i missing?
Due to the way select2 works, livewire's wire:model and wire:change may not work with select2. Livewire's wire:model and wire:change work perfectly with the traditional HTML select control. To use select to with livewire's wire:model and wire:change, write a js code to get the selected value from select2, then use Livewire.emit() to send the selected value to your component and handle it from there. Example js code is as follows:
$(document).ready(function() {
$('#id').select2();
$('#id').on('change', function(e) {
Livewire.emit('listenerReferenceHere',
$('#id').select2("val"));
});
});
Your Livewire component :
...
protected $listeners = ['listenerReferenceHere'];
public function listenerReferenceHere($selectedValue)
{
//Do something with the selected2's selected value here
}
I hope this helps... 😊
you can use Bootstrap-select
npm install bootstrap-select
It worked well for me. this my code.
<div class="form-group">
<label for="permissions">{{ __('role.permissions') }}</label>
<div class="col-sm-10">
<div wire:key="UNIQUE_KEY">
<div wire:ignore>
<select id="permissions" wire:model="permissions"
data-live-search="true"
data-actions-box="true"
title="{{__('generic.select')}} {{ __('role.permissions') }}"
name="permissions[]" data-width="100%"
class="selectpicker permissions" multiple>
#foreach($list_permission as $permission)
<option value="{{ $permission->id }}"
data-subtext="{{ $permission->key }} {{ ' -'. $permission->table_name }}">
{{ __('permission.'.$permission->key) }}
</option>
#endforeach
</select>
</div>
</div>
#error('permissions') <span class="text-danger">{{ $message }}</span> #enderror
</div>
</div>
in script :
....
#push('scripts')
<script>
Livewire.restart();
$(function () {
$('.permissions').selectpicker();
});
</script>
#endpush
</div>
in Component
public $permissions = [];
public $old_permissions = [];
public function updatedPermissions()
{
$filter_arrays = array_filter($this->permissions);
$unique = array_unique($filter_arrays);
$this->permissions = $unique;
}
in update :
if (! empty($this->old_permissions)){
$updateRole = $this->role->find($this->modelId)->permissions()->detach();
$updateRole = $this->role->find($this->modelId)->permissions()->sync($validatedData['permissions']);
}elseif ($this->old_permissions != $this->permissions ){
$updateRole = $this->role->find($this->modelId)->permissions()->attach($validatedData['permissions']);
}
I tried hard to combine livewire with select2 and finally found the solution that way.
UsersComponent.php
class Users extends Component
{
public $users = [];
public function mount()
{
$this->users= User::all();
}
public function render()
{
return view('livewire.users');
}
}
then
users.blade.php
<div class="col-sm-12 col-xl-3 m-b-30" wire:ignore >
<div >
<h4 class="sub-title" >USERS</h4>
<select class="js-example-basic-single form-control-warning" name="states" >
#foreach ($users as $user)
<option value="{{ $user->id }}">{{ $user->name}}</option>
#endforeach
</select>
</div>
</div>
index.blade.php
<p>
#livewire(livewire.users)
</p>

How to display data to textfield from combo selection in laravel

I'd like to display data to textfield based on combo/drop box selection in laravel 5.8. then save the data. is there complete tutorial how to do it from model, view and controller.
In Customer Controller
public function create()
{
$customer= Customer::all();
return view('Customer.create', compact('Customer'));
}
in view create.blade
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>CUSTOMER</strong>
<select type="text" class="form-control" name="kde_cust" id="cde_customer" required>
<option value=""> -- PICK CUST-- </option>
#foreach($cust as $cust)
<option value="{{ $cust->cde_cust }}" selected>{{ $cust->nme_customer }}</option>
#endforeach
</select>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>NAME</strong>
<input type="text" name="cust_name" id="cust_name" class="form-control" value="{{ $cust->nme_customer }}">
</div>
</div>
This should helps:
Create a route to get the user address:
Route::get('user-address/{user_id}','YourController#method')->name('user.address');
Your controller method should look like this:
public function yourFunction($cde_customer)
{
$customer = Customer::where('cde_customer', $cde_customer)->first();
$address = $customer->address;
return response()->json([
'address' => $address,
]);
}
Add this script to your blade:
$("#cde_customer").on('change', function(){
var user_id = $(this).val();
$.ajax({
url: '/user-address/' + user_id,
method: 'GET',
success: function(response){
$("#textfield").html(response.address);
}
});
});
Hope it helps.

Resources