Search code examples
javascriptjqueryformsvue.jsgeocomplete

geocomplete with Vue js -- location being erased


I'm trying to use jQuery geocomplete along with Vue.js to populate a form with geo data.

My code contains this form:

<form>
    <label for="get-offer-location">location: </label><input id="get-offer-location" v-model="newoffer.location" type="text"/>
    <div style="visibility:hidden">
        <input name="lat" type="text" value=""/>
        <input name="lng" type="text" value=""/>
    </div>
</form>

After I click on a suggested location from the get-offer-location input, it looks like the field is filled out -- but then when I start typing in another field, the location input field reverts to just the letters I typed in for the location search. Try it out here by clicking "post", then "news" or "offers": https://jsfiddle.net/dvdgdnjsph/157w6tk8/

Can anyone tell me what's wrong?


Solution

  • The problem you are having is that v-model binds on input, since the geolocation dropdown is a plugin that changes the value programatically the input event is not fired, so v-model is not updated. As a case, try typing a space after selecting a location, you will see that it sticks.

    Fortunately, v-model is nothing more than syntactic sugar for v-on:input, so you can use v-on to fire your event instead. Considering that you are going to need to unfocus to get out of the box, the blur event is likely to be your best option, so you can simply do:

    v-on:blur="newarticle.location = $event.target.value"
    

    Unfortunately, JSFiddle won't let me save or update your Fiddle, but I did get it working with the code above.

    For completeness, in case you want to use this behavior extensively, and because the Vue docs are fairly limited in this regard, you may write a custom directive to encapsulate the code:

    Vue.directive('model-blur', {
      bind: function(el, binding, vnode) {
        el.addEventListener('blur', function() {
          vnode.context[binding.expression] = el.value;
        });
      }
    });
    

    Then you can use like so:

    <input v-model-blur="myVar" />
    

    Here's the JSFiddle: https://jsfiddle.net/4vp6Lvmc/