SelectExtSearchDialog.vue 4.0 KB

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