Foundation for order entry
This commit is contained in:
154
htdocs/ViewOrderableLookup.vue
Normal file
154
htdocs/ViewOrderableLookup.vue
Normal file
@@ -0,0 +1,154 @@
|
||||
<template>
|
||||
<div class="input-group">
|
||||
<span v-if="label" class="input-group-text">{{label}}</span>
|
||||
<select v-if="selectable_xref" class="form-select" style="flex: 0.15 1 auto;" v-model="x_xref">
|
||||
<option v-for="item in ORDERABLE_XREF" :value="item.xref">{{item.name}}</option>
|
||||
</select>
|
||||
<input class="form-control" placeholder="Filter..." v-model="x_query" />
|
||||
</div>
|
||||
<div class="scroller" ref="scroller">
|
||||
<table class="table table-striped">
|
||||
<tbody>
|
||||
<tr v-for="item in resultset" :class="{ 'table-active': item.IEN == x_modelValue }" @click="x_modelValue = item.IEN">
|
||||
<td>{{item.IEN}}</td>
|
||||
<td>{{item.synonym}}</td>
|
||||
</tr>
|
||||
<tr ref="bottom" />
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
div.scroller {
|
||||
max-height: 25vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
td {
|
||||
cursor: default;
|
||||
}
|
||||
.table-active, .table-active:nth-of-type(odd) > * {
|
||||
color: #fff;
|
||||
background-color: #0d6efd;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import { debounce } from './util.mjs';
|
||||
|
||||
import { ORDERABLE_XREF } from './constants.mjs';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
client: Object,
|
||||
xref: String,
|
||||
label: String,
|
||||
query: String,
|
||||
qocall: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
modelValue: String
|
||||
},
|
||||
emits: {
|
||||
'update:xref': String,
|
||||
'update:query': String,
|
||||
'update:modelValue': String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ORDERABLE_XREF,
|
||||
selectable_xref: !this.xref,
|
||||
x_xref: this.xref || 'S.O RX',
|
||||
x_query: this.query,
|
||||
resultset: [],
|
||||
has_more: false,
|
||||
is_loading: true,
|
||||
observer_bottom: null,
|
||||
x_modelValue: this.modelValue
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
query_view() {
|
||||
return this.x_query ? this.x_query.replace(/^\s+|\s+$/g, '').replace(/\s+/g, ' ').toUpperCase() : '';
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
xref(value) { this.x_xref = value; },
|
||||
x_xref(value) {
|
||||
this.$emit('update:xref', value);
|
||||
this.$emit('update:query', this.x_query = '');
|
||||
},
|
||||
modelValue(value) { this.x_modelValue = value; },
|
||||
x_modelValue(value) { this.$emit('update:modelValue', value); },
|
||||
query(value) { this.x_query = value; },
|
||||
x_query(value) {
|
||||
this.$emit('update:query', value);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async handle_bottom([entry]) {
|
||||
if((entry.isIntersecting) && (this.has_more) && (!this.is_loading)) {
|
||||
this.is_loading = true;
|
||||
this.has_more = false;
|
||||
try {
|
||||
var batch = await this.client.ORWDX_ORDITM(this.resultset[this.resultset.length - 1].synonym, 1, this.x_xref, this.qocall);
|
||||
if(this.query_view.length >= 3) batch = batch.filter(x => x.synonym.startsWith(this.query_view));
|
||||
if(batch.length > 0) {
|
||||
Array.prototype.push.apply(this.resultset, batch);
|
||||
this.has_more = true;
|
||||
} else this.has_more = false;
|
||||
} catch(ex) {
|
||||
this.has_more = false;
|
||||
} finally {
|
||||
this.is_loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$watch(
|
||||
() => (this.client, this.modelValue, {}),
|
||||
async () => {
|
||||
if((this.client) && (!this.x_query) && (this.modelValue) && (this.modelValue == parseInt(this.modelValue))) {
|
||||
var item = await this.client.ORWDLR32_LOAD(this.modelValue);
|
||||
this.x_query = item['Test Name'].default;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
this.$watch(
|
||||
() => (this.client, this.xref, this.query_view, this.qocall, {}),
|
||||
debounce(async function() {
|
||||
if((this.client) && (this.xref)) {
|
||||
this.is_loading = true;
|
||||
this.has_more = false;
|
||||
try {
|
||||
var query = this.query_view;
|
||||
if(query.length >= 3) {
|
||||
var batch = await this.client.ORWDX_ORDITM(query.slice(0, -1) + String.fromCharCode(query.charCodeAt(query.length - 1) - 1), 1, this.xref, this.qocall);
|
||||
this.resultset = batch.filter(x => x.synonym.startsWith(query));
|
||||
if((this.resultset.length > 0) && ((this.resultset[0].name == query) || (this.resultset[0].synonym == query))) this.x_modelValue = this.resultset[0].IEN;
|
||||
} else this.resultset = await this.client.ORWDX_ORDITM('', 1, this.xref, this.qocall);
|
||||
this.has_more = this.resultset.length > 0;
|
||||
} catch(ex) {
|
||||
this.resultset = [];
|
||||
this.has_more = false;
|
||||
} finally {
|
||||
this.is_loading = false;
|
||||
this.$refs.scroller.scrollTo(0, 0);
|
||||
}
|
||||
}
|
||||
}, 500),
|
||||
{ immediate: true }
|
||||
);
|
||||
},
|
||||
mounted() {
|
||||
this.observer_bottom = new IntersectionObserver(this.handle_bottom, { root: this.$refs.scroller, rootMargin: '25%' });
|
||||
this.observer_bottom.observe(this.$refs.bottom);
|
||||
},
|
||||
destroyed() {
|
||||
if(this.observer_bottom) this.observer_bottom.disconnect();
|
||||
}
|
||||
};
|
||||
</script>
|
Reference in New Issue
Block a user