Select/Multiselect using choice.js in laravel livewire not working - laravel

I have using livewire and now I need to create select dropdown with a search option, and I came across choices.js choice.js link and follow this livewire with choice.js link I can make with work (but I have to use wire:ignore) for the select when the data is not dependent on others select (like fetch district after state is selected)
Now I need to fetch district after state is change, and of course i use wire:ignore because of styling and the district cannot display in the option list. If I didn't use wire:ignore then the style is breaking. For the very first time the district display based on state select without breaking any styles, after that district cannot updated even state is changed.
Below are my code for select state and district
<x-input.select wire:model="state" prettyname="state" :options="$allState" selected="('State')" placeholder="Select State*"/>
#if(!is_null($state))
<x-input.select wire:model="district" prettyname="district" :options="$allDistrict" selected="('District')" placeholder="Select District*"/>
#endif
and in Component
public function updatedState($state)
{
$this->allDistrict = District::where('state_id', $state)->pluck('id','name')->toArray();
}
The function updatedState() is trigger but the districts value cannot display in the blade file except the first time
the view component for <x-input.select /> is below
<div x-data wire:ignore x-init="() => {
var choices = new Choices($refs.{{ $attributes['prettyname'] }}, {
itemSelectText: '',
});
choices.passedElement.element.addEventListener(
'change',
function(event) {
values = event.detail.value;
#this.set('{{ $attributes['wire:model'] }}', values);
},
false,
);
let selected = parseInt(#this.get{!! $attributes['selected'] !!}).toString();
choices.setChoiceByValue(selected);
}"
>
<select id="{{ $attributes['prettyname'] }}" wire-model="{{ $attributes['wire:model'] }}" wire:change="{{ $attributes['wire:change'] }}" x-ref="{{ $attributes['prettyname'] }}">
<option value="">{{ isset($attributes['placeholder']) ? $attributes['placeholder'] : '-- Select --' }}</option>
#if(count($attributes['options'])>0)
#foreach($attributes['options'] as $key=>$option)
<option value="{{$key}}" >{{$option}}</option>
#endforeach
#endif
</select>
</div>
My question is how to get district value based on state data, and not breaking style and which can be searchable?
Thanks in advance

Related

Laravel Livewire and select2 dropdown inside of bootstrap modal

I have a select2 blade component that I'm using inside of a bootstrap modal. Everything is working as expected, except when the modal form is submitted, the styling of the select 2 is lost, and a new empty option (must be the placeholder) is shown as an option, but only in the selects where I'm doing a yes/no option where the value is either 1 or 0 (See code below).
The styling is messed up on all, but the extra placeholder option only shows up on some.
Here's the normal way it should look, and does look when you first open the modal after a page refresh:
After submitting the modal it looks like this (notice the extra placeholder option):
Here's the code for my select2 component:
#props(['id', 'usePlaceholder' => null])
<div wire:ignore style="width:100%;" id="select2-{{ $id }}">
<select {{ $attributes }} id="{{ $id }}" name="{{ $id }}[]" class="form-select select2" data-width="100%" data-select2-id="{{ $id }}">
#if ($usePlaceholder)
<option></option>
#endif
{{ $slot }}
</select>
</div>
{{-- blade-formatter-disable --}}
#push('custom-scripts')
<script>
$(document).ready(function() {
let select2 = $('#' + #js($id));
select2.select2({
dropdownParent: $('#select2-' + #js($id)),
placeholder: 'Select an option',
minimumResultsForSearch: 15
});
***The below listeners I can comment out, they have no effect as far as I can tell, just including them for reference***
window.addEventListener('hideModal', event => {
select2.val(null).trigger('change');
});
window.addEventListener('set'+#js(ucfirst($id)), event => {
select2.val(event.detail).trigger('change');
});
});
</script>
#endpush
{{-- blade-formatter-enable --}}
And here's where I'm actually using the component:
<div class="col-md-6">
<x-input.group label="Sales Tax" for="salesTax" :error="$errors->first('salesTax')">
<x-input.select2 usePlaceholder="{{ empty($salesTax) ? 'true' : '' }}" wire:model.defer="salesTax" id="salesTax">
<option name="no" id="sales-tax-0" value="0">No</option>
<option name="yes" id="sales-tax-1" value="1">Yes</option>
</x-input.select2>
</x-input.group>
</div>
I've tried destroying and re-initializing the select2 when the modal is dismissed, but that hasn't done anything for me.

Need to show the down arrow in dropdown list in ASP.NET Core MVC

Working on an ASP.NET Core 6 MVC app. I am created a dropdown using the select asp-for tag helper. But I am not seeing a dropdown down arrow. Also I want to set the top or particular value selected by default.
Below is code and image of a dropdown
<div class="col-sm-3">
<select name="products" class="form-control "
asp-items="#(new SelectList(ViewBag.ddaircraft,"id","name"))">
</select>
</div>
Action Method code for ViewBag:
Public IActionResult Index()
{
var countries= _countries.getCountries();
//add an country item on the top of list.
countries.Insert(0, new Aircraft { Registration="0"});
//i used the country.name for value and item
var ddforAircraft = from country in countries
select new { id = country.name, name=country.name=="0"?"Item List":country.name };
// ddforAircraft.Append(new { id = "0", name = "" });
ViewBag.ddaircraft = ddforAircraft;
return View()
}
I found the answer, after Tiny Wang pointed me to the direction which really helped me to search the answer.
In order to see the dropdown down arrow I added a css class "form-select" without removing anything and I started to see the down arrow
<div class="col-sm-3">
<select name="products" class="form-control form-select-sm form-select " asp-items="#(new SelectList(ViewBag.ddaircraft,"id","name"))">
</select>
</div>
Missing dropdown arrow resulted from the class form-control, I test in my side and I found the arrow can be seen by default until I add class="form-control " to my code:
removing this 2 options then the arrow appeared again, so it proved to relate to the class, you may need to update the style:
Then I use Jquery to change the default selected option when page is loading in my code, my selector has Id Country, then change the value(ListItem.Value):
<select asp-for="Country" asp-items="#(new SelectList(Model.Countries, nameof(ListItem.Value), nameof(ListItem.Text)))">
<option>Please select one</option>
</select>
#section Scripts{
<script>
$("#Country").val('Canada')
</script>
}

