How to point out this to a certain element in VueJS? - javascript

I am creating a form. When a input is focused, then the color of label should be blue. But it looks like something is wrong in my code. I am unable to point out this to the input.
Here's the code which doesn't work:
new Vue({
el: '#app',
data: {
inputs: document.querySelector('.input')
},
methods: {
changeColor(){
this.inputs.previousElementSibling.style.color = "blue";
}
}
});
<div id="app">
<label for="input">Input</label>
<input type="text" class = "input" v-on:focus = "changeColor"><br /><br />
</div>
<script type = "text/javascript" src = "https://vuejs.org/js/vue.js"></script>
Here's the code that works:
new Vue({
el: '#app',
data: {
inputs: document.querySelector('.input')
},
methods: {
changeColor(){
document.querySelector('.input').previousElementSibling.style.color = "blue";
}
}
});
<div id="app">
<label for="input">Input</label>
<input type="text" class = "input" v-on:focus = "changeColor"><br /><br />
</div>
<script type = "text/javascript" src = "https://vuejs.org/js/vue.js"></script>
So, my question why this.inputs doesn't work but document.querySelector('.input') works?

I have a simpler alternative that gives more flexibility
new Vue({
el: '#app',
props: ['styles'],
methods: {
changeStyles() {
this.styles = {
color: 'blue' // Add more CSS rules if you want
}
},
restoreStyles() {
this.styles = {
color: 'black'
}
}
}
})
<div id="app">
<label :style="styles">Input</label>
<input type="text" #focus="changeStyles" #focusout="restoreStyles">
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
Hope it helps. And the for attribute in label tag only works with id of the bound input field.

Check the console output of this snippet:
new Vue({
el: '#app',
data: {
inputs: document.querySelector('.input')
},
methods: {
changeColor(){
console.log('Are the similar? answer: ',
this.inputs == document.querySelector('.input'));
this.inputs.previousElementSibling.style.color = "blue";
}
}
});
<div id="app">
<label for="input">Input</label>
<input type="text" class = "input" v-on:focus = "changeColor"><br /><br />
</div>
<script type = "text/javascript" src = "https://vuejs.org/js/vue.js"></script>
After Vue instance is created it replaces all elements inside the #app in its own flavor. Your inputs field is set at the moment of creating Vue instance and before mounting the #app component. So the thing that you store in the this.inputs is long dead!
You should probably read through the Reactivity in Depth very carefully. And as suggested by the #Shreevardhan's answer, you should always use Vue's way to manipulate Vue's stuffs.

Related

Get the value of input when the cursor is out in javascript?

