Reputation: 755
When I use the combination of Materialize/jQuery and VueJS, to make a select, and then I try to select the desired value, VueJS isn't updated to reflect the new value that is selected.
I think this is a Materialize issue; however, I can't get the value to trigger an update/change event at all for VueJS.
What I have is in the snippet below. What I am looking to do is just have the select - or any select update VueJS properly when updated by jQuery.
It's starting to seem impossible, even though I know better.
$('select').material_select();
$(document).on('change', function(e){
$('#live').text("\n Using JUST jquery... Notice that the vue option remains unchanged\n" + JSON.stringify({ 'selectShouldBe': $(e.target).val()}, null, ' '));
});
new Vue({
el: '.container',
data: {
'select':''
},
methods: {
updateThing: function(){
console.log(this);
}
},
})
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.css">
</head>
<body>
<div class="container">
<!-- here is the select in question -->
<select id='jurisdiction' v-model='select' @change="updateThing">
<option value disabled selected>Please select a value.</option>
<option value='1'>One</option>
<option value='2'>Two</option>
<option value='3'>Three</option>
<option value='4'>Four</option>
</select>
<!-- Print out the data, then pass it through json for easier readability. -->
<pre>
{{$data|json}}
<div id="live"></div>
</pre>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.12/vue.min.js"></script>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.min.js">
</script>
</body>
</html>
Any suggestion?
Upvotes: 3
Views: 2601
Reputation: 2343
I had the problem of where my materialize select dropdown on the UI was not being updated with the value from the Vue model. Also, I could not clear a previous selection programmatically. But this code below works for me. The final trick was to use the Vue.nextTick(...) function.
The HTML:
<select id="fooField" v-model="myObject.foo" onchange="MyVueElement.fooChanged(this)">
<option value="" disabled selected>Choose...</option>
<option value="A">a</option>
<option value="B">b</option>
<option value="C">c</option>
</select>
And the JS for handling a new selection from the UI:
fooChanged: function(selectObject) {
this.myObject.foo = selectObject.value;
},
When I want to reset/clear the select/dropdown on the UI:
myObject.foo = ""; //setting this to null did not work
Vue.nextTick( function(){
$("#fooField").material_select();
});
Upvotes: 0
Reputation: 2299
How about separate vuejs from it?
If you can get the selection with jquery, then you can set the value to vue instance manually like:
var vm = new Vue({
el: '.container',
data: {
select: ''
}
});
$('select').material_select();
$('select').on('change', function(e){
vm.$set('select', ...)
});
Upvotes: 0
Reputation: 1075
I had a similar issue with materialize-css and vue js. After struggling with it for a while and inspecting the code with firebug i realized that everything was fine...except that I was calling the $('select').material_select();
at wrong place.
I was issuing the statement just like you at the top of my app.js file. The catch here is we need to issue this command when your Vue app is ready.
In my case, issuing the command in the ready function of the app did the trick.
var vm = new Vue({
el:"#app",
data: function() {
options: ["Clayton","Mt Meigs","Birmingham","Helena","Grant"]
},
ready: function() {
$('select').material_select();
}})
Make sure you include jQuery first, followed by materialize.js and Vue.js. Once those are included, use the code like above and it should work
I also see, that you are not using the Vue efficiently at the DOM level. You can use the Vue directives v-for to populate your select options like below:
<div class="input-field col s12 m5">
<select class="black-text">
<option value="" selected="">Source Location</option>
<option v-for="city in options" value="{{city}}">{{city}}</option>
</select>
</div>
Upvotes: 2
Reputation: 2467
While this may not be an ideal solution, it might get around the Materializecss overloading of the select element.
This basically stitches them together.
$('select').material_select();
$(document).on('change', function(e){
$('#live').text("\n Using JUST jquery... Notice that the vue option remains unchanged\n" + JSON.stringify({ 'selectShouldBe': $(e.target).val()}, null, ' '));
});
var myVue = new Vue({
el: '.container',
data: {
select:''
},
methods: {
updateThing: function(){
console.log(this);
}
},
});
$('#jurisdiction').change(function(){ myVue.$set('select', $('#jurisdiction').val()); });
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.css">
</head>
<body>
<div class="container">
<!-- here is the select in question -->
<select id='jurisdiction' v-model='select' @change="updateThing">
<option value disabled selected>Please select a value.</option>
<option value='1'>One</option>
<option value='2'>Two</option>
<option value='3'>Three</option>
<option value='4'>Four</option>
</select>
<!-- Print out the data, then pass it through json for easier readability. -->
<pre>
{{$data|json}}
<div id="live"></div>
</pre>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.12/vue.min.js"></script>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.min.js">
</script>
</body>
</html>
Upvotes: 0
Reputation: 25221
When I inspect the DOM after running your code, it looks like the Materialize library creates a new dropdown. The original dropdown, the one you attached the Vue listener to, is hidden. Then Materialize created a new, formatted dropdown. So when you update the value there, the original dropdown remains hidden and does not get updated. Because you did a document.on('change')
it is being picked up anyway, but I think if you did a $('#jurisdiction').on('change')
listener you'd find that it is never firing.
I will check out Materialize JS and see what I can find, it seems like you'll need to use the Materialize library to fire an event and update the Vue component.
Upvotes: 0