Livewire uncaught (in promise) DOMException with select

I have a dropdown in my component that seems to be causing an error in Livewire.
Uncaught (in promise) DOMException: Failed to execute 'setAttribute'
on 'Element': '?' is not a valid attribute name.
I added the wire:key code based on what I read in the docs under the troubleshooting section, but it didn't seem to help. It updates the value on save just like it should, but when it refreshes the dom with the new data, it's not working.
Here's the offending element:
<div class="mb-3 col-md-4 ">
<label for="state" class="form-label">State</label>
<select wire:model.defer="location.state" class="form-select"
id="state" name="state">
#foreach ($states as $state)
<option
name="{{ $state->name }}"
id="{{ $state->code }}"
wire:key="{{ $state->id }}"
value="{{ $state->code }}"
#if (isset($location->state)
&& $location->state === $state->code) ? selected #endif
>{{ $state->name }}
</option>
#endforeach
</select>
</div>
You have a typo here,
#if (isset($location->state) && $location->state === $state->code)
? selected
#endif
Where it tries to apply ? as an attribute on the element, but ? is not a valid attribute. Just remove the ?.
That said, you cannot use the selected property on <select> elements in Livewire to set the selected value. You need to set the value of your wire:model in your component. This means that you have to remove the #if(..) selected #endif from your Blade entirely, and instead set the value in your component,
public function mount() {
$this->location['state'] = $state->code;
}

vue js - check one radio button by default

In each set of group I wants to select one radio input by default.
each menu have multiple items. user need to select one item from each menu. so, I'm trying to select one item by default. How can I do that?
<div v-for="menu in menus">
<h4>#{{ menu.name }}</h4>
<div v-for="item in menu.menuitems">
<input type="radio" v-model="selected_items[menu.id]" :value="item" :key="item.item_id"> #{{ item.name }}
</div>
</div>
Firstly, you need to set a name attribute to the radio buttons in each menu, so that only one can be selected at a time.
And to set the first item of each menu as selected, you can use v-for index like:
<div v-for="item in menu.menuitems">
<input type="radio" v-model="selected_items[menu.id]"
:value="item.id"
:name="menu.id"
:key="item.item_id"> #{{ item.name }}
</div>
You will also need to update radio button :value from items to item.item_id and also modify :key="items.item_id" to :key="item.item_id". I think this was typo, as no variable exists in this scope like items.
and then inside mounted vue instance or any initial function inside methods you can set the values for each group item like:
mounted: function() {
this.menus.forEach(function(menu) {
this.selected_items[menu.id] = this.menu.menuitems.length ? this.menu.menuitems[0].id : null;
})
}
assuming menuitems[0] in an object with properties like item_id & name
You can still get selected item for each menu like:
this.menus.forEach(function(menu) {
var selectedItem = this.menu.menuitems.find(m => m.id == this.selected_items[menu.id]);
console.log(selectedItem)
// Retursn { id: xxx, name: 'xxx' }
})

