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' }
})
Related
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>
}
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
I am trying to create a sidebar menu with Alpine JS
I am not even sure if this is possible to do with Alpine JS.
#foreach($kanbans as $kanban)
<div x-data="activeKanban : ????">
<div #click="activeKanban = {{$kanban->id}}">
<div x-show="activeKanban !== {{$kanban->id}}">
// Design for collapsed kanban
</div>
<div>
<div x-show="activeKanban === {{$kanban->id}}">
// Design for active kanban
</div>
</div>
#endforeach
As I switch trough the pages, the $kanban->id changes, and I was wondering instead of manually setting activeKanban : 1 is there a way to pass this information to AlpineJS?
So that by default if I load the other page, the default menu that would be open would be based on the ID instead of them all being collapsed or just 1 that is specified being open?
If you're aiming for an accordion menu of sorts here's how you might achieve it with AlpineJs based on the code you shared:
// Set x-data on a div outside the loop and add your active kanban as a property
<div x-data="{
activeKanban: {{ $activeKanbanId ?? null }}
}">
#foreach($kanbans as $kanban)
<div #click="activeKanban = {{ $kanban->id }}">
<div x-show="activeKanban !== {{ $kanban->id }}">
// Collapsed view
</div>
<div x-show="activeKanban === {{ $kanban->id }}">
// Expanded view
</div>
</div>
#endforeach
</div>
Here each kanban menu item will have access to the activeKanban property in AlpineJs component instance and can set it reactively.
i.e. if activeKanban is set to a new id the current open item will close and the new one will open
Adding flexibility
What if you want to open and close them all independently though? There's more than one way to achieve this but in this case we can modify the code above to allow for it:
// Here we add an array of openItems and two helper functions:
// isOpen() - to check if the id is either the activeKanban or in the openItems array
// toggle() - to add/remove the item from the openItems array
<div x-data="{
activeKanban: {{ $activeKanbanId ?? null }},
openItems: [],
isOpen(id){
return this.activeKanban == id || openItems.includes(id)
},
toggle(id){
if(this.openItems.includes(id)){
this.openItems = this.openItems.filter(item => {
return item !== id
});
}else{
this.openItems.push(id)
}
}
}">
#foreach($kanbans as $kanban)
<div #click="toggle({{ $kanban->id }})">
<div x-show="!isOpen({{$kanban->id}})">
// Collapsed view
</div>
<div x-show="isOpen({{$kanban->id}})">
// Expanded view
</div>
</div>
#endforeach
</div>
This allows us to set an active item and also optionally open/close other menu items.
I know that I can get the row selected using the event "click:row" in my Datatable component, but I need to get the specific cell that I had clicked
You can use slots for that. Add it inside of your table component like given below:
<template v-slot:item.name="{ item }">
<div #click="rowClicked(item)">
<v-icon
class="mr-2"
color="#54a1e0"
large
>{{ "mdi-folder" }}
</v-icon>
{{ item.name }}
</div>
</template>
Here, you call a "rowClicked" method and you pass the clicked item when there is a click on "name" field that you also customise within the template.
I'm trying to set the value of an input corresponding to the selected radio button, but I just can't figure out how.
<input type="text" class="input" name="provider" v-model="selected_provider">
<b-radio-group v-model="provider_options">
<div class="field">
<template v-for="provider in providers">
<b-radio
name="select_provider[]" id="provider_#{{ $index }}"
model="selected_provider"
value="provider"
type="radio">
#{{ provider.provider_name }}
</b-radio>
</template>
</div>
</b-radio-group>
I've managed to get an array to display and that the input shows whatever is written in selected_provider, but I just don't know how to link those together.
var app = new Vue({
el: '#app',
data: {
selected_provider: '',
providers: [
{
provider_name: 'Twitch',
provider_url: 'https://www.twitch.tv/'
},
{
provider_name: 'Smashcast',
provider_url: 'https://www.smashcast.tv/'
},
{
provider_name: 'AzubuFrost',
provider_url: 'https://www.smashcast.tv/'
}
]
},
});
furthermore I'd like to attach the value of
<input type="text" class="input" name="name" id="name">
to the end of provider_url in selected_provider
Is someone so kind to help me?
If you set your for-loop to v-for="(provider, index) in providers"You can put a v-on:click="setSelectedProvider(index)" inside <b-radio></b-radio> and can create a method that looks like this:
setSelectedProvider: function(index){
this.$set(this, 'selected_provider', index);
}
Whenever a radio button is clicked this will set selected_provider to the index of the clicked radio button.
As for attaching the value of your other input to the end of provider_url, you can create a method that does this:
updateProviderURL: function(event){
this.$set(this.providers[this.selected_provider], 'provider_url',
'https://www.twitch.tv/' + event.currentTarget.value);
}
You can then add a listener to your input that looks like this:
v-on:input="updateProviderURL($event)"
It's good to set selected_provider by default to 0 inside the data part of your component so that the updateProviderURL function never tries to set a part of the array that doesn't exist ;)