I have a input :
<a-form-item label="user" :colon="false">
<a-input placeholder="user" name="user" #keyup.enter="checkUser"/>
</a-form-item>
In methods:
checkUser() {
console.log('ok');
},
In methods : checkUser when i enter then i get the input value. But now I don't want to do that, I want when I finish entering the input value, move the cursor outside and methods : checkUser will get the value of that input. Thank you
Make use of blur event listener.
<a-input placeholder="user" name="user" #blur="checkUser"/>
Sample Fiddle
new Vue({
el: '#app',
data: {},
methods: {
checkUser: function(e) {
console.log("Blur event triggered", e.target.value)
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.4/vue.js"></script>
<div id="app">
<input type="text" #blur="checkUser">
</div>
If you want the method to get triggered while moving out the cursor then you can use #mouseleave event.
OR
If you want to trigger the method when the input loses focus then you could try using #blur event
new Vue({
el: '#app',
methods: {
checkUser(e) {
if(e.target.value !== '') { // To check if the input is not empty
console.log("event triggered", e.target.value)
}
return;
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.4/vue.js"></script>
<div id="app">
<input type="text" #mouseleave="checkUser">
<!-- OR -->
<!--<input type="text" #blur="checkUser"> -->
</div>

How to switch between v-html and insert as plain text in vue.js?

I'm looking to toggle between v-html and insert as plain text in vue.js v2. So far I have this
HTML
<div id="app">
<h2 v-html="html ? text : undefined">{{html ? '' : text}}</h2>
<button #click="toggle">
switch
</button>
</div>
JS
new Vue({
el: "#app",
data: {
text:"Hello<br/>World",
html:false
},
methods: {
toggle: function(){
this.html = !this.html;
}
}
})
but this doesn't work when html is false. How can I get this to work? I'm looking for a solution where I don't need to repeat <h2> twice using a v-else. Preferably, if I can do it with just the 1 <h2> tag.
Thanks
Use v-bind with the prop modifier. see docs.
new Vue({
el: "#app",
data: {
text:"Hello<br/>World",
html:false
},
computed: {
headingProps() {
return this.html ? { innerHTML: this.text } : { innerText: this.text } ;
},
},
methods: {
toggle: function(){
this.html = !this.html;
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<h2 v-bind.prop="headingProps"></h2>
<button #click="toggle">
switch
</button>
</div>

How to swap input fields with Vue?

I am having difficulty to swap fields when a click event is triggered. Here is my code below, which is just changing the value and name once but it does not work if I click again. It also does not change the v-model value. Can anyone help me please?
HTML
<div id='app'>
<button #click="swapInputFields">Swap</button>
<input type="text" :name="[field1]" v-model="model1" :value="[fromCity]"><br>
<input type="text" :name="[field2]" v-model="model2" :value="[toCity]">
</div>
Vue code:
var app = new Vue({
el: '#app',
data: {
fromCity:'FROM',
toCity :'TO',
field1 :'name1',
field2 :'name2'
},
methods: {
swapInputFields()
{
this.fromCity = 'TO';
this.toCity ='FROM';
this.field1 = 'name2';
this.field2 ='name1';
}
}
});
Remove the [ ] brackets from the bindings and remove all of the attributes from the inputs other than type and v-model:
<button #click="swapInputFields">Swap</button>
<input type="text" v-model="fromCity"><br>
<input type="text" v-model="toCity">
You only need those model variables fromCity and toCity in your data:
data() {
return {
fromCity:'FROM',
toCity :'TO'
}
},
And swap them like this:
swapInputFields()
{
const temp = this.fromCity;
this.fromCity = this.toCity;
this.toCity = temp;
}
Here is a demo:
new Vue({
el: "#app",
data(){
return {
fromCity:'FROM',
toCity :'TO'
}
},
methods: {
swapInputFields()
{
const temp = this.fromCity;
this.fromCity = this.toCity;
this.toCity = temp;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button #click="swapInputFields">Swap</button>
<input type="text" v-model="fromCity"><br>
<input type="text" v-model="toCity">
</div>

V-bind with dynamically rendered components

I have a simple code where I have got input fields for the user and the user can click on a button to render more input fields, and I want to store those input fields.
<div id='wordslist'>
<div class='announcement'>Voer hieronder uw woorden in</div>
<div class='wordsdiv'>
<div id='onedictspec' v-for='arrayspot in wordupload.wordcount'>
<input type='text' class='inputwordtext' v-model='arrayspot[wordupload.wordcount][0]'>
<input type='text' class='inputwordtext' v-model='arrayspot[wordupload.wordcount][1]'>
</div>
</div>
<div id='morewords'>
<button class='morewordsbtn active hover' v-on:click='morewords'>More words</button>
</div>
Vuejs
data{
wordupload: {
wordcount: 20,
wordinput: [],
}
}
methods: {
morewords: function () {
this.wordupload.wordcount += 30
}
}
In short it renderes wordupload.wordcount number of #wordsdiv, and I am tring to give the input of those wordsdiv a spot in the wordinput array. But I can't v-model their value to the spot if it doesn't exist. Any ideas on what would be the best way to store those dynamically rendered input values would be much appreciated.
Are you looking for something like this?
https://jsfiddle.net/2nn58fa8/1/
Vue.component('wordlist', {
data: function() {
return {
wordupload: {
wordcount: 20,
wordinput: [],
}
}
},
created: function() {
this.wordupload.wordinput.length = this.wordupload.wordcount;
},
methods: {
morewords: function() {
this.wordupload.wordcount += 30;
this.wordupload.wordinput.length = this.wordupload.wordcount;
},
checkwords: function() {
console.log(this.wordupload.wordinput);
}
}
});
var vue = new Vue({
el: '#app'
});

How to use an attribute selector with vue.js?

I would like to apply a computed style to an input form. The documentation explains how to do that, but only for simple styles.
I need to apply the equivalent of
input[type="text"], textarea {
background-color : red;
}
but it is not clear for me how to convey the [type="text"] bit.
Using it verbatim does not work:
var vm = new Vue({
el: "#root",
data: {
password: '',
},
computed: {
passwordStyle: function() {
var style = {}
style['input[type="text"]'] = 'red';
style['textarea'] = 'blue';
return style;
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script>
<div id="root>">
<input type="text" name="password" autofocus="true" v-bind:style='passwordStyle'>
</div>
You need to only pass the style, not the css selector, like:
var vm = new Vue({
el: "#root",
data: {
password: '',
},
computed: {
passwordStyle: function() {
return {
backgroundColor: 'red'
};
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script>
<div id="root">
<input type="text" name="password" autofocus="true" :style="passwordStyle">
</div>
Can you explain your use-case little bit elaborately, use of v-bind:style is when you want to dynamically change the style of some element, depending on some variable, as it is in docs, following code with change the CSS depending on isActive and hasError variable:
<div class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
data: {
isActive: true,
hasError: false
}
I don't see in your code you are changing style based on any variable.

Categories