SelectExtSearchDialog.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <template>
  2. <Dialog ref="dialog" v-model="dialogVisible">
  3. <template #header>
  4. <div class="row items-center">
  5. <div style="font-size: 110%">
  6. Расширенный поиск
  7. </div>
  8. </div>
  9. </template>
  10. <div ref="box" class="column q-mt-xs overflow-auto" style="max-width: 660px; padding: 0px 10px 10px 10px;">
  11. <div class="row">
  12. <div v-for="f in recStruct" :key="f.field" class="row">
  13. <div class="q-mx-xs" />
  14. <q-input
  15. v-model="search[f.field]" :maxlength="5000"
  16. class="q-mt-xs" style="width: 150px;" :label="`(${f.type}) ${f.field}`"
  17. :bg-color="bgColor[f.field] || 'white'"
  18. stack-label outlined dense clearable
  19. @keypress="onKeyPress"
  20. >
  21. <q-tooltip v-if="search[f.field]" :delay="500" anchor="bottom middle" content-style="font-size: 80%" max-width="400px">
  22. {{ search[f.field] }}
  23. </q-tooltip>
  24. </q-input>
  25. </div>
  26. </div>
  27. <div class="row q-mt-xs q-ml-sm" style="color: red" v-html="error" />
  28. </div>
  29. <template #footer>
  30. <q-btn class="q-px-md q-ml-sm" color="primary" dense no-caps :disabled="error !== ''" @click="apply">
  31. Применить
  32. </q-btn>
  33. </template>
  34. </Dialog>
  35. </template>
  36. <script>
  37. //-----------------------------------------------------------------------------
  38. import vueComponent from '../../vueComponent.js';
  39. import Dialog from '../../share/Dialog.vue';
  40. import _ from 'lodash';
  41. const componentOptions = {
  42. components: {
  43. Dialog
  44. },
  45. watch: {
  46. modelValue(newValue) {
  47. this.dialogVisible = newValue;
  48. },
  49. dialogVisible(newValue) {
  50. this.$emit('update:modelValue', newValue);
  51. },
  52. extSearch: {
  53. handler(newValue) {
  54. this.search = _.cloneDeep(newValue);
  55. },
  56. deep: true,
  57. },
  58. search: {
  59. handler() {
  60. this.validate();
  61. },
  62. deep: true,
  63. },
  64. }
  65. };
  66. class SelectExtSearchDialog {
  67. _options = componentOptions;
  68. _props = {
  69. modelValue: Boolean,
  70. extSearch: Object,
  71. };
  72. dialogVisible = false;
  73. search = {};
  74. bgColor = {};
  75. error = '';
  76. created() {
  77. this.commit = this.$store.commit;
  78. }
  79. mounted() {
  80. }
  81. get config() {
  82. return this.$store.state.config;
  83. }
  84. get recStruct() {
  85. if (this.config.dbConfig && this.config.dbConfig.inpxInfo.recStruct)
  86. return this.config.dbConfig.inpxInfo.recStruct;
  87. else
  88. return [];
  89. }
  90. validate() {
  91. const validNumValue = (n) => {
  92. const validChars = new Set('0123456789.'.split(''));
  93. for (const c of n.split(''))
  94. if (!validChars.has(c))
  95. return false;
  96. const v = n.split('..');
  97. if ( isNaN(parseInt(v[0] || '0', 10)) || isNaN(parseInt(v[1] || '0', 10)) )
  98. return false;
  99. return true;
  100. };
  101. let error = [];
  102. const s = this.search;
  103. for (const f of this.recStruct) {
  104. if (f.type == 'N' && s[f.field] && !validNumValue(s[f.field])) {
  105. error.push(`Недопустимое значение поля ${f.field}`);
  106. this.bgColor[f.field] = 'red-2';
  107. } else {
  108. this.bgColor[f.field] = '';//default
  109. }
  110. }
  111. this.error = error.join('<br>');
  112. }
  113. onKeyPress(event) {
  114. if (event.code == 'Enter')
  115. this.apply();
  116. }
  117. apply() {
  118. this.validate();
  119. if (!this.error) {
  120. this.$emit('update:extSearch', _.cloneDeep(this.search));
  121. this.dialogVisible = false;
  122. }
  123. }
  124. }
  125. export default vueComponent(SelectExtSearchDialog);
  126. //-----------------------------------------------------------------------------
  127. </script>
  128. <style scoped>
  129. </style>