Created
December 1, 2024 22:48
-
-
Save busseyl/56a4c65461569f301e3618c073064cd2 to your computer and use it in GitHub Desktop.
VueJS 2 | VuetifyJS 2 | CDN | CSV | Data Form | HTML | Javascript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>CSV Data Form</title> | |
<link href="https://cdn.jsdelivr.net/npm/@mdi/font/css/materialdesignicons.css" rel="stylesheet"> | |
<link href="https://cdn.jsdelivr.net/npm/vuetify@2/dist/vuetify.min.css" rel="stylesheet"> | |
</head> | |
<body> | |
<div id="app"> | |
<v-app> | |
<v-progress-linear v-if="loading" indeterminate></v-progress-linear> | |
<v-navigation-drawer app v-if="items.length > 0"> | |
<v-btn block text @click="clearData">Clear Data</v-btn> | |
<v-select hide-details class="ma-2" v-model="selectedColumn" :items="columns" label="Select Title" outlined></v-select> | |
<div class="text-h6 pa-2">{{ items.length }} Row{{ items.length > 1 ? 's' : '' }}</div> | |
<v-divider></v-divider> | |
<v-list> | |
<v-list-item-group v-model="selectedItemIndex"> | |
<v-list-item v-for="(item, index) in items" :key="index" @click="updateSelectedItem(index)"> | |
<v-list-item-content> | |
<v-list-item-title>{{ item[selectedColumn] }}</v-list-item-title> | |
</v-list-item-content> | |
</v-list-item> | |
</v-list-item-group> | |
</v-list> | |
</v-navigation-drawer> | |
<v-main> | |
<v-container fill-height fluid> | |
<template v-if="items.length > 0"> | |
<v-card width="100%" v-if="selectedItemIndex !== null"> | |
<v-card-title> | |
{{ selectedItemData[selectedColumn] }} | |
</v-card-title> | |
<v-card-text v-for="(value, key) in selectedItemData" :key="key"> | |
<div class="text-subtitle-2">{{ key }}</div> | |
<div class="text-subtitle-1" style="white-space: pre-wrap;">{{ selectedItemData[key] }}</div> | |
<v-divider></v-divider> | |
</v-card-text> | |
</v-card> | |
</template> | |
<template v-else> | |
<v-card class="ma-auto" min-width="400px"> | |
<v-card-title>Select CSV file</v-card-title> | |
<v-file-input | |
label="Upload CSV" | |
@change="handleFileUpload" | |
accept=".csv" | |
outlined | |
class="ma-2" | |
:disabled="loading" | |
></v-file-input> | |
</v-card> | |
</template> | |
</v-container> | |
</v-main> | |
</v-app> | |
</div> | |
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/vuetify@2/dist/vuetify.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/papaparse/papaparse.min.js"></script> | |
<script> | |
const vm = new Vue({ | |
el: '#app', | |
vuetify: new Vuetify(), | |
data() { | |
return { | |
loading: false, | |
items: [], | |
columns: [], | |
selectedColumn: null, | |
selectedItemIndex: null, | |
selectedItemData: {} | |
}; | |
}, | |
methods: { | |
clearData() { | |
this.items = []; | |
this.columns = []; | |
this.selectedColumn = null; | |
this.selectedItemIndex = null; | |
this.selectedItemData = {}; | |
}, | |
async handleFileUpload(file) { | |
this.loading = true; | |
if (file) { | |
const text = await this.readFile(file); | |
await this.parseCSV(text); | |
} | |
this.loading = false; | |
}, | |
async readFile(file) { | |
return new Promise((resolve, reject) => { | |
const reader = new FileReader(); | |
reader.onload = (event) => resolve(event.target.result); | |
reader.onerror = (error) => reject(error); | |
reader.readAsText(file); | |
}); | |
}, | |
async parseCSV(csvText) { | |
const { data, meta } = await Papa.parse(csvText, { header: true }); | |
this.columns = meta.fields; | |
this.items = data; | |
this.selectedColumn = this.columns[0]; | |
}, | |
updateSelectedItem(index) { | |
this.selectedItemIndex = index; | |
this.selectedItemData = { ...this.items[index] }; | |
} | |
} | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment