forked from rc/aircox
radiocampus: style update
This commit is contained in:
193
radiocampus/assets/src/components/AFormSet.vue
Normal file
193
radiocampus/assets/src/components/AFormSet.vue
Normal file
@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<div>
|
||||
<input type="hidden" :name="_prefix + 'TOTAL_FORMS'" :value="items.length || 0"/>
|
||||
<template v-for="(value,name) in formData.management" v-bind:key="name">
|
||||
<input type="hidden" :name="_prefix + name.toUpperCase()"
|
||||
:value="value"/>
|
||||
</template>
|
||||
|
||||
<a-rows ref="rows" :set="set" :context="this"
|
||||
:columns="visibleFields" :columnsOrderable="columnsOrderable"
|
||||
:orderable="orderable" @move="moveItem" @colmove="onColumnMove"
|
||||
@cell="e => $emit('cell', e)">
|
||||
|
||||
<template #header-head>
|
||||
<template v-if="orderable">
|
||||
<th style="max-width:2em" :title="orderField.label"
|
||||
:aria-label="orderField.label"
|
||||
:aria-description="orderField.help || ''">
|
||||
<span class="icon">
|
||||
<i class="fa fa-arrow-down-1-9"></i>
|
||||
</span>
|
||||
</th>
|
||||
<slot name="rows-header-head"></slot>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template #row-head="data">
|
||||
<input v-if="orderable" type="hidden"
|
||||
:name="_prefix + data.row + '-' + orderBy"
|
||||
:value="data.row"/>
|
||||
<input type="hidden" :name="_prefix + data.row + '-id'"
|
||||
:value="data.item ? data.item.id : ''"/>
|
||||
|
||||
<template v-for="field of hiddenFields" v-bind:key="field.name">
|
||||
<input type="hidden"
|
||||
v-if="!(field.name in ['id', orderBy])"
|
||||
:name="_prefix + data.row + '-' + field.name"
|
||||
:value="field.value in [null, undefined] ? data.item.data[name] : field.value"/>
|
||||
</template>
|
||||
|
||||
<slot name="row-head" v-bind="data">
|
||||
<td v-if="orderable">{{ data.row+1 }}</td>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<template v-for="(field,slot) of fieldSlots" v-bind:key="field.name"
|
||||
v-slot:[slot]="data">
|
||||
<slot :name="slot" v-bind="data" :field="field" :input-name="_prefix + data.cell.row + '-' + field.name">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<slot :name="'control-' + field.name" v-bind="data" :field="field" :input-name="_prefix + data.cell.row + '-' + field.name"/>
|
||||
</div>
|
||||
<p v-for="[error,index] in data.item.error(field.name)" class="help is-danger" v-bind:key="index">
|
||||
{{ error }}
|
||||
</p>
|
||||
</div>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<template #row-tail="data">
|
||||
<slot v-if="$slots['row-tail']" name="row-tail" v-bind="data"/>
|
||||
<td class="align-right pr-0">
|
||||
<button type="button" class="button square"
|
||||
@click.stop="removeItem(data.row, data.item)"
|
||||
:title="labels.remove_item"
|
||||
:aria-label="labels.remove_item">
|
||||
<span class="icon"><i class="fa fa-trash" /></span>
|
||||
</button>
|
||||
</td>
|
||||
</template>
|
||||
</a-rows>
|
||||
<div class="a-formset-footer flex-row">
|
||||
<div class="flex-grow-1 flex-row">
|
||||
<slot name="footer"/>
|
||||
</div>
|
||||
<div class="flex-grow-1 align-right">
|
||||
<button type="button" class="button square is-warning p-2"
|
||||
@click="reset()"
|
||||
:title="labels.discard_changes"
|
||||
:aria-label="labels.discard_changes"
|
||||
>
|
||||
<span class="icon"><i class="fa fa-rotate" /></span>
|
||||
</button>
|
||||
<button type="button" class="button square is-primary p-2"
|
||||
@click="onActionAdd"
|
||||
:title="labels.add_item"
|
||||
:aria-label="labels.add_item"
|
||||
>
|
||||
<span class="icon">
|
||||
<i class="fa fa-plus"/></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {cloneDeep} from 'lodash'
|
||||
import Model, {Set} from '../model'
|
||||
|
||||
import ARows from './ARows'
|
||||
|
||||
export default {
|
||||
emit: ['cell', 'move', 'colmove', 'load'],
|
||||
components: {ARows},
|
||||
|
||||
props: {
|
||||
labels: Object,
|
||||
|
||||
//! If provided call this function instead of adding an item to rows on "+" button click.
|
||||
actionAdd: Function,
|
||||
|
||||
//! If True, columns can be reordered
|
||||
columnsOrderable: Boolean,
|
||||
//! Field name used for ordering
|
||||
orderBy: String,
|
||||
|
||||
//! Formset data as returned by get_formset_data
|
||||
formData: Object,
|
||||
//! Model class used for item's set
|
||||
model: {type: Function, default: Model},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
set: new Set(Model),
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
// ---- fields
|
||||
_prefix() { return this.formData.prefix ? this.formData.prefix + '-' : '' },
|
||||
fields() { return this.formData.fields },
|
||||
orderField() { return this.orderBy && this.fields.find(f => f.name == this.orderBy) },
|
||||
orderable() { return !!this.orderField },
|
||||
|
||||
hiddenFields() { return this.fields.filter(f => f.hidden && !(this.orderable && f == this.orderField)) },
|
||||
visibleFields() { return this.fields.filter(f => !f.hidden) },
|
||||
|
||||
fieldSlots() { return this.visibleFields.reduce(
|
||||
(slots, f) => ({...slots, ['row-' + f.name]: f}),
|
||||
{}
|
||||
)},
|
||||
|
||||
items() { return this.set.items },
|
||||
rows() { return this.$refs.rows },
|
||||
},
|
||||
|
||||
methods: {
|
||||
onCellEvent(event) { this.$emit('cell', event) },
|
||||
onColumnMove(event) { this.$emit('colmove', event) },
|
||||
onActionAdd() {
|
||||
if(this.actionAdd)
|
||||
return this.actionAdd(this)
|
||||
this.set.push()
|
||||
},
|
||||
|
||||
moveItem(event) {
|
||||
const {from, to} = event
|
||||
const set_ = event.set || this.set
|
||||
set_.move(from, to);
|
||||
this.$emit('move', {...event, seŧ: set_})
|
||||
},
|
||||
|
||||
removeItem(row) {
|
||||
const item = this.items[row]
|
||||
if(item.id) {
|
||||
// TODO
|
||||
}
|
||||
else {
|
||||
this.items.splice(row,1)
|
||||
}
|
||||
},
|
||||
|
||||
//! Load items into set
|
||||
load(items=[], reset=false) {
|
||||
if(reset)
|
||||
this.set.items = []
|
||||
for(var item of items)
|
||||
this.set.push(cloneDeep(item))
|
||||
this.$emit('load', items)
|
||||
},
|
||||
|
||||
//! Reset forms to initials
|
||||
reset() {
|
||||
this.load(this.formData?.initials || [], true)
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.reset()
|
||||
}
|
||||
}
|
||||
</script>
|
Reference in New Issue
Block a user