How to change <select> value on Vuejs3? - javascript

I wanted to change <select> value getting ul > li value and use this value id on <select> v-model.
<div>
<select id="selected" #click="show-modal" v-model="subcategory_id">
<option></option>
</select>
</div>
<div class="modal">
<header class="modal-card-head">
<p class="modal-card-title">Choose category</p>
<button #click.prevent="close-modal" class="delete" aria-label="close"></button>
</header>
<section class="modal-card-body">
<div class="card ">
<ul class="cl-menu">
<li v-for="category in categories" :key="category.id" >
<a href="#">{{category.name}}
<ul>
<li #click="getLi(sub)" v-for="sub in category.subcategory" :key="sub.id">
<a class="px-2" href="#">{{sub.name}}</a>
</li>
</ul>
</li>
</ul>
</div>
</section>
</div>
Vuejs
getLi: function(e) {
const m = document.querySelector('.modal');
document.getElementById("selected").options[0].value = e.name;
m.classList.toggle('is-active')
console.log(e.name)
}
I am able to get value from list but cannot pass it to select value and value`s id to v-model.
Thanks in advance

Instead of manipulating the DOM as #Thomas said, you should make use of Vue's data binding:
new Vue({
el: '#app',
template: `<div><div>
<select id="selected" #click="show-modal" v-model="subcategory_id" disabled>
<optgroup v-for="category in categories" :key="category.id" :label="category.name">
<option v-for="sub in category.subcategory" :key="sub.id" :value="sub.id">
{{sub.name}}
</option>
</optgroup>
</select>
<button #click="openModal">Choose</button>
</div>
<div class="modal" v-if="showModal">
<header class="modal-card-head">
<p class="modal-card-title">Choose category</p>
<button #click.prevent="closeModal" class="delete" aria-label="close">×</button>
</header>
<section class="modal-card-body">
<div class="card ">
<ul class="cl-menu">
<li v-for="category in categories" :key="category.id" >
{{category.name}}
<ul>
<li #click="getLi(sub)" v-for="sub in category.subcategory" :key="sub.id">
<a class="px-2" href="#">{{sub.name}}</a>
</li>
</ul>
</li>
</ul>
</div>
</section>
</div></div>`,
data() {
return {
showModal: true,
subcategory_id: null,
categories: [{
name: 'A',
id: 1,
subcategory: [{
name: 'A.1',
id: 2
}]
}, {
name: 'B',
id: 3,
subcategory: [{
name: 'B.1',
id: 4
}]
}]
}
},
methods: {
getLi: function(subId) {
this.subcategory_id = subId.id
this.closeModal()
},
closeModal() {
this.showModal = false
},
openModal() {
this.showModal = true
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>

Related

Vue not passing data in component

I am not sure why the data is undefined despite passing the right property from the component.
This is my vue component
Vue.component('store-squaretile-component',{
template: '#store-squaretile-component',
props: [
'storeName'
],
data: function () {
return {}
},
});
This is its template
<script type='text/x-template' id='store-squaretile-component'>
<div class="stores-squaretile__container">
<div class="stores-squaretile__btn stores-squaretile__btn--shadow" >
<!-- background of store-squaretile to be set to img -->
<div class="dropdown">
<div class="stores-squaretile__threedots" data-bs-toggle="dropdown" >
<i class="fas fa-ellipsis-v"></i>
</div>
<ul id="dropdown-menu-store" class="dropdown-menu" >
<div class="'dropdown-item dropdown-title">Quick Actions</div>
<div class="dropdown-line"></div>
<a class="dropdown-item" href="#">Edit Store</a>
<a class="dropdown-item" href="#">Delete Store</a>
</ul>
</div>
</div>
<div class="stores-squaretile__title">{{storeName}}</div>
</div>
</script>
When i pass the component this array:
stores: [
{name: "harry's",},
{name: "Carl's junior",},
{name: "Mcdonald's",}
]
into this component
<store-squaretile-component
v-for="store in stores"
:storeName="store.name"
></store-squaretile-component>
it is suppose to suppose to replace the storeName with the name in the array but instead I get a NaN or the title disappears entirely.
I received an undefined value. Is there a reason for this?
It's working fine, just replaced storeName with storename and added :key to v-for loop:
Vue.component('store-squaretile-component', {
template: '#store-squaretile-component',
props: ['storename'],
})
new Vue({
el: '#demo',
data() {
return {
stores: [
{name: "harry's", },
{name: "Carl's junior",},
{name: "Mcdonald's",}
]
}
}
})
Vue.config.productionTip = false
Vue.config.devtools = false
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<store-squaretile-component
v-for="(store, idx) in stores"
:storename="store.name"
:key="idx"
></store-squaretile-component>
</div>
<script type='text/x-template' id='store-squaretile-component'>
<div class="stores-squaretile__container">
<div class="stores-squaretile__btn stores-squaretile__btn--shadow" >
<div class="dropdown">
<div class="stores-squaretile__threedots" data-bs-toggle="dropdown" >
<i class="fas fa-ellipsis-v"></i>
</div>
<ul id="dropdown-menu-store" class="dropdown-menu" >
<div class="'dropdown-item dropdown-title">Quick Actions</div>
<div class="dropdown-line"></div>
<a class="dropdown-item" href="#">Edit Store</a>
<a class="dropdown-item" href="#">Delete Store</a>
</ul>
</div>
</div>
<div class="stores-squaretile__title">{{storename}}</div>
</div>
</script>

How to make a specific element to have an active class using v-if and v-bind

This is the following code:
<div class="filter-item-wrapper-inner">
<div class="filter-item" #click="filterImages(1)">
<div class="bg-item-img"></div>
<div class="filter-item-overlay active">
<h5>{{webData.filters[0]}}</h5>
</div>
</div>
<div class="filter-item" #click="filterImages(2)">
<div class="bg-item-img"></div>
<div class="filter-item-overlay">
<h5>{{webData.filters[1]}}</h5>
</div>
</div>
<div class="filter-item" #click="filterImages(3)">
<div class="bg-item-img"></div>
<div class="filter-item-overlay">
<h5>{{webData.filters[2]}}</h5>
</div>
</div>
<div class="filter-item" #click="filterImages(4)">
<div class="bg-item-img"></div>
<div class="filter-item-overlay">
<h5>{{webData.filters[3]}}</h5>
</div>
</div>
<div class="filter-item" #click="filterImages(5)">
<div class="bg-item-img"></div>
<div class="filter-item-overlay">
<h5>{{webData.filters[4]}}</h5>
</div>
</div>
<div class="filter-item" #click="filterImages(6)">
<div class="bg-item-img"></div>
<div class="filter-item-overlay">
<h5 class="entertainment-font">{{webData.filters[5]}}</h5>
</div>
</div>
<div class="filter-item" #click="filterImages(7)">
<div class="bg-item-img"></div>
<div class="filter-item-overlay">
<h5>{{webData.filters[6]}}</h5>
</div>
</div>
</div>
Here is the class:
.filter-item .filter-item-overlay.active {
background-color: rgba(0, 0, 0, .7291);
}
So I want to make single selected element to set as active by click. So when the user clicks on specific filter it remains active. Is there some alternative with using v-bind and v-if?
Here is a simplified version of your code using style binding:
var app = new Vue({
el: '#app',
data: {
activeIndex: 0
}
})
.active {
color: red;
}
<script src="https://cdn.jsdelivr.net/npm/vue#2/dist/vue.js"></script>
<div id="app">
<ul>
<li #click="activeIndex=1" :class="[activeIndex===1 ? 'active' : '']">One</li>
<li #click="activeIndex=2" :class="[activeIndex===2 ? 'active' : '']">Two</li>
<li #click="activeIndex=3" :class="[activeIndex===3 ? 'active' : '']">Three</li>
</ul>
</div>
As suggested you above, you should take a look at the vue doc : https://v2.vuejs.org/v2/guide/class-and-style.html
But this might help you :
<template>
<div
v-for="i in 7"
:key="'img_' + i"
class="filter-item"
#click="filterImages(i)"
>
<div class="bg-item-img"></div>
<div
class="filter-item-overlay"
:class="{'active' : filteredImage === i}"
>
<h5>{{webData.filters[i]}}</h5>
</div>
</div>
</template>
<script>
export default {
name: "Filter",
data() {
return {
filteredImage: -1,
}
},
methods: {
filterImages(index) {
this.filteredImage = index;
}
}
}
</script>

Vuejs - How can i bind select item to input of combobox

I am trying to bind data from combobox I selected to its own input but every time I select an item of combobox 1 combobox 2 will also show combobox 1 item. Below is the code I wrote
HTML
// Combobox 1
<div style="height: 40px">
<div class="m-combobox" id="cbbWorkStatus">
<div class="m-combobox-label">Tình trạng công việc</div>
<div
class="select-list"
:class="
isActivate === 'workstatus' ? 'sl-activate' : 'inactive'
"
ref="selectList"
>
<div
class="select-item"
:value="item.WorkStatusId"
v-for="item in workStatuses"
:key="item.WorkStatusId"
#click="isSelect"
>
<i class="fas fa-check"></i>
<div class="select-item-text">
{{ item.WorkStatusName }}
</div>
</div>
</div>
<div class="select">
<input
class="m-combobox-input"
type="text"
placeholder="Chọn/Nhập thông tin"
value=""
tabindex="15"
id="txtWorkStatus"
fieldname="WorkStatus"
format="workStatus"
v-model="selectedValue" <----------------
/>
<div
class="m-combobox-button"
#click="activateCbb('workstatus')"
>
<i class="fas fa-angle-down"></i>
</div>
</div>
</div>
</div>
//Combobox 2
<div style="height: 40px">
<div
class="m-combobox"
id="cbbDepartment"
cbbname="DepartmentName"
cbbid="DepartmentId"
>
<div class="m-combobox-label">Phòng ban</div>
<div
class="select-list"
style="z-index: 100"
:class="
isActivate === 'department' ? 'sl-activate' : 'inactive'
"
ref="selectList"
>
<div
class="select-item"
v-for="item in departments"
:value="item.DepartmentId"
:key="item.DepartmentId"
#click="isSelect"
>
<i class="fas fa-check"></i>
<div class="select-item-text">
{{ item.DepartmentName }}
</div>
</div>
</div>
<div class="select">
<input
class="m-combobox-input"
type="text"
placeholder="Chọn/Nhập thông tin"
value=""
tabindex="11"
id="txtDepartment"
fieldname="DepartmentId"
format="department"
v-model="selectedValue" <--------------
/>
<div
class="m-combobox-button"
#click="activateCbb('department')"
>
<i class="fas fa-angle-down"></i>
</div>
</div>
</div>
Data
data() {
valueInput: null,
}
Methods
created() {
this.selectedValue = this.valueInput;
},
But this way, when I select the item in the combobox above, the combobox below is also displayed. I want each combobox to show only their item. Thank all!
You have bound the same v-model to both the comboboxes, naturally giving you this result. Just create two separate v-models, one for selectedWorkStatusValue and the other for selectedDeptStatusValue. I don't know the library you used for creating the combo-box, or else I would have given you a full working demo. Nevertheless, the below sample should be enough to get you going.
new Vue({
el: "#app",
data: function() {
return {
workStatuses: [{
WorkStatusId: 1,
WorkStatusName: 'Programmer'
},
{
WorkStatusId: 2,
WorkStatusName: 'DevOps'
},
{
WorkStatusId: 3,
WorkStatusName: 'HR'
}
],
departments: [{
DepartmentId: 1,
DepartmentName: 'IT'
},
{
DepartmentId: 2,
DepartmentName: 'Management'
}
],
selectedWorkStatusValue: '',
selectedDeptStatusValue: ''
};
},
methods: {
isSelect(){ console.log('clicked isSelect') },
activateCbb(){ console.log('clicked isSelect') }
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div style="height: 40px">
<div class="m-combobox" id="cbbWorkStatus">
<div class="m-combobox-label">Tình trạng công việc</div>
<div class="select-list" ref="selectList">
<div class="select-item" :value="item.WorkStatusId" v-for="item in workStatuses" :key="item.WorkStatusId" #click="isSelect">
<i class="fas fa-check"></i>
<div class="select-item-text">
{{ item.WorkStatusName }}
</div>
</div>
</div>
<div class="select">
<input class="m-combobox-input" type="text" placeholder="Chọn/Nhập thông tin" value="" tabindex="15" id="txtWorkStatus" fieldname="WorkStatus" format="workStatus" v-model="selectedWorkStatusValue" />
<div class="m-combobox-button" #click="activateCbb('workstatus')">
<i class="fas fa-angle-down"></i>
</div>
</div>
</div>
</div>
<br/><br/><br/><br/>
<div style="height: 40px">
<div class="m-combobox" id="cbbDepartment" cbbname="DepartmentName" cbbid="DepartmentId">
<div class="m-combobox-label">Phòng ban</div>
<div class="select-list" style="z-index: 100" ref="selectList">
<div class="select-item" v-for="item in departments" :value="item.DepartmentId" :key="item.DepartmentId" #click="isSelect">
<i class="fas fa-check"></i>
<div class="select-item-text">
{{ item.DepartmentName }}
</div>
</div>
</div>
<div class="select">
<input class="m-combobox-input" type="text" placeholder="Chọn/Nhập thông tin" value="" tabindex="11" id="txtDepartment" fieldname="DepartmentId" format="department" v-model="selectedDeptStatusValue" />
<div class="m-combobox-button" #click="activateCbb('department')">
<i class="fas fa-angle-down"></i>
</div>
</div>
</div>
</div>
</div>
You v-model is the same on combobox 1 and 2 so if you select a value it's the same on both
So you need to create another v-model for your combobox 2 :
// Combobox 1
<div style="height: 40px">
<div class="m-combobox" id="cbbWorkStatus">
<div class="m-combobox-label">Tình trạng công việc</div>
<div
class="select-list"
:class="
isActivate === 'workstatus' ? 'sl-activate' : 'inactive'
"
ref="selectList"
>
<div
class="select-item"
:value="item.WorkStatusId"
v-for="item in workStatuses"
:key="item.WorkStatusId"
#click="isSelect"
>
<i class="fas fa-check"></i>
<div class="select-item-text">
{{ item.WorkStatusName }}
</div>
</div>
</div>
<div class="select">
<input
class="m-combobox-input"
type="text"
placeholder="Chọn/Nhập thông tin"
value=""
tabindex="15"
id="txtWorkStatus"
fieldname="WorkStatus"
format="workStatus"
v-model="selectedValue" <----------------
/>
<div
class="m-combobox-button"
#click="activateCbb('workstatus')"
>
<i class="fas fa-angle-down"></i>
</div>
</div>
</div>
</div>
//Combobox 2
<div style="height: 40px">
<div
class="m-combobox"
id="cbbDepartment"
cbbname="DepartmentName"
cbbid="DepartmentId"
>
<div class="m-combobox-label">Phòng ban</div>
<div
class="select-list"
style="z-index: 100"
:class="
isActivate === 'department' ? 'sl-activate' : 'inactive'
"
ref="selectList"
>
<div
class="select-item"
v-for="item in departments"
:value="item.DepartmentId"
:key="item.DepartmentId"
#click="isSelect"
>
<i class="fas fa-check"></i>
<div class="select-item-text">
{{ item.DepartmentName }}
</div>
</div>
</div>
<div class="select">
<input
class="m-combobox-input"
type="text"
placeholder="Chọn/Nhập thông tin"
value=""
tabindex="11"
id="txtDepartment"
fieldname="DepartmentId"
format="department"
v-model="selectedValue2" <-------------- New Selected Value
/>
<div
class="m-combobox-button"
#click="activateCbb('department')"
>
<i class="fas fa-angle-down"></i>
</div>
</div>
</div>
<script>
export default {
data() {
return {
workStatuses: [],
departments: [],
selectedValue : '',
selectedValue2: ''
};
},
methods: {
isSelect(){ console.log('clicked isSelect') },
activateCbb(){ console.log('clicked isSelect') }
}
}
</script>

Nested loop to v-model Vue JS

I want to collect the data from input with v-model on nested loop, but idk how to do it cause i'm new in Vue.
Here's the code for the component :
<div
class="date-item"
v-for="(day,index) in dateList"
>
<div class="mt-4">
<div class="form-group">
<ul class="list-task">
<li v-for="(n,n_key) in 10" :key="n_key">
<base-input
:id="'input-text'+n"
:type="'text'"
:disabled="day.isPastDay"
/>
</li>
</ul>
</div>
</div>
</div>
Anyone can help how i created a v-model and data variable for this case ?
With v-model="day.inputs[n_key]"
new Vue({
el: '#app',
data: () => ({
dateList: [{
isPastDay: false,
inputs: []
}]
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.14/vue.min.js"></script>
<div id="app">
<div class="date-item" v-for="(day,index) in dateList">
<div class="mt-4">
<div class="form-group">
<ul class="list-task">
<li v-for="(n,n_key) in 10" :key="n_key">
<input type="text" v-model="day.inputs[n_key]" :disabled="day.isPastDay" />
</li>
</ul>
</div>
</div>
</div>
<pre>{{ dateList }}</pre>
</div>

Problem with search script I can't take a good property from navbar to searchcomponent in vue.js

I have issue with my search script in Vue.js. I can't take property from navbar component to search component. Search component is connected with Search.vue file but it only has appeal to search component.
<template>
<div>
<Navbar></Navbar>
<div class="container">
<br>
<div class="row justify-content-center">
<div class="col-md-8">
<div v-if="showsearch == true">
<div v-for="post in posts.data" :key="post.id">
<div class="card">
<div class="card-header">{{post.title}}</div>
<div class="card-body text-center">
<div id="description">{{post.description}}</div>
<div class="embed-responsive embed-responsive-16by9" v-if="post.source_url !== null && post.source_url !== undefined">
<iframe id="source_url" class="embed-responsive-item" :src="post.source_url + '?showinfo=0'" frameborder="0" allowfullscreen/>
</div>
<div v-if="post.file_name !== null && post.file_name !== 'undefined'">
<img id="file_name" class="img-responsive" :src="'images/' + post.file_name"/>
</div>
<div id="author">Wrzucony przez: {{post.author}}</div>
</div>
</div>
<br>
</div>
</div>
<pagination :meta_data="meta_data" v-on:next="fetchSearch"></pagination>
<div v-if="showsearch == false"></div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
import Pagination from '/resources/js/components/Pagination'
import Navbar from '/resources/js/components/Navbar'
export default {
data(){
return {
posts: [],
post: {
id: '',
title: '',
description: '',
author: '',
source_url: '',
file_name: '',
},
meta_data: {
last_page: null,
current_page: 1,
prev_page_url: null
},
props: ['search'],
showsearch: false,
}
},
mounted() {
this.fetchSearch();
},
components: {
Pagination,
Navbar
},
methods: {
fetchSearch(page = 1){
axios.get('/api/post/search/' + this.props.search + '?page=' + page)
.then(res => {
this.posts = res.data;
this.search = res.data.search;
this.showsearch = true;
this.meta_data.last_page = res.data.last_page;
this.meta_data.current_page = res.data.current_page;
this.meta_data.prev_page_url = res.data.prev_page_url;
})
.catch(err => {
console.log(err);
})
},
},
}
</script>
<template>
<div>
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<nuxt-link to="/" class="navbar-brand nav-link">PanZiemniak</nuxt-link>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<nuxt-link to="/create" class="nav-link">Dodaj Ziemniaka</nuxt-link>
</li>
</ul>
<form class="form-inline my-2 my-lg-0 navbar-right" action="/search" method="GET">
<input class="form-control mr-sm-2" type="text" placeholder="Podaj tytuł" aria-label="search" id="search" name="search" v-model="search">
<button class="btn btn-primary" type="submit">Wyszukaj</button>
</form>
</nav>
<nuxt/>
</div>
</template>
<script>
export default {
props: ['search'],
data(){
return{
search: '',
}
}
}
</script>
My output in network:
URL Request:http://localhost/api/post/search/undefined?page=1
Method request:GET
Code: 200

Categories