parsley/app/javascript/components/TheCalculator.vue

107 lines
3.0 KiB
Vue

<template>
<div>
<h1 class="title">Calculator</h1>
<div class="box">
<div class="columns">
<app-text-field label="Input" v-model="input" class="column" :validation-error="inputErrors"></app-text-field>
<app-text-field label="Output Unit" v-model="outputUnit" class="column" :validation-error="outputUnitErrors"></app-text-field>
</div>
<div class="columns">
<div class="field column">
<label class="label">Ingredient</label>
<div class="control">
<app-autocomplete
:inputClass="{'is-success': ingredient !== null}"
ref="autocomplete"
v-model="ingredient_name"
:minLength="2"
valueAttribute="name"
labelAttribute="name"
placeholder=""
@optionSelected="searchItemSelected"
:onGetOptions="updateSearchItems"
>
</app-autocomplete>
</div>
</div>
<app-text-field label="Density" v-model="density" class="column" :disabled="ingredient !== null" :validation-error="densityErrors"></app-text-field>
</div>
<app-text-field label="Output" v-model="output" disabled></app-text-field>
</div>
</div>
</template>
<script setup>
import { computed, ref, watch } from "vue";
import api from "../lib/Api";
import debounce from "lodash/debounce";
import { useLoadResource } from "../lib/useLoadResource";
const { loadResource } = useLoadResource();
const input = ref("");
const outputUnit = ref("");
const ingredient_name = ref("");
const ingredient = ref(null);
const density = ref("");
const output = ref("");
const errors = ref({});
const inputErrors = computed(() => getErrors("input"));
const outputUnitErrors = computed(() => getErrors("output_unit"));
const densityErrors = computed(() => getErrors("density"));
const updateOutput = debounce(function() {
if (input.value && input.value.length > 0) {
loadResource(api.getCalculate(input.value, outputUnit.value, ingredient.value ? ingredient.value.ingredient_id : null, density.value)
.then(data => {
output.value = data.output;
errors.value = data.errors;
})
);
}
}, 500);
watch(ingredient_name, function(val) {
if (ingredient.value && ingredient.value.name !== val) {
ingredient.value = null;
}
});
watch(
[input, outputUnit, density, ingredient],
() => updateOutput()
);
function updateSearchItems(text) {
return api.getSearchIngredients(text);
}
function searchItemSelected(ingredient) {
ingredient.value = ingredient || null;
ingredient_name.value = ingredient.name || null;
density.value = ingredient.density || null;
}
function getErrors(type) {
if (errors.value[type] && errors.value[type].length > 0) {
return errors.value[type].join(", ");
} else {
return null;
}
}
</script>
<style lang="scss" scoped>
</style>