MultiSearchWidget.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. <template>
  2. <div class="content">
  3. <div class="form-group">
  4. <!-- <label v-show="isVisible[0]" class="col-xs-5 col-sm-4 col-md-3 col-lg-2 control-label">
  5. <span class="required-mark" v-if="field.mandatory">*</span>{{labelNames[0]}}
  6. </label> -->
  7. <div
  8. v-show="isVisible[0]"
  9. style="position:relative; padding-left: 0px;"
  10. class="col-xs-12 col-sm-12 col-md-12 col-lg-12"
  11. >
  12. <div class="input-group">
  13. <!-- <input :aria-describedby="'addon' + field.id" type="text" class="form-control" v-model="searchText" @input="textChange($event)" :readonly="readonly"/> -->
  14. <!-- <span @click="showSearchDialog" class="input-group-addon" :id="'addon' + field.id" :disabled="readonly">
  15. <span class="glyphicon glyphicon-search"></span>
  16. </span> -->
  17. <div
  18. class="box"
  19. :class="{'div-readonly':readonly}"
  20. >
  21. <span
  22. v-for="(item) in selectDatas"
  23. :key="item.id"
  24. class="selected-tag"
  25. >
  26. {{ item.text }}
  27. <button
  28. v-if="!readonly"
  29. type="button"
  30. class="close"
  31. aria-label="Remove option"
  32. @click="deleteRecord(item)"
  33. >
  34. <span aria-hidden="true">&times;</span>
  35. </button>
  36. </span>
  37. <span
  38. class="glyphicon glyphicon-search search-icon"
  39. @click="showSearchDialog"
  40. />
  41. </div>
  42. <Modal
  43. ref="modal"
  44. :full="true"
  45. @ok="searchDialogOk"
  46. @cancel="searchDialogCancel"
  47. >
  48. <template #default>
  49. <info
  50. ref="info"
  51. :info-window-no="infoWindowNo"
  52. @data-selected="dataSelected"
  53. />
  54. </template>
  55. <template #header>
  56. <div>
  57. {{ field.name }}
  58. </div>
  59. </template>
  60. </Modal>
  61. </div>
  62. <div
  63. v-show="isShowAuto"
  64. class="div-autoComplete"
  65. >
  66. <table class="table-bordered table-hover">
  67. <thead>
  68. <tr>
  69. <td
  70. v-for="item in infoWindowDto.infoGridFields"
  71. :key="'td-' + item.fieldName"
  72. align="center"
  73. width="100px"
  74. >
  75. {{ item.name }}
  76. </td>
  77. </tr>
  78. </thead>
  79. <tbody>
  80. <tr
  81. v-for="item1 in infoWindowData.dataList"
  82. :key="'row-data-' + item1.id"
  83. height="40px"
  84. @click="selectNode(item1)"
  85. >
  86. <td
  87. v-for="item2 in infoWindowDto.infoGridFields"
  88. :key="'row-column-data-' + item1.id + '-' + item2.fieldName"
  89. align="center"
  90. >
  91. {{ item1.data[item2.fieldName].displayValue[0] }}
  92. </td>
  93. </tr>
  94. </tbody>
  95. </table>
  96. </div>
  97. </div>
  98. </div>
  99. <div
  100. v-for="(titleName, index) in titleNames"
  101. v-show="isVisible[index]"
  102. :key="titleName + '-' + index"
  103. :class="{'form-group' : index > 0}"
  104. >
  105. <label
  106. v-if="index > 0"
  107. class="col-xs-5 col-sm-4 col-md-3 col-lg-2 control-label"
  108. >
  109. <span
  110. v-if="field.mandatory"
  111. class="required-mark"
  112. >*</span>{{ titleName }}
  113. </label>
  114. <div
  115. v-if="index > 0"
  116. class="col-xs-7 col-sm-8 col-md-9 col-lg-10"
  117. >
  118. <input
  119. type="text"
  120. class="form-control"
  121. :value="getFieldStringValue(index)"
  122. disabled
  123. />
  124. </div>
  125. </div>
  126. </div>
  127. </template>
  128. <script>
  129. var Modal = require('../../modal/src/Modal.vue').default;
  130. var Info = require('../../info/src/InfoWindow.vue').default;
  131. var Common = require('../../common/Common.js').default;
  132. export default {
  133. components: {
  134. Modal, Info,
  135. },
  136. props: {
  137. 'infoWindowNo':{
  138. type: String,
  139. default: null,
  140. },
  141. 'field':{
  142. type: Object,
  143. default: null,
  144. },
  145. 'fieldValue':{
  146. type: Object,
  147. default: null,
  148. },
  149. 'readonly':{
  150. type: Boolean,
  151. default: false,
  152. },
  153. },
  154. emits: [ 'getData', 'valueChanged'],
  155. data: function () {
  156. return {
  157. isVisible: [],
  158. infoWindowDto: {},
  159. infoWindowData: {},
  160. isShowAuto: false,
  161. searchText: '',
  162. selectDatas: [],
  163. };
  164. },
  165. computed: {
  166. titleNames: function () {
  167. if (this.field == null && this.field.displayName == null) {
  168. return '';
  169. } else {
  170. let labelNames = this.field.displayName.split(',');
  171. return labelNames;
  172. }
  173. },
  174. },
  175. watch: {
  176. infoWindowData: function (val) {
  177. var _self = this;
  178. if (val.dataList != undefined && val.dataList.length > 0) {
  179. _self.isShowAuto = true;
  180. } else {
  181. _self.isShowAuto = false;
  182. }
  183. },
  184. },
  185. mounted: function () {
  186. this.getInfoWindowDto();
  187. },
  188. methods: {
  189. // 显示搜索对话框
  190. showSearchDialog: function () {
  191. var _self = this;
  192. if (this.readonly) {
  193. return;
  194. }
  195. _self.$refs.modal.showModal();
  196. _self.$nextTick(function () {
  197. _self.$refs.modal.showModal();
  198. if (this.$refs.info) {
  199. _self.$refs.info.refresh();
  200. }
  201. });
  202. },
  203. searchDialogOk: function () {
  204. },
  205. searchDialogCancel: function () {
  206. },
  207. // 输入的文本发生改变
  208. textChange: function (e) {
  209. var _self = this;
  210. var text = _self.searchText;
  211. // if(text == undefined || text.length == 0){
  212. // var newFieldValue = {
  213. // id : {},
  214. // displayValue: [],
  215. // fieldType: 'Key'
  216. // }
  217. // this.$emit("valueChanged", newFieldValue);
  218. // }
  219. if (text.trim() != '') {
  220. _self.getInfoWindowData(text);
  221. } else {
  222. _self.isShowAuto = false;
  223. }
  224. },
  225. /**
  226. * 查询InfoWindowDto
  227. * @return {void}
  228. */
  229. getInfoWindowDto: function () {
  230. var _self = this;
  231. $.ajax({
  232. url: Common.getApiURL('InfoWindowResource/uniqueByNo'),
  233. type: 'GET',
  234. dataType: 'json',
  235. data: { 'infoWindowNo': _self.infoWindowNo },
  236. beforeSend: function (request) {
  237. Common.addTokenToRequest(request);
  238. },
  239. success: function (data) {
  240. _self.infoWindowDto = data;
  241. },
  242. error: function (XMLHttpRequest, textStatus, errorThrown) {
  243. Common.processException(XMLHttpRequest, textStatus, errorThrown);
  244. },
  245. });
  246. },
  247. /**
  248. * 查询infoWindowData
  249. * @return {void}
  250. */
  251. getInfoWindowData: function (text) {
  252. var _self = this;
  253. var infoQueryParam = {
  254. infoWindowNo: _self.infoWindowNo,
  255. start: 0,
  256. length: 5,
  257. sortClause: '',
  258. condition: text,
  259. };
  260. $.ajax({
  261. url: Common.getApiURL('InfoWindowResource/queryInfoWindowDataSimple'),
  262. type: 'post',
  263. dataType: 'json',
  264. beforeSend: function (request) {
  265. Common.addTokenToRequest(request);
  266. },
  267. contentType: 'application/json',
  268. data: JSON.stringify(infoQueryParam),
  269. success: function (data) {
  270. _self.infoWindowData = data;
  271. },
  272. error: function (XMLHttpRequest, textStatus, errorThrown) {
  273. Common.processException(XMLHttpRequest, textStatus, errorThrown);
  274. },
  275. });
  276. },
  277. /**
  278. * 选择数据(自动提示框)
  279. * @return {void}
  280. */
  281. selectNode: function (data) {
  282. var _self = this;
  283. _self.isShowAuto = false;
  284. _self.dataSelected(data);
  285. },
  286. deleteRecord: function (selectData) {
  287. var _self = this;
  288. var index = _self.selectDatas.indexOf(selectData);
  289. if (index > -1) {
  290. _self.selectDatas.splice(index, 1);
  291. _self.getSelectDataIds();
  292. }
  293. },
  294. // 数据已经选择
  295. dataSelected: function (data) {
  296. var _self = this;
  297. var index = _self.selectDatas.indexOf(data);
  298. if (index > -1) {
  299. return;
  300. }
  301. if (this.$refs.modal != undefined) {
  302. this.$refs.modal.hideModal();
  303. }
  304. _self.$refs.modal.hideModal();
  305. var text = [];
  306. var listDisplayFieldNames = this.field.listDisplayFieldNames;
  307. var displayValues = listDisplayFieldNames.split(',');
  308. for (var i = 0; i < displayValues.length; i++) {
  309. var fieldValue = data.data[displayValues[i]];
  310. if (fieldValue != undefined && fieldValue.displayValue != undefined) {
  311. text[i] = fieldValue.displayValue[0];
  312. } else {
  313. text[i] = '';
  314. }
  315. }
  316. data.text = text[0];
  317. _self.selectDatas.push(data);
  318. /*var selectDataIds = [];
  319. _self.selectDatas.forEach(function(item){
  320. selectDataIds.push(item.id);
  321. })
  322. var newFieldValue = {
  323. displayValue: selectDataIds,
  324. fieldType: 'MultiSearchBoxEditor'
  325. }
  326. this.$emit("valueChanged", newFieldValue);*/
  327. _self.getSelectDataIds();
  328. this.$emit('getData', data);
  329. },
  330. getSelectDataIds: function () {
  331. var _self = this;
  332. var selectDataIds = [];
  333. _self.selectDatas.forEach(function (item) {
  334. selectDataIds.push(item.id);
  335. });
  336. var newFieldValue = {
  337. displayValue: selectDataIds,
  338. fieldType: 'MultiSearchBoxEditor',
  339. };
  340. this.$emit('valueChanged', newFieldValue);
  341. },
  342. // 获取String字符串
  343. getFieldStringValue: function (index) {
  344. if (this.fieldValue == undefined || this.fieldValue.displayValue == undefined || this.fieldValue.displayValue.length < index) {
  345. return '';
  346. } else {
  347. return this.fieldValue.displayValue[index];
  348. }
  349. },
  350. },
  351. };
  352. </script>
  353. <style scoped>
  354. .required-mark {
  355. color: red;
  356. margin-right: 10px;
  357. }
  358. .div-autoComplete {
  359. position: absolute;
  360. z-index: 99;
  361. background-color: #fff;
  362. border: 1px #e5e5e5 solid;
  363. padding: 0px 15px 15px 15px;
  364. box-shadow: 0 0 5px rgba(81, 203, 238, 1);
  365. }
  366. .box {
  367. width: 200px;
  368. min-height: 34px;
  369. border: 1px solid rgba(60, 60, 60, 0.26);
  370. border-radius: 4px;
  371. white-space: normal;
  372. transition: border-radius 0.25s;
  373. background-color: #ffffff;
  374. position: relative;
  375. }
  376. .div-readonly {
  377. background-color: #eee !important;
  378. }
  379. .close {
  380. float: none;
  381. margin-right: 0;
  382. font-size: 20px;
  383. appearance: none;
  384. padding: 0;
  385. cursor: pointer;
  386. background: 0 0;
  387. border: 0;
  388. font-weight: 700;
  389. line-height: 1;
  390. color: #000;
  391. text-shadow: 0 1px 0 #fff;
  392. filter: alpha(opacity=20);
  393. opacity: 0.2;
  394. }
  395. .selected-tag {
  396. color: #333;
  397. background-color: #f0f0f0;
  398. border: 1px solid #ccc;
  399. border-radius: 4px;
  400. height: 26px;
  401. margin: 4px 1px 0px 3px;
  402. padding: 3px 0.25em;
  403. line-height: 34px;
  404. }
  405. .search-icon {
  406. position: absolute;
  407. top: 9px;
  408. right: 7px;
  409. }
  410. .content {
  411. display: inline-block !important;
  412. }
  413. /*.img-box {
  414. width: 60px;
  415. float: left;
  416. text-align: center;
  417. margin-right: 20px;
  418. }
  419. .img-box div img{
  420. width: 60px;
  421. height: 60px;
  422. }
  423. .add-box {
  424. width: 60px;
  425. height: 60px;
  426. float: left;
  427. border-radius: 30px;
  428. border: 1px #999 dashed;
  429. text-align: center;
  430. margin-top: 20px;
  431. }
  432. .add-box:hover {
  433. cursor: pointer;
  434. background-color: #ccc;
  435. }
  436. .add-icon {
  437. width: 60px;
  438. height: 60px;
  439. color: #aaa;
  440. font-size: 40px;
  441. line-height: 60px;
  442. position: relative;
  443. top: -1px;
  444. }
  445. .remove-icon {
  446. color: red;
  447. position: relative;
  448. top: 10px;
  449. right: -30px;
  450. cursor: pointer;
  451. }*/
  452. </style>