<!DOCTYPE html>
<html>
<head>
<script data-require="vue.js@10.0.26" data-semver="10.0.26" src="https://vuejs.org/js/vue.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="https://cdn.jsdelivr.net/npm/vue-resource@1.5.1"></script>
<script src="https://unpkg.com/http-vue-loader"></script>
<script src="v-autocomplete.js"></script>
<script src="script.js"></script>
</head>
<body onload="init()">
<div id="overlay">
<div id="text">Espera</div>
</div>
<div id="app">
<div>
por calle:
<autocomplete :options="options"
@select="onOptionSelect"
:filter="filterCalle"
>
<template slot="item" slot-scope="itemProps">
<article class="media" v-bind:value="itemProps.element._id">
<strong>{{ itemProps.element.calle }}</strong>
</article>
</template>
</autocomplete>
</div>
<div>
por RFC:
<autocomplete :options="options"
@select="onOptionSelect"
:filter="filterRfc"
>
<template slot="item" slot-scope="itemProps">
<article class="media" v-bind:value="itemProps.element._id">
<strong>{{ itemProps.element.rfc }}</strong>
</article>
</template>
</autocomplete>
</div>
</div>
</body>
</html>
// Code goes here
function init() {
httpVueLoader.register(Vue, 'v-autocomplete.vue');
new Vue({
el: "#app",
data: {
options: [ ],
url: 'https://api.datos.gob.mx/v1/precio.gasolina.publico?pageSize=1000',
actuales: []
},
mounted: function() {
// GET /someUrl
this.$http.get(this.url).then(
function(data) {
// get body data
//console.log('%s', JSON.stringify(data.body.results));
this.options = data.body.results;
document.getElementById("overlay").style.display = "none";
},
function(data) {
alert('Fallamos :S');
}
);
},
methods: {
compareValues: function(key, order = 'asc') {
return function innerSort(a, b) {
if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
return 0;
}
const varA = (typeof a[key] === 'string')
? a[key].toUpperCase() : a[key];
const varB = (typeof b[key] === 'string')
? b[key].toUpperCase() : b[key];
let comparison = 0;
if (varA > varB) {
comparison = 1;
} else if (varA < varB) {
comparison = -1;
}
console.log('%s <> %s : %s', varA, varB, comparison );
return (
(order === 'desc') ? (comparison * -1) : comparison
);
};
},
filterCalle: function(kw, ops) {
const re = new RegExp(kw, 'i');
return ops.filter(o =>
o.calle
.toLowerCase()
.startsWith( kw.toLowerCase() )
).sort( this.compareValues('calle') );
},
filterRfc: function(kw, ops) {
const re = new RegExp(kw, 'i');
return ops.filter(o =>
o.rfc
.toLowerCase()
.startsWith( kw.toLowerCase() )
).sort( this.compareValues('rfc') );
},
onOptionSelect: function() {
}
}
});
}
/* Styles go here */
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
input {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
}
.autocomplete-input {
position: absolute;
height: 300px;
}
ul.options-list {
display: flex;
flex-direction: column;
margin-top: -12px;
border: 1px solid #dbdbdb;
border-radius: 0 0 3px 3px;
position: relative;
width: 100%;
overflow: auto;
max-height: 200px;
}
ul.options-list li {
width: 100%;
flex-wrap: wrap;
background: white;
margin: 0;
border-bottom: 1px solid #eee;
color: #363636;
padding: 7px;
cursor: pointer;
}
ul.options-list li.highlighted {
background: #f8f8f8
}
/* ul.options-list { */
/* display: flex; */
/* flex-direction: column; */
/* border: 1px solid #dbdbdb; */
/* border-radius: 0 0 3px 3px; */
/* position: relative; /*absolute;*/ */
/* width: 100%; */
/* overflow: scroll; /*hidden;*/ */
/* list-style-type: none; */
/* margin: 0; */
/* padding: 0; */
/* margin-top: -12px; */
/* } */
/* ul.options-list li { */
/* width: 100%; */
/* flex-wrap: wrap; */
/* background: white; */
/* margin: 0; */
/* border-bottom: 1px solid #eee; */
/* color: #363636; */
/* padding: 7px; */
/* cursor: pointer; */
/* } */
/* ul.options-list li.highlighted { */
/* background: #f8f8f8 */
/* } */
html, body{
min-height: 100%;
}
body{
position: relative;
}
#overlay{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 10;
background-color: rgba(0,0,0,0.5); /*dim the background*/
}
#text{
position: absolute;
top: 50%;
left: 50%;
font-size: 50px;
color: white;
transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
}
// Definir un nuevo componente llamado button-counter
Vue.component('autocomplete', {
props: {
options: {
type: Array,
required: true
},
filter: {
type: Function,
required: true
}
},
data () {
return {
isOpen: false,
highlightedPosition: 0,
keyword: ''
}
},
//mixins: [app.mixins.input],
computed: {
fOptions () {
if(this.keyword) {
return this.filter(this.keyword, this.options);
} else {
return [];
}
}
},
methods: {
compareValues (key, order = 'asc') {
return function innerSort(a, b) {
if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
return 0;
}
const varA = (typeof a[key] === 'string')
? a[key].toUpperCase() : a[key];
const varB = (typeof b[key] === 'string')
? b[key].toUpperCase() : b[key];
let comparison = 0;
if (varA > varB) {
comparison = 1;
} else if (varA < varB) {
comparison = -1;
}
return (
(order === 'desc') ? (comparison * -1) : comparison
);
};
},
onInput (value) {
this.highlightedPosition = 0
this.isOpen = !!value
},
moveDown () {
if (!this.isOpen) {
return
}
this.highlightedPosition =
(this.highlightedPosition + 1) % this.fOptions.length
},
moveUp () {
if (!this.isOpen) {
return
}
this.highlightedPosition = this.highlightedPosition - 1 < 0
? this.fOptions.length - 1
: this.highlightedPosition - 1
},
select () {
const selectedOption = this.fOptions[this.highlightedPosition]
this.$emit('select', selectedOption)
this.isOpen = false
this.keyword = selectedOption.nombre
},
onBlur() {
this.isOpen = false
this.keyword = ''
//alert("This input field has lost its focus.");
//this.focusedIndex = null
// this.$emit('blur', event);
}
},
template: `
<div class="autocomplete">
<p class="control has-icon has-icon-right">
<input v-model="keyword"
class="col-sm-7"
placeholder="Buscar..."
@input="onInput($event.target.value)"
@keyup.esc="isOpen = false"
@keydown.down="moveDown"
@keydown.up="moveUp"
@blur="onBlur()"
@keydown.enter="select">
<i class="fa fa-angle-down"></i>
</p>
<ul v-show="isOpen"
class="options-list">
<li v-for="(option, index) in fOptions"
:class="{
'highlighted': index === highlightedPosition
}"
@mouseenter="highlightedPosition = index"
@mousedown="select"
>
<slot name="item" v-bind:element="option">
</slot>
</li>
</ul>
</div>
`
});