I wonder how I can select a specific element in the DOM using VueJS with our without jquery
In my component I have a method function that does this:
$(".u-loc input").focusin(function() {
$(".u-loc-icon").addClass('blue-active');
});
The only problem is that its generated dynamic, so I could have 1 or 10 different which means I need to have a uniqe selector to each one.
So I have added :ref="'u-loc' + index"
Which means that I can now target the element using $(this.$refs['u-loc' + index]);
But I dont know how I can chain the selector to look something like this:
$(this.$refs['u-loc' + index]).('input').focusin(function() {
$(this.$refs['u-loc' + index]).addClass('blue-active');
});
The problem is that I need to select the elements [input]
If a ref attribute is added to an HTML element in your Vue template, you'll then be able to reference that element or even a child element in your Vue instance. You can also access the DOM element directly; it is a read-only attribute and returns an object.
querySelector in Vue We can use querySelector to select an HTML element that returns the first element within the document that matches a specified selector. It can be used to set, obtain, modify, or delete properties of the selected element in Vue.
If we want to reference a DOM element, we can use the ref attribute in Vue. Vue can store references to DOM elements in a property called $ref . The first thing we have to do, is add a ref attribute to the element we want to reference in our Javascript.
You're making things very fragile with this approach. A quick fix for you would be to handle it like this.
<div class="input-container">
<input @focusin="addParentClass" @focusout="removeParentClass">
</div>
Then have:
methods: {
addParentClass (event) {
event.target
.closest('.input-container')
.classList.add('blue-active')
},
removeParentClass (event) {
event.target
.closest('.input-container')
.classList.add('blue-active')
},
},
However, for the long term, you should look into breaking these into components. That way you can do something like:
<div :class="[containerClasses]">
<input @focusout="isFocused = false" @focusin="isFocused = true">
</div>
Then have a computed property like:
computed: {
containerClasses () {
return {
'input-container': true,
'blue-active': this.isFocused,
}
},
},
If I understand correctly what you are trying to accomplish then I think you're going wrong about it. I would add a vue.js event (focus) to all input elements:
<input @focus="onFocus" />
then I would define the onFocus method/event handler for the focus event on my Vue model:
methods: {
onFocus: function (e) {
var element = this.$el;
var children = this.$el.childNodes;
}
}
As you can see you can now get to the event envoking element via this.$el. Furthermore you can get to any child elements via this.$el.childNodes.
Remember Vue is data driven so the view should reflect an underlying data model. In general you should not be injecting anything in to the DOM unless you have a specific reason to do so. In your case, what it looks like you want to di is highlight the input on focus by adding a class, so, we could have an array of input objects that have an active
property:
new Vue({
el: '#app',
methods:{
setActive(index){
this.inputs[index].active = true;
},
removeActive(index){
this.inputs[index].active = false;
}
},
data: {
inputs: [
{value: 'foo', active: false},
{value: 'bar', active: false}
]
}
})
Now in your template you can use v-for
to print all the inputs:
<div v-for="(input, index) in inputs">
<input v-model="input.value" @focusin="setActive(index)" @focusout="removeActive(index)" :class="{'blue-active' : input.active}"/>
</div>
You may notice that I'm attaching an event listener directly to each input (@focusin
and @focusout
), which calls a method that sets the active
flag to true
and fals
e respectively for the given input (I've done that in a pretty verbose way for demonstrative purposes), I'm then using Vue's class binding to add and remove the blue-active
class based on that flag.
And here's the final result: https://jsfiddle.net/mooxo19v/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With