vue.js 2 #click on div not respond(without methods) - vuejs2

I try change color of div by clicked on him, but the event not responded,
what I'm doing wrong?
here is my code
HTML:
<div class="demo" #click="attachRed != attachRed" :class="{ red: attachRed }"></div>
script:
'
export default {
data() {
return {
attachRed: false
}}
'
style:
.demo {
width: 100px;
height: 100px;
background-color: gray;
display: inline-block;
margin: 10px;
}
.red {
background-color: red;
}

It is
#click="attachRed = !attachRed
Not
#click="attachRed != attachRed
The != symbol is a test operator, and is read as "not equal," so what you have is "attachRed is not equal to attachRed." You should use the assignment operator of just = and negate the right-hand value. It should read "attachRed is assigned to NOT (!) attachRed."

Related

Vuejs v-movable with #click is not working

Im trying to implement a moveable text that can also be click and call the method. However when i try to put #click its not calling the function. Can anyone help me? Thank you..
App.vue
<template>
<div id="app">
<div>
<a #click="next()">
<movable class="testmove" posTop="222" posLeft="222" shiftKey="true"
><span>Shift Key Behavior</span></movable
>
</a>
</div>
</div>
</template>
<script>
import movable from "v-movable";
export default {
name: "app",
movable,
methmethods: {
next() {
alert("Hello");
},
},
};
</script>
<style>
body {
padding: 0;
margin: 0;
font-family: Helvetica, Arial;
}
.movable {
cursor: pointer;
}
.testmove {
/* display:block;
position: absolute; */
top: 0;
height: 150px;
width: 150px;
background: #333;
color: white;
}
.modaltitle {
background: blue;
display: block;
width: 100%;
color: white;
}
</style>
Here is the code:
https://codesandbox.io/s/cold-darkness-0zm03?file=/src/App.vue
There is a typo in your code methmethods which should be corrected to methods
You can use start event for the v-movable.
#start: fires immediately after the pointerdown event on the element

Custom switch component with v-model doesn't work

trying to do my custom Switch component in VueJS following these manuals Using v-model on Components, Adding v-model Support to Custom Vue.js Components but something wrong and it doesn't work.
My SwitchTest component:
<template>
<div>
<input type="checkbox" :id="_uid"
:value="value"
#input="updateData"
class="checkbox">
<label :for="_uid" class="switch"></label>
</div>
</template>
<script>
export default {
props: ["value"],
data() {
return {};
},
methods: {
updateData($event) {
console.log($event.target.value);
this.$emit("input", $event.target.value);
}
}
};
</script>
<style scoped>
.switch {
position: relative;
display: inline-block;
width: 40px;
height: 20px;
background-color: rgba(0, 0, 0, 0.25);
border-radius: 20px;
transition: all 0.3s;
}
.switch::after {
content: "";
position: absolute;
width: 18px;
height: 18px;
border-radius: 50%;
background-color: white;
top: 1px;
left: 1px;
transition: all 0.3s;
}
.checkbox:checked + .switch::after {
left: 20px;
}
.checkbox:checked + .switch {
background-color: #7983ff;
}
.checkbox {
display: none;
}
</style>
And using SwitchTest component:
{{switch1}}
<SwitchTest v-model="switch1"/>
{{switch2}}
<SwitchTest v-model="switch2"/>
You can see the whole MVCE example here: https://codesandbox.io/s/ecstatic-meninsky-zx7w0?file=/src/App.vue:32-131
When I toggle checkbox, its value doesn't change.
Where am I wrong?
Thank you.
Checkboxes are a special case where they have two states (checked / unchecked) which can be translated to two values. Normally, this is simply true / false but since you've bound a single :value, you'll only ever get the same value each time.
Try binding the Boolean value prop to checked and emit a true / false value
<input
type="checkbox"
:checked="value"
:id="_uid"
#input="$emit('input', $event.target.checked)"
class="checkbox"
>

Vue-multiselect - How to insert html code in placeholder?

Im trying insert span in placeholder, for color change. But placeholder returns only string, ow to fix that?
computed: {
customPlaceholder () {
let numLength = this.options.length;
return this.placeholder + "<span>"+numLength+"</span>"
}
}
I think you're trying to add a custom placeholder inside an input field.
to do this you need some mix of css and html.
new Vue({
el: '#editor',
data: {
input: '',
input2: 'some text'
},
computed: {
placeholderText: function () {
return `${this.input2} <span>*</span>`
}
},
methods: {
update: _.debounce(function (e) {
this.input = e.target.value
}, 300)
}
})
#editor div {
display: inline-block;
}
.input-placeholder {
position: relative;
}
.input-placeholder input {
padding: 10px;
font-size: 25px;
}
.input-placeholder input:valid + .placeholder {
display: none;
}
.placeholder {
position: absolute;
pointer-events: none;
top: 0;
bottom: 0;
height: 25px;
font-size: 25px;
left: 10px;
margin: auto;
color: #ccc;
}
.placeholder span {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/lodash#4.16.0"></script>
<div id="editor">
<div class="input-placeholder">
<input type="text" #input="update">
<div class="placeholder" v-if="!input" v-html="placeholderText">
Email <span>*</span>
</div>
</div>
</div>
I have created this jsfiddle for my solution.
you can use css placeholder selector
input::-webkit-input-placeholder { /* Edge */
color: green!important;
}
input:-ms-input-placeholder { /* Internet Explorer 10-11 */
color: green!important;
}
input::placeholder {
color: green!important;
}
Try it, then try to remove the !important.
But information is missing. You want to change the color dynamically or not? or you want to have different colours into the same placeholder?

vue-pagination-2 not working

I am brand new to VueJS and almost everything is working, except for pagination. As a matter of fact, I have zero warnings. The only thing appearing in the console is "[HMR] Waiting for update signal from WDS... log.js?4244:23" followed by a ">" on the next line.
With that said, the pagination is showing the correct number of pages - given the data coming from the JSON, but I do not know how to connect the pagination to the UL or the app.
At least when there is an error, I can figure something out. Any help is appreciated and thanks in advance.
<template>
<div class="container" id="app">
<span>VueJS-Example</span>
<ul class="list-group list-inline mHeaders">
<li class="list-group-item">Title</li>
<li class="list-group-item">Band</li>
<li class="list-group-item">Date Posted</li>
<li class="list-group-item">Downloads</li>
<li class="list-group-item">YouTube</li>
<li class="list-group-item">MP3</li>
</ul>
<ul :key="item.id" class="list-group list-inline" v-for="item in items">
<li class="list-group-item">
{{item.title}}
</li>
<li class="list-group-item">
{{item.original_band}}
</li>
<li class="list-group-item">
{{item.date_posted}}
</li>
<li class="list-group-item mZip">
<a v-bind:href="''+item.download_midi_tabs+''" target="_blank"></a>
</li>
<li class="list-group-item mYt">
<a v-bind:href="''+item.youtube_link+''" target="_blank"></a>
</li>
<li class="list-group-item mAudio">
<a v-bind:href="''+item.download_guitar_m4v+''" target="_blank"></a>
</li>
</ul>
<pagination :records="288" :per-page="30" #paginate="getPostsViaREST"></pagination>
</div>
</template>
<script>
import axios from 'axios'
import {Pagination} from 'vue-pagination-2'
export default {
name: 'App',
data: function () {
return {
items: [{
title: '',
original_band: '',
date_posted: '',
download_midi_tabs: '',
youtube_link: '',
download_guitar_m4v: ''
}]
}
},
created: function () {
this.getPostsViaREST()
},
methods: {
getPostsViaREST: function () {
axios.get('http://local.sites/getSongs.php')
.then(response => { this.items = response.data })
}
},
components: {
Pagination
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
a {
color: #999;
}
.current {
color: red;
}
ul {
padding: 0;
list-style-type: none;
}
li {
display: inline;
margin: 5px 5px;
}
ul.list-group:after {
clear: both;
display: block;
content: "";
}
.list-group-item {
float: left;
}
.list-group li{
max-width: 30%;
min-width: 50px;
min-height: 48px;
max-height: 48px;
}
.list-group li:first-child{
width: 200px;
cursor: pointer;
}
.list-group li:nth-child(2){
width: 200px;
}
.list-group li:nth-child(3){
width: 110px;
}
.list-group li:nth-child(4){
width: 48px;
}
.list-group li:nth-child(5){
width: 48px;
}
.list-group li:last-child{
width: 48px;
}
.mZip{
background: url("http://www.kronusproductions.com/songs_angular/assets/images/mZip.png");
display: block !important;
max-width: 48px;
height: 48px;
cursor: pointer;
}
.mYt{
background: url("http://www.kronusproductions.com/songs_angular/assets/images/youtube-icon_48x48.png");
display: block !important;
width: 48px;
height: 48px;
cursor: pointer;
}
.mAudio{
background: url("http://www.kronusproductions.com/songs_angular/assets/images/volume.png");
display: block !important;
width: 48px;
height: 48px;
cursor: pointer;
}
.mZip a{
display: block !important;
width: 48px;
height: 48px;
}
.mYt a{
display: block !important;
width: 48px;
height: 48px;
}
.mAudio a{
display: block !important;
width: 48px;
height: 48px;
}
.mHeaders li{
background-color: cornflowerblue;
font-size: 0.85rem;
color: white;
}
OK - this is somewhat of a hack, but it works.
The following URL is a working example:
Needed help from some old fashion native JavaScript on the index.html file. First, I needed to be able to read a hidden field that contained the number of entries coming from the JSON., followed by setting all the ULs to display none - the setTimeout is to make sure that the JSON file was loaded
<script type="text/javascript">
var mTO = setTimeout(function () {
for (var x = 31; x <= $(".numRows").val() - 1; x++) {
if (typeof (document.getElementById('sp_' + x)) === 'undefined') {
} else {
document.getElementById('sp_' + x).style.display = 'none'
}
}
}, 1000);
mTO;
</script>
This is followed by calling a computed user created method to set this.mVar to the number of elements/entries/properties - whatever name you want to use for it - for Vue to know how many elements, so that we could divide by the number of pages to paginate
computed: {
mFunc: function () {
this.mVar = Object.keys(this.items).length
return Object.keys(this.items).length
}
}
This is another portion of the aforementioned hack - depending on page clicked in the pagination section, this determines what to hide and what to show
setPage: function (page) {
this.page = page
// console.log(page)
for (var y = 0; y <= this.mVar - 1; y++) {
if (typeof (document.getElementById('sp_' + y)) === 'undefined') {
} else {
document.getElementById('sp_' + y).style.display = 'none'
}
}
for (var x = (30 * (this.page - 1)); x <= 30 * (this.page); x++) {
if (typeof (document.getElementById('sp_' + x)) === 'undefined' || (document.getElementById('sp_' + x)) == null) {
break
} else {
document.getElementById('sp_' + x).style.display = 'block'
}
}
}
In case you were wondering what the "30" is for, that is the number of ULs that I wanted to show per page.
The last portion of the hack is within the template section
<pagination :records="mFunc" :per-page="30" #paginate="setPage"></pagination>
<span style="display: none;"><input type="hidden" class="numRows" :value="this.mVar" /></span>
If you would like to use the entire, then you can find it on my github:
Github repo for vuejs-example

Stop event listener from listing to children elements in Vue

I'm creating a modal in Vue, which I want to to be able to close whenever the user clicks outside of the inner modal container. The problem is when I add an event listener on click to the parent element all children elements also trigger that event listener when clicked.
I created a simple demo below to demonstrate my problem. If the user clicks on the black portion of the parent element the modal should close but the containing white space of the child element shouldn't be able to trigger the close function.
new Vue({
el: '#modal',
data: {
active: true,
},
methods: {
closeModal() {
this.active = false
}
}
})
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
justify-content: center;
align-items: center;
background-color: black;
}
.modal.active {
display: flex;
}
.modal-content {
width: 200px;
height: 200px;
padding: 1rem;
background-color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="modal" class="modal" :class="{active: active}" v-on:click="closeModal">
<div class="modal-content">This child element shouldn't be able to close the modal on click.</div>
</div>
You can try
v-on:click.self=...
Should only trigger if the target element is itself.
Hope that helps
I endorse kimy82's answer. Use click.self. Snippet updated.
new Vue({
el: '#modal',
data: {
active: true,
},
methods: {
closeModal(event) {
this.active = false
}
}
})
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
justify-content: center;
align-items: center;
background-color: black;
}
.modal.active {
display: flex;
}
.modal-content {
width: 200px;
height: 200px;
padding: 1rem;
background-color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="modal" class="modal" :class="{active: active}" v-on:click.self="closeModal">
<div class="modal-content">This child element shouldn't be able to close the modal on click.</div>
</div>
There are event modifiers for the click event handler
https://v2.vuejs.org/v2/guide/events.html#Event-Modifiers
<!-- modifiers can be chained -->
<a v-on:click.stop.prevent="doThat"></a>