66 <v-card-text >
77
88 <div v-for =" (field, i) in fields" :key =" i" >
9-
10- <!-- text field: input / number / decimal / date / time / datetime -->
11- <v-text-field
12- hide-details
13- :rules =" fieldRules(field)"
14- v-if =" ['input', 'number', 'decimal', 'date', 'time', 'datetime'].includes(field.type)"
15- :label =" field.text"
16- v-model =" field.value"
17- :disabled =" field.disabled"
18- :type =" ['number', 'decimal'].includes(field.type) ? 'number' : 'text'"
19- :step =" field.type == 'decimal' ? 0.01 : 1"
20- min =" 0"
21- :mask =" ['date', 'time', 'datetime'].includes(field.type) ? masks[field.type] : undefined"
22- :return-masked-value =" ['date', 'time', 'datetime'].includes(field.type) ? true : false"
23- ></v-text-field >
24-
25- <!-- text area -->
26- <v-textarea
27- hide-details
28- :rules =" fieldRules(field)"
29- v-else-if =" field.type == 'textarea'"
30- :label =" field.text"
31- v-model =" field.value"
32- :disabled =" field.disabled"
33- ></v-textarea >
34-
35- <!-- file upload -->
36- <div v-else-if =" field.type == 'file'" class =" file-container" >
37- <div class =" field-label" >{{ field.text }}</div >
38- <v-btn dark class =" jbtn-file" :loading =" uploadLoaders[field.name]" :class =" fileUploadBtn(uploadStatuses[field.name])" >
39- {{ $t('global.details.files.upload') }}
40- <v-icon dark right >
41- {{ fileUploadIcon(uploadStatuses[field.name]) }}
42- </v-icon >
43- <input
44- :id =" field.name"
45- type =" file"
46- @change =" fileSelected($event, field)"
47- accept =" *"
48- :multiple =" false"
49- :disabled =" field.disabled"
50- ref =" fileInput"
51- >
52- </v-btn >
53- </div >
54-
55- <!-- select -->
56- <template v-else-if =" field .type == ' select' " >
57- <v-autocomplete
58- v-if =" field.async"
59- hide-details
60- :rules =" fieldRules(field)"
61- :loading =" searchLoading['search_' + field.name]"
62- :items =" searchData['search_' + field.name]"
63- v-model =" field.value"
64- :search-input.sync =" searchPhrases['search_' + field.name]"
65- flat
66- :item-text =" field.list.text"
67- :item-value =" field.list.value"
68- item-disabled =" itemDisabled"
69- :label =" field.text"
70- menu-props =" bottom"
71- :disabled =" field.disabled"
72- ></v-autocomplete >
73- <v-autocomplete
74- v-else
75- hide-details
76- :rules =" fieldRules(field)"
77- :items =" field.list.data"
78- v-model =" field.value"
79- :item-text =" field.list.text"
80- :item-value =" field.list.value"
81- item-disabled =" itemDisabled"
82- :label =" field.text"
83- menu-props =" bottom"
84- :disabled =" field.disabled"
85- ></v-autocomplete >
86- </template >
87-
88- <!-- date picker -->
89- <v-menu
90- v-else-if =" field.type == 'datePicker'"
91- lazy
92- :close-on-content-click =" true"
93- v-model =" field.show"
94- transition =" scale-transition"
95- offset-y
96- full-width
97- :nudge-right =" 40"
98- min-width =" 290px"
99- :return-value.sync =" field.value"
100- :disabled =" field.disabled"
101- >
102- <v-text-field
103- hide-details
104- slot =" activator"
105- :label =" field.text"
106- v-model =" field.value"
107- prepend-icon =" event"
108- :disabled =" field.disabled"
109- ></v-text-field >
110- <v-date-picker v-model =" field.value" no-title scrollable ></v-date-picker >
111- </v-menu >
112-
113- <!-- rich text editor -->
114- <template v-else-if =" field .type == ' richTextBox' " >
115- <label >{{field.text}}</label >
116- <vue-editor
117- id =" editor"
118- v-model =" field.value"
119- :editorOptions =" {bounds: '#editor'}"
120- :disabled =" field.disabled"
121- ></vue-editor >
122- <br >
123- </template >
124-
125- <!-- checkbox -->
126- <v-checkbox v-else-if =" field.type == 'checkbox'"
127- hide-details
128- color =" primary"
129- v-model =" field.value"
130- :label =" field.text"
131- :disabled =" field.disabled"
132- ></v-checkbox >
133-
9+ <field
10+ :field =" field"
11+ :fieldValue =" field.value"
12+ :reload =" reload"
13+ @valueChanged =" valueChanged"
14+ ></field >
13415 </div >
13516 </v-card-text >
13617 <v-card-actions >
14425 </v-dialog >
14526</template >
14627<script >
147- import Vue from ' vue'
148- import { VueEditor } from ' vue2-editor'
28+ import Field from ' ./Field.vue'
14929import { fieldModifiers } from ' @/utils/crud/helpers/functions'
15030
15131export default {
15232 components: {
153- VueEditor
33+ Field
15434 },
15535 props: {
15636 details: Object ,
15737 fieldsInfo: Array
15838 },
15939 data () {
16040 return {
161- searchPhrases: {},
162- searchLoading: {},
163- searchData: {},
41+ fields: [],
16442 masks: {
16543 date: ' ####-##-##' ,
16644 time: ' ##:##' ,
16745 datetime: ' ####-##-## ##:##:##'
16846 },
47+ reload: false ,
16948 customFilter (item , queryText , itemText ) {
17049 const hasValue = val => (val != null ? val : ' ' )
17150 const text = hasValue (item .name )
@@ -179,79 +58,10 @@ export default {
17958 }
18059 }
18160 },
182- created () {
183- for (const field of this .fields ) {
184- if (field .type === ' select' ) {
185- const { url } = field
186- if (field .async ) {
187- this .$set (this .searchPhrases , ` search_${ field .name } ` , ' ' )
188- this .$set (this .searchLoading , ` search_${ field .name } ` , false )
189- this .$set (this .searchData , ` search_${ field .name } ` , [])
190- this .$set (field .list , ' oldSearch' , ' ' )
191- } else {
192- field .list .data = []
193- let selectItems
194- Vue .http .get (url).then ((response ) => {
195- const items = response .body
196- selectItems = items .map ((item ) => {
197- const rItem = item
198- if (typeof field .list .activeColumn !== ' undefined' ) {
199- rItem .itemDisabled = parseInt (item[field .list .activeColumn ]) === 0
200- }
201- if (typeof field .list .complexName !== ' undefined' ) {
202- const textArray = field .list .complexName .map ((textInfo ) => {
203- const splittedText = textInfo
204- .split (' .' )
205- .reduce ((object , property ) => object[property] || ' ' , item)
206- return splittedText
207- })
208- rItem .complexName = textArray .join (' , ' )
209- }
210- return rItem
211- })
212- if (! field .required ) {
213- const nullElement = {}
214- nullElement[field .list .value ] = ' '
215- nullElement[field .list .text ] = ' -'
216- field .list .data = [nullElement, ... selectItems]
217- } else {
218- field .list .data = selectItems
219- }
220- })
221- }
222- }
223- }
61+ mounted () {
62+ this .setFields ()
22463 },
22564 computed: {
226- fields () {
227- let filteredFields
228- filteredFields = this .fieldsInfo .filter (
229- field => field .details !== false && field .type !== ' divider'
230- )
231- const result = filteredFields .map ((field ) => {
232- const rField = field
233- rField .value = this .details .item [field .column ]
234- if (field .type === ' select' ) {
235- const defaultVal = field .list .default || 1
236- rField .value = field .stringId
237- ? this .details .item [field .column ]
238- : parseInt (this .details .item [field .column ]) || defaultVal
239- }
240- if (field .apiObject ) {
241- if (field .apiObject .useFunctionsInDetails ) {
242- const functions = field .apiObject .functions || []
243- const availableFunctions = fieldModifiers
244-
245- for (let i = 0 ; i < functions .length ; i++ ) {
246- const functionName = functions[i]
247- rField .value = availableFunctions[functionName](rField .value )
248- }
249- }
250- }
251- return rField
252- })
253- return result
254- },
25565 itemData () {
25666 const result = {}
25767 for (const field of this .fields ) {
@@ -266,82 +76,66 @@ export default {
26676 input: [v => !! v || self .$t (' global.details.rules.required' )],
26777 required : v => !! v || self .$t (' global.details.rules.required' )
26878 }
79+ },
80+ detailsShow () {
81+ return this .details .show
26982 }
27083 },
27184 watch: {
272- details: {
273- handler (val ) {
274- if (val .show === true && val .action === ' edit' ) {
275- for (const field of this .fields ) {
276- if (field .type === ' select' ) {
277- if (field .async ) {
278- field .list .oldSearch = ' '
279- let data
280- const url = ` ${ field .url } /id/${ field .value } `
281- Vue .http .get (url).then ((response ) => {
282- const items = response .body
283- if (typeof field .list .complexName !== ' undefined' ) {
284- data = items .map ((item ) => {
285- const rItem = item
286- const textArray = field .list .complexName .map ((textInfo ) => {
287- const splittedText = textInfo
288- .split (' .' )
289- .reduce ((object , property ) => object[property] || ' ' , item)
290- return splittedText
291- })
292- rItem .complexName = textArray .join (' , ' )
293- return rItem
294- })
295- } else {
296- data = items
297- }
298- this .$set (this .searchData , ` search_${ field .name } ` , data)
299- })
300- }
301- }
302- }
85+ detailsShow : function (val ) {
86+ if (val) {
87+ this .setFields ()
88+ this .reload = true
89+ setTimeout (() => {
90+ this .reload = false
91+ }, 100 )
92+ }
93+ }
94+ },
95+ methods: {
96+ setFields () {
97+ let filteredFields
98+ filteredFields = this .fieldsInfo .filter (
99+ field => field .details !== false && field .type !== ' divider'
100+ )
101+ const result = filteredFields .map ((field ) => {
102+ const rField = field
103+ let show = true
104+ if (this .details .action === ' create' ) {
105+ show = field .create !== false
303106 }
304- },
305- deep: true
306- },
307- searchPhrases: {
308- handler (val ) {
309- for (const field of this .fields ) {
107+ rField .show = show
108+ rField .value = this .details .item [field .column ]
109+ if (typeof rField .value !== ' undefined' ) {
310110 if (field .type === ' select' ) {
311- if (field .async ) {
312- if (val[` search_${ field .name } ` ] !== undefined ) {
313- const url = ` ${ field .url } /phrase/${ val[` search_${ field .name } ` ]} `
314- this .$set (this .searchLoading , ` search_${ field .name } ` , true )
315- Vue .http .get (url).then ((response ) => {
316- this .$set (this .searchLoading , ` search_${ field .name } ` , false )
317- const items = response .body
318- let data
319- if (typeof field .list .complexName !== ' undefined' ) {
320- data = items .map ((item ) => {
321- const rItem = item
322- const textArray = field .list .complexName .map ((textInfo ) => {
323- const splittedText = textInfo
324- .split (' .' )
325- .reduce ((object , property ) => object[property] || ' ' , item)
326- return splittedText
327- })
328- rItem .complexName = textArray .join (' , ' )
329- return rItem
330- })
331- } else {
332- data = items
333- }
334- this .$set (this .searchData , ` search_${ field .name } ` , data)
335- })
111+ const defaultVal = field .list .default || 1
112+ rField .value = field .stringId ? this .details .item [field .column ] : parseInt (this .details .item [field .column ]) || defaultVal
113+ } else if (field .type === ' datePicker' ) {
114+ rField .value = this .details .item [field .column ].substring (0 , 10 )
115+ } else if (field .type === ' checkbox' ) {
116+ rField .value = parseInt (this .details .item [field .column ]) === 1
117+ }
118+ if (field .apiObject ) {
119+ if (field .apiObject .useFunctionsInDetails ) {
120+ const functions = field .apiObject .functions || []
121+ const availableFunctions = fieldModifiers
122+
123+ for (let i = 0 ; i < functions .length ; i++ ) {
124+ const functionName = functions[i]
125+ rField .value = availableFunctions[functionName](rField .value )
336126 }
337127 }
338128 }
129+ } else if (field .type === ' checkbox' ) {
130+ rField .value = false
339131 }
340- },
341- deep: true
342- }
343- },
344- methods: {
132+ return rField
133+ })
134+ this .$set (this , ' fields' , result)
135+ },
136+ valueChanged (val , fieldColumn ) {
137+ this .$set (this .fields [this .fields .findIndex (el => el .column === fieldColumn)], ' value' , val)
138+ },
345139 fieldRules (field ) {
346140 const rules = []
347141 const required = field .required !== undefined ? field .required : true
0 commit comments