How to show selected value from database in dropdown using Laravel?

I want to show selected value from database into dropdown list on page load.
My controller index function is :
public function index()
{
$country_data =DB::table('country')->select('country_id','country_name')->get();
$profile_data= DB::table('profiles')->select('*')->where('id',$user_id)->first();
return view('profile_update',compact('profile_data','country_data'));
}
Column name in database for height is :Height
My dropdown in profile_update.blade.php is
<select class="select4" name="country" id="country">
<option value="">Please Select</option>
#foreach($country_data as $country)
<option value="{{$country->country_id}}" {{$country_data->country == $country->country_id ? 'selected' : ''}}>{{$country->country_name}}</option>
#endforeach</select>
This is a example of how I do this:
<select class="js-states browser-default select2" name="shopping_id" required id="shopping_id">
<option value="option_select" disabled selected>Shoppings</option>
#foreach($shoppings as $shopping)
<option value="{{ $shopping->id }}" {{$company->shopping_id == $shopping->id ? 'selected' : ''}}>{{ $shopping->fantasyname}}</option>
#endforeach
</select>
In order to understand it fully you will need basics of laravel (MVC),
Let suppose, you have controller. In my case I made a separate table for drop down values.
My Approach --- Separate table for values of drop down, you can try different approach but my explanation was mainly focused on concept.
Note: PersonInfo is model, sampleType is model of my drop down values and don't forget to make a route for the controller.
ExampleController{
public funtion getValues($id){
/*
I am fetching information of a single row from the database by id and
then passing it to the view. The $id to the function came from the
request by your view/form.
I also fetched the values of drop down from the separate table
of database and passed it to the exampleView.
*/
$selectedValue=PersonInfo::findOrFail($id);
$sampleType=SampletypePicker::all(); //model for fetching all values of drop down
return view('exampleView',compact('selectedValue','sampleType));
}
}
So, in the above controller I fetched all values and passed it to the ExampleView. Now in your View file you have to work likewise.
exampleView.blade.php add the below code
<?php $options=$selectedValue->sample_type ?> //note take the value from the database which stored for the individual record and match it with the selected one.
<select class="form-control" name="test">
<option>Select Test Type</option>
#foreach ($sampleType as $value)
<option value="{{ $value->sample_type }}" {{ ( $value->sample_type == $options) ? 'selected' : '' }}>
{{ $value->sample_type }}
</option>
#endforeach
</select>
It is one of the best approach when you want to add dynamic values to the drop down. I mean if you want to add more values to the select tag options then this is the best approach.
Another Approach - take the idea
<?php $months = array("Jan", "Feb", "Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"); ?>
<?php $options=$patient_data->month ?>
#if($patient_data->month)
<select id="expiry_month" name="month" class="form-control-sm">
#foreach($months as $month)
<option value="{{$month}}" {{($month==$options)? 'selected':'' }}>{{$month}}</option>
#endforeach
</select>
#endif
<span class="select-icon"><i class="zmdi zmdi-chevron-down"></i></span>
</div>
OUTPUT of ABOVE CODE
#Sarita Sharma show the error(s). Maybe then anyone help you to resolve this problem. Show data in colections in controler - use dd e.g.
dd($country_data);
dd($profile_data);
Do you want to display the country in the view with the appropriate Height value from profile_data?
Ps. How to put the code, please use the formatting code - put the code in `` and use camelCase in value name (maintaining good PSR-1 practice) - it is easier to read code.
Well, simply if anyone still looking for this, here is the simple way to select items for dropdown from database to blade view
$users = Users::pluck('name', 'id');
$selectedID = 2;
return view('users.edit', compact('id', 'users'));
add this in the controller function before rendering the view
and in the blade view, simply use this variable as foreach loop as
<select name="user_id" class="form-control" id="exampleFormControlSelect1">
#foreach ($users as $key => $value)
<option value="{{ $key }}" {{ ($key == $selectedID) ? 'selected' : '' }}>
{{ $value }}
</option>
#endforeach
</select>
if you don't want to select all users from DB, you can use where condition before pluck condition as
$users = Users::where('status', 1)->pluck('name', 'id');
works with Laravel 8 and Laravel6

Resources