|
1 | 1 | <script>
|
2 | 2 | Vue.component('apijson-table', {
|
3 | 3 | delimiters: ['{', '}'],
|
4 |
| - props: ["table_name","config","func_init","func_change_params"], |
| 4 | + props: [ |
| 5 | + "table_name", |
| 6 | + "config", |
| 7 | + "custom_tcolumns_render_generator", |
| 8 | + "hook_init", |
| 9 | + "hook_ajax_params" |
| 10 | + ], |
5 | 11 | template: `<div>
|
6 | 12 | <div v-if="config_editable && config_add_fields!=null"><i-button type="primary" @click="add">Add</i-button> <br><br> </div>
|
7 | 13 | <Spin size="large" fix v-if="loading"></Spin>
|
|
10 | 16 | <modal v-model="modal_add" title="Add">
|
11 | 17 | <i-form @submit.native.prevent :label-width="80">
|
12 | 18 | <form-item v-for="item in add_items" :key="item.key" :label="item.title">
|
13 |
| - <i-input v-if="item.type=='input'" v-model="item.value"></i-input> |
14 |
| - <checkbox v-if="item.type=='checkbox'" v-model="item.value"></checkbox> |
15 |
| - <i-input v-if="item.type=='textarea'" v-model="item.value" type="textarea" :autosize="{minRows: 2,maxRows: 5}"></i-input> |
| 19 | + <i-input v-if="item.component=='input'" v-model="item.value"></i-input> |
| 20 | + <checkbox v-if="item.component=='checkbox'" v-model="item.value"></checkbox> |
| 21 | + <i-input v-if="item.component=='textarea'" v-model="item.value" type="textarea" :autosize="{minRows: 2,maxRows: 5}"></i-input> |
16 | 22 | </form-item>
|
17 | 23 | <form-item v-if="config_editable" label="action">
|
18 |
| - <i-button type="info" icon="plus" @click="real_add">Add</i-button> |
| 24 | + <i-button type="info" icon="plus" size="large" @click="real_add">Add</i-button> |
19 | 25 | </form-item>
|
20 | 26 | </i-form>
|
| 27 | + <div slot="footer"> |
| 28 | + <i-button type="default" size="large" @click="modal_add=false">Cancel</i-button> |
| 29 | + </div> |
21 | 30 | </modal>
|
22 | 31 | <modal v-model="modal_view" :title="viewedit_label">
|
23 | 32 | <i-form @submit.native.prevent :label-width="80">
|
24 | 33 | <form-item v-for="item in viewedit_items" :key="item.key" :label="item.title">
|
25 |
| - <i-input v-if="item.type=='input'" v-model="item.value" :readonly="!editable(item)"></i-input> |
26 |
| - <checkbox v-if="item.type=='checkbox'" v-model="item.value" :disabled="!editable(item)"></checkbox> |
27 |
| - <i-input v-if="item.type=='textarea'" v-model="item.value" type="textarea" :autosize="{minRows: 2,maxRows: 5}"></i-input> |
| 34 | + <i-input v-if="item.component=='input'" v-model="item.value" :readonly="!editable(item)"></i-input> |
| 35 | + <checkbox v-if="item.component=='checkbox'" v-model="item.value" :disabled="!editable(item)"></checkbox> |
| 36 | + <i-input v-if="item.component=='textarea'" v-model="item.value" type="textarea" :autosize="{minRows: 2,maxRows: 5}"></i-input> |
28 | 37 | </form-item>
|
29 | 38 | <form-item v-if="config_editable" label="action">
|
30 |
| - <i-button type="info" icon="ios-download" @click="save">Save</i-button> |
| 39 | + <i-button type="info" icon="ios-download" size="large" @click="save">Save</i-button> |
31 | 40 | </form-item>
|
32 | 41 | </i-form>
|
| 42 | + <div slot="footer"> |
| 43 | + <i-button type="default" size="large" @click="modal_view=false">Cancel</i-button> |
| 44 | + </div> |
33 | 45 | </modal>
|
34 | 46 | <modal v-model="modal_delete" title="Confirm to delete" @on-ok="real_remove">
|
35 | 47 | <p>Confirm to delete #{delete_params.row&&delete_params.row.id} in table '{table_name}'?</p>
|
|
91 | 103 | }
|
92 | 104 | }
|
93 | 105 | },
|
| 106 | + tcolumns_render_generator: { |
| 107 | + checkbox: function(key) { |
| 108 | + var render_func = function(h,params){ |
| 109 | + var row = params.row |
| 110 | + return h('Icon',{ |
| 111 | + attrs:{ |
| 112 | + type: row[key]?"ios-checkmark":"ios-checkmark-outline", |
| 113 | + color: row[key]?"#2d8cf0":"#bbbec4", |
| 114 | + size: "25" |
| 115 | + }, |
| 116 | + }) |
| 117 | + } |
| 118 | + return render_func |
| 119 | + } |
| 120 | + }, |
94 | 121 | tcolumns_init: false,
|
95 | 122 | tlist:[],
|
96 |
| - query_count: 10, |
| 123 | + query_count: thisp.config ? (thisp.config.default_page_size || 10) : 10, |
97 | 124 | current_page: 1,
|
98 | 125 | total: 0,
|
99 | 126 | sort_key: "id",
|
|
109 | 136 | viewedit_label: function(){return this.config_editable?'Edit':'View'}
|
110 | 137 | },
|
111 | 138 | methods: {
|
| 139 | + tcolumns_custom_render(){ |
| 140 | + for (var k in this.tcolumns) { |
| 141 | + var c = this.tcolumns[k] |
| 142 | + if (c.component!=null) { |
| 143 | + var g = null |
| 144 | + if (this.custom_tcolumns_render_generator!=null) { |
| 145 | + g = this.custom_tcolumns_render_generator[c.component] |
| 146 | + } |
| 147 | + if (g==null) { |
| 148 | + g = this.tcolumns_render_generator[c.component] |
| 149 | + } |
| 150 | + if (g!=null){ |
| 151 | + c.render = g(c.key) |
| 152 | + } |
| 153 | + } |
| 154 | + } |
| 155 | + }, |
| 156 | + ajax_hook: function(method,action,params) { |
| 157 | + if (this.hook_ajax_params!=null) { |
| 158 | + var after_hook = this.hook_ajax_params(method,action,params) |
| 159 | + if (after_hook!=null) { |
| 160 | + params = after_hook |
| 161 | + } |
| 162 | + else { |
| 163 | + console.log("warning: hook_ajax_params('"+method+"','"+action+"',params) return null, so ignore this hook") |
| 164 | + } |
| 165 | + } |
| 166 | + return params |
| 167 | + }, |
112 | 168 | update_list: function(){
|
113 | 169 | var thisp = this
|
114 | 170 | var arr_params = {
|
|
124 | 180 | "[]":arr_params,
|
125 | 181 | "total@":"/[]/total"
|
126 | 182 | }
|
127 |
| - if (thisp.func_change_params!=null) { |
128 |
| - params = thisp.func_change_params("apijson_get",params) |
129 |
| - } |
| 183 | + params = thisp.ajax_hook("apijson_get","list",params) |
130 | 184 | thisp.loading = true
|
131 | 185 | $.ajax({
|
132 | 186 | type: "POST",
|
|
141 | 195 | if (thisp.config_table_fields!=null){
|
142 | 196 | thisp.tcolumns = thisp.config_table_fields
|
143 | 197 | thisp.tcolumns.push(thisp.tcolumns_preset["action"])
|
| 198 | + thisp.tcolumns_custom_render() |
144 | 199 | thisp.tcolumns_init = true
|
145 | 200 | }
|
146 | 201 | else {
|
|
160 | 215 | }
|
161 | 216 | }
|
162 | 217 | thisp.tcolumns.push(thisp.tcolumns_preset["action"])
|
| 218 | + thisp.tcolumns_custom_render() |
163 | 219 | thisp.tcolumns_init = true
|
164 | 220 | }
|
165 | 221 | }
|
166 | 222 | }
|
167 | 223 | thisp.tlist = arr
|
168 | 224 | thisp.total = data.total
|
169 | 225 | }
|
| 226 | + else { |
| 227 | + thisp.$Notice.error({ |
| 228 | + title: 'error when get table '+thisp.table_name, |
| 229 | + desc: data.msg |
| 230 | + }) |
| 231 | + } |
170 | 232 | }
|
171 | 233 | })
|
172 | 234 | },
|
|
177 | 239 | for (var i in this.config_viewedit_fields) {
|
178 | 240 | var d = this.config_viewedit_fields[i]
|
179 | 241 | d.value = row[d.key]
|
180 |
| - d.type = d.type || "input" |
| 242 | + d.component = d.component || "input" |
181 | 243 | this.viewedit_items.push(d)
|
182 | 244 | }
|
183 | 245 | }
|
184 | 246 | else {
|
185 |
| - this.viewedit_items.push({title:"id",value:row.id,"type":"input"}) |
186 |
| - var type2type = { |
| 247 | + this.viewedit_items.push({title:"id",value:row.id,component:"input"}) |
| 248 | + var type2comp = { |
187 | 249 | "boolean":"checkbox"
|
188 | 250 | }
|
189 | 251 | for (var k in row){
|
190 | 252 | if (k!="id" && k[0]!="_") {
|
191 | 253 | var value = row[k]
|
192 |
| - var type = type2type[typeof value] || "input" |
193 |
| - this.viewedit_items.push({title:k,value:value,type:type}) |
| 254 | + var comp = type2comp[typeof value] || "input" |
| 255 | + this.viewedit_items.push({title:k,value:value,component:comp}) |
194 | 256 | }
|
195 | 257 | }
|
196 | 258 | }
|
|
226 | 288 | }
|
227 | 289 | }
|
228 | 290 | params[thisp.table_name] = record_params
|
229 |
| - if (thisp.func_change_params!=null) { |
230 |
| - params = thisp.func_change_params("apijson_put",params) |
231 |
| - } |
| 291 | + params = thisp.ajax_hook("apijson_put","update",params) |
232 | 292 | $.ajax({
|
233 | 293 | type: "POST",
|
234 | 294 | url: "{{=url_for('uliweb_apijson.apijson.views.ApiJson.put')}}",
|
|
253 | 313 | })
|
254 | 314 | },
|
255 | 315 | real_remove: function(){
|
| 316 | + if (this.config_delete_set_deleted) { |
| 317 | + this.real_remove_set_deleted() |
| 318 | + } |
| 319 | + else { |
| 320 | + this.real_remove_delete() |
| 321 | + } |
| 322 | + }, |
| 323 | + real_remove_set_deleted: function(){ |
| 324 | + var thisp = this |
| 325 | + var params = { |
| 326 | + "@tag": thisp.table_name |
| 327 | + } |
| 328 | + var params_table = { |
| 329 | + "id": thisp.delete_params.row.id, |
| 330 | + } |
| 331 | + params_table[this.config_deleted_field_name] = true |
| 332 | + params[thisp.table_name] = params_table |
| 333 | + |
| 334 | + params = thisp.ajax_hook("apijson_put","delete",params) |
| 335 | + |
| 336 | + $.ajax({ |
| 337 | + type: "POST", |
| 338 | + url: "{{=url_for('uliweb_apijson.apijson.views.ApiJson.put')}}", |
| 339 | + contentType: 'application/json', |
| 340 | + data: JSON.stringify(params), |
| 341 | + success: function (data) { |
| 342 | + if (data.code!=200){ |
| 343 | + thisp.$Notice.error({ |
| 344 | + title: 'error when remove #'+thisp.delete_params.row.id+' in table '+thisp.table_name, |
| 345 | + desc: data.msg |
| 346 | + }) |
| 347 | + return |
| 348 | + } |
| 349 | + var result = data[thisp.table_name] |
| 350 | + if (result.code!=200){ |
| 351 | + thisp.$Notice.error({ |
| 352 | + title: 'error when remove #'+thisp.delete_params.row.id+' in table '+thisp.table_name, |
| 353 | + desc: result.msg |
| 354 | + }) |
| 355 | + return |
| 356 | + } |
| 357 | + thisp.$Notice.success({ |
| 358 | + title: 'success remove #'+thisp.delete_params.row.id+' in table '+thisp.table_name, |
| 359 | + desc: result.msg |
| 360 | + }) |
| 361 | + thisp.update_list() |
| 362 | + } |
| 363 | + }) |
| 364 | + }, |
| 365 | + real_remove_delete: function(){ |
256 | 366 | var thisp = this
|
257 | 367 | var params = {
|
258 | 368 | "@tag": thisp.table_name
|
259 | 369 | }
|
260 | 370 | params[thisp.table_name] = {
|
261 | 371 | "id": thisp.delete_params.row.id
|
262 | 372 | }
|
263 |
| - if (thisp.func_change_params!=null) { |
264 |
| - params = thisp.func_change_params("apijson_delete",params) |
265 |
| - } |
| 373 | + params = thisp.ajax_hook("apijson_delete","delete",params) |
266 | 374 | $.ajax({
|
267 | 375 | type: "POST",
|
268 | 376 | url: "{{=url_for('uliweb_apijson.apijson.views.ApiJson.delete')}}",
|
|
296 | 404 | for (var k in this.add_items){
|
297 | 405 | var d = this.add_items[k]
|
298 | 406 | d.value = null
|
| 407 | + d.component = d.component || "input" |
299 | 408 | }
|
300 | 409 | this.modal_add = true
|
301 | 410 | },
|
|
310 | 419 | post_params[d.key] = d.value
|
311 | 420 | }
|
312 | 421 | params[this.table_name] = post_params
|
313 |
| - if (thisp.func_change_params!=null) { |
314 |
| - params = thisp.func_change_params("apijson_post",params) |
315 |
| - } |
| 422 | + params = thisp.ajax_hook("apijson_post","add",params) |
316 | 423 | $.ajax({
|
317 | 424 | type: "POST",
|
318 | 425 | url: "{{=url_for('uliweb_apijson.apijson.views.ApiJson.post')}}",
|
|
354 | 461 | this.config_table_fields = this.config.table_fields || null
|
355 | 462 | this.config_viewedit_fields = this.config.viewedit_fields || null
|
356 | 463 | this.config_add_fields = this.config.add_fields || null
|
357 |
| - if (this.config.add_fields!=null) { |
| 464 | + if (this.config_add_fields!=null) { |
358 | 465 | this.add_items = this.config_add_fields
|
359 | 466 | }
|
360 | 467 | if (this.config.default_page_size!=null) {
|
361 | 468 | this.query_count = this.config.default_page_size
|
362 | 469 | }
|
| 470 | + this.config_delete_set_deleted = this.config.delete_set_deleted || false |
| 471 | + this.config_deleted_field_name = this.config.deleted_field_name || "deleted" |
363 | 472 | }
|
364 |
| - if (this.func_init!=null) { |
365 |
| - this.func_init(this) |
| 473 | + //if not do this, the first notice will hide behind the navigation bar in uliweb apps |
| 474 | + this.$Notice.config({top: 100,duration: 8}); |
| 475 | + if (this.hook_init!=null) { |
| 476 | + this.hook_init(this) |
366 | 477 | }
|
367 | 478 | this.update_list()
|
368 | 479 | }
|
|
0 commit comments