Guspread is a Javascript Spreadsheet Component for Vue.
https://misu007.github.io/vue-guspread/
npm install vue-guspread
After installing, please register the component either globaly or localy you would like.
import VueGuspread from 'vue-guspread';
import 'vue-guspread/dist/vue-guspread.css';
Vue.use(VueGuspread);
import VGuspread from "vue-guspread";
export default {
components: {
VGuspread
}
}
<v-guspread></v-guspread>
tag will be available after loading the javascript library.
<link href="https://cdn.jsdelivr.net/npm/vue-guspread@latest/dist/vue-guspread.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-guspread@latest"></script>
<template>
<div style="width:100%;height:400px;">
<v-guspread v-model="dataset" :fields="fields"></v-guspread>
</div>
</template>
<script>
import VGuspread from "vue-guspread";
export default {
components: {
VGuspread
},
data: () => ({
fields: [
{ name: "c1", label: "A" },
{ name: "c2", label: "B" },
{ name: "c3", label: "C" }
],
dataset: [
{ c1: "blue", c2: "banana", c3: "sky" },
{ c1: "red", c2: "apple", c3: "river" },
{ c1: "orange", c2: "orange", c3: "mountain" },
{ c1: "white", c2: "rasberry", c3: "lake" }
]
})
};
</script>
<!DOCTYPE html>
<html>
<head>
<title>Guspread Sample</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui"/>
<link href="https://cdn.jsdelivr.net/npm/vue-guspread@latest/dist/vue-guspread.css" rel="stylesheet"/>
</head>
<body>
<div id="app">
<v-guspread v-model="dataset" :fields="fields"></v-guspread>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-guspread@latest"></script>
<script>
new Vue({
el: '#app',
data: {
fields: [
{ name: "c1", label: "A" },
{ name: "c2", label: "B" },
{ name: "c3", label: "C" }
],
dataset: [
{ c1: "blue", c2: "banana", c3: "sky" },
{ c1: "red", c2: "apple", c3: "river" },
{ c1: "orange", c2: "orange", c3: "mountain" },
{ c1: "white", c2: "raspberry", c3: "lake" }
]
}
});
</script>
</body>
</html>
<apex:page docType="html-5.0" applyHtmlTag="false" applyBodyTag="false" standardStylesheets="false" showHeader="false">
<html xmlns:v-bind="http://vue.org" xmlns:v-on="http://vue.org" xmlns:v-slot="http://vue.org">
<head>
<title>Guspread Sample For Visualforce</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui"/>
<link href="https://cdn.jsdelivr.net/npm/vue-guspread@latest/dist/vue-guspread.css" rel="stylesheet"/>
</head>
<body>
<div id="app">
<v-guspread v-model="dataset" v-bind:fields="fields"></v-guspread>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-guspread@latest"></script>
<script>
new Vue({
el: '#app',
data: {
fields: [
{ name: "c1", label: "A" },
{ name: "c2", label: "B" },
{ name: "c3", label: "C" }
],
dataset: [
{ c1: "blue", c2: "banana", c3: "sky" },
{ c1: "red", c2: "apple", c3: "river" },
{ c1: "orange", c2: "orange", c3: "mountain" },
{ c1: "white", c2: "raspberry", c3: "lake" }
]
}
});
</script>
</body>
</html>
</apex:page>
Required | Prop Name | Type | Description | Default |
---|---|---|---|---|
* | value (v-model) | Array | An array of row item objects | [] |
* | fields | Array | An array of column objects that each describe a header | [] |
color | String | Apply css color ('#ffffff' or rgb(65, 184, 131)) to the main controled color. | '#41b883' | |
nameKey | String | The value of this property represents the field key of each items | 'name' | |
labelKey | String | The value of this property represents the default label of each fields | 'label' | |
cellClass | Function | You can optionaly customize the classname for each cells | null | |
cellReadonly | Function | You can optionaly apply readonly behavior for each cells | null |
Event Name | Payload | Description |
---|---|---|
changeEditMode | True (Edit mode) or False (Show mode) | Fired when changed between edit mode and show mode |
changeFocused | {"a": Object, "b": Object} | Fired when changed the rect focued cells. Both keys "a" and "b" have row index and col index |
Slot Name | Slot Props | Description |
---|---|---|
field | {"field": Object} | "field": Each field Object given as "fields" prop |
cell | {"field": Object, "item": Object, "row": Number, "col": Number, "value": Any} | "item": Each row Object given as "value(v-model)" prop |
input | {"field": Object, "item": Object} |
<template>
<div style="width: 100%; height:600px;">
<v-guspread
v-model="dataset"
:fields="fields"
nameKey="apiName"
:cellClass="cellClass"
:cellReadonly="cellReadonly"
>
<!-- Each Field -->
<template #field="{field}">{{field.label}}</template>
<!-- Each Field -->
<!-- Each Cell -->
<template #cell="{field, item}">
<!-- Checkbox-->
<template v-if="field.dataType == 'Boolean'">
<template v-if="item[field.apiName] == true">✅</template>
<template v-else-if="item[field.apiName] == false">☐</template>
<template v-else></template>
</template>
<!-- Checkbox-->
<!-- Text-->
<template v-else>
<span>{{item[field.apiName]}}</span>
</template>
<!-- Text-->
</template>
<!-- Each Cell -->
<!-- Input Form -->
<template #input="{field, item}">
<!-- Checkbox -->
<template v-if="field.dataType == 'Boolean'">
<input type="checkbox" v-model="item[field.apiName]" />
</template>
<!-- Checkbox -->
<!-- Number-->
<template v-else-if="field.dataType == 'Int'">
<input type="number" v-model="item[field.apiName]" />
</template>
<!-- Number -->
<!-- Text -->
<template v-else>
<input type="text" v-model="item[field.apiName]" />
</template>
<!-- Text -->
</template>
<!-- Input Form -->
</v-guspread>
</div>
</template>
<script>
export default {
data: () => ({
fields: [
{ dataType: "Boolean", label: "Field1", apiName: "c1", updateable: true },
{ dataType: "Int", label: "Field2", apiName: "c2", updateable: true },
{ dataType: "String", label: "Field3", apiName: "c3", updateable: false },
{ dataType: "String", label: "Field4", apiName: "c4", updateable: true }
],
dataset: [
{ c1: true, c2: 58, c3: "Japan", c4: "Tokyo" },
{ c1: false, c2: 30, c3: "US", c4: "New York" },
{ c1: true, c2: 48, c3: "China", c4: "Beijing" },
{ c1: false, c2: 27, c3: "UK", c4: "London" },
{ c1: true, c2: 75, c3: "Korea", c4: "Seoul" }
],
cellClass: ({ field }) => {
let ret = [];
if (field.dataType == "Boolean" || field.dataType == "Int") {
ret.push("text-align-right");
}
return ret;
},
cellReadonly: ({ field }) => {
return !field.updateable;
}
})
};
</script>
<style lang="stylus">
.guspread-table {
.guspread-table-cell.text-align-right {
text-align: right;
}
}
</style>