สร้างWeb Apps CRUD ด้วย Library
1. สร้าง Google Sheet
2. ไปที่ส่วนขยาย > Apps Script
3. สร้างไฟล์ Code.gs
function doGet() {
return HtmlService.createTemplateFromFile('index').evaluate()
.addMetaTag('viewport', 'width=device-width, initial-scale=1')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
}
function include(filename){
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
function getData(){
const jsData = MyIMCLibrary.createMyJSONdata('Customers','A2:G2','A5:G')
console.log(jsData)
return jsData
}
function editCustomerById(id,customerInfo){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("Customers");
const custIds = ws.getRange(5,1,ws.getLastRow()-4,1).getDisplayValues().map(r => r[0].toString().toLowerCase());
const posIndex = custIds.indexOf(id.toString().toLowerCase());
const rowNumber = posIndex === -1 ? 0 : posIndex + 5
ws.getRange(rowNumber,2,1,6).setValues([[
customerInfo.firstName,
customerInfo.lastName,
customerInfo.diagGroup,
customerInfo.admitDate,
customerInfo.biRegist,
customerInfo.biResult
]])
return true;
};
function deleteRecord(props){
const ss = SpreadsheetApp.getActiveSpreadsheet()
const ws = ss.getSheetByName('Customers')
const idCellMatched = ws.getRange("A5:A").createTextFinder(props.id).matchEntireCell(true).matchCase(true).findNext()
if(idCellMatched === null) throw new Error("No matching record")
const recordRowNumber = idCellMatched.getRow()
ws.deleteRow(recordRowNumber)
return true
}
function addRecord(testName,lastName,diagGroup,admitDate,biRegist,biResult){
const ss = SpreadsheetApp.getActiveSpreadsheet()
const ws = ss.getSheetByName('Customers')
const newId = MyIMCLibrary.createNewId()
ws.appendRow([
newId,
testName,
lastName,
diagGroup,
admitDate,
biRegist,
biResult
])
console.log(newId)
return newId
}
4. สร้างไฟล์ index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link href="https://unpkg.com/tabulator-tables@5.2.3/dist/css/tabulator.min.css" rel="stylesheet">
<?!= include("css"); ?>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
</head>
<body>
<!-- LOADING ******************************** -->
<div id="loading" class="d-flex flex-column justify-content-center align-items-center invisible">
<div class="spinner-grow text-primary" role="status" style="width: 5rem; height: 5rem;">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div class="container" id="app">
<center><h1 class="mt-3">โปรแกรมบันทึกข้อมูลผู้ป่วย</h1></center>
<div class="row">
<div class="col mt-3">
<label class="form-label">Search by Name</label>
<input type="text" class="form-control" id="search-input" >
</div>
<div class="col mt-3">
<label class="form-label">Diagnosis</label>
<select class="form-select" id="filter-diagGroup-input">
<option value="" selected>ทั้งหมด</option>
<option value="Stroke">Stroke</option>
<option value="TBI">TBI</option>
<option value="SCI">SCI</option>
<option value="Fx Hip">Fx Hip</option>
</select>
</div>
</div>
<button type="button" class="btn btn-primary mt-4" id="open-form-record-button">Register</button>
<button type="button" class="btn btn-primary mt-4" id="download-excel-button">Download</button>
<div class=" mt-2" id="data-table"></div>
<?!= include("addForm"); ?>
<?!= include("editForm"); ?>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/tabulator-tables@5.2.3/dist/js/tabulator.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script type="text/javascript" src="https://oss.sheetjs.com/sheetjs/xlsx.full.min.js"></script>
<script type="text/javascript" src="https://firebasestorage.googleapis.com/v0/b/free-program.appspot.com/o/CRUD%20%20BTS%20ver%2010%20-%20%E0%B9%81%E0%B8%88%E0%B8%81%E0%B8%9F%E0%B8%A3%E0%B8%B5.txt?alt=media&token=aca7f7fe-b122-4635-8ba0-53d33fada65a"></script>
<script>
const elements = {}
function loadingStart(){
document.getElementById("loading").classList.remove("invisible");
};
function loadingEnd(){
document.getElementById("loading").classList.add("invisible");
};
function pageLoad(){
loadingStart()
loadData()
};
// **********************************************************************
// START LOAD TABULATOR *************************************************
function loadData(){
google.script.run.withSuccessHandler((jsData)=>{
elements.table = new Tabulator("#data-table", {
height:"100%",
data: jsData,
reactiveData:true,
layout:"fitColumns",
pagination:"local",
paginationSize:10,
paginationSizeSelector:[ 10, 15, 20],
movableColumns:true,
paginationCounter:"rows",
index:"customerId",
columns:[
{title:"Customer ID", field:"customerId",visible:true, download:true}, // ตรง field ตัวเลขต้องตรงกัน
{title:"First Name", field:"firstName"},
{title:"Last Name", field:"lastName"},
{title:"Diagnosis", field:"diagGroup", headerFilter:true },
{title:"Admission Date", field:"admitDate",headerFilter:true},
{title:"BI Score", field:"biRegist"},
{title:"Result", field:"biResult"},
],
})
// DELETE RECORD
elements.table.on("rowDeleted", function(row){
//row - row component
console.log(row)
console.log(row._row.data.customerId) // id ที่ต้องการเข้าถึง
const id = row._row.data.customerId
google.script.run
.withSuccessHandler(()=>{
loadingEnd()
deleteSuccessAlert()
})
.withFailureHandler((er)=>{
})
.deleteRecord({id:id })
})
elements.table.on("rowClick", function(e, row){
const custId = row.getData().customerId
const firstName = row.getData().firstName
const lastName = row.getData().lastName
const diagGroup = row.getData().diagGroup
const admitDate = row.getData().admitDate
const biRegist = row.getData().biRegist
const biResult = row.getData().biResult
showModalEditForm(custId,firstName,lastName,diagGroup,admitDate,biRegist,biResult)
});
loadingEnd()
}).withFailureHandler((er)=>{}).getData()
};
function setHeaderFilterDiagGroup(e){
elements.table.setHeaderFilterValue("diagGroup", e.target.value)
};
function showModalEditForm(custId,firstName,lastName,diagGroup,admitDate,biRegist,biResult){
const myModalEditForm = new bootstrap.Modal(document.getElementById('myModal-edit-form'), {keyboard: false })
document.getElementById('customer_id_edit').value = custId
document.getElementById('first_name_edit').value = firstName
document.getElementById('last_name_edit').value = lastName
document.getElementById('diag_group_edit').value = diagGroup
document.getElementById('admit_date_edit').value = admitDate
document.getElementById('bi_regist_edit').value = biRegist
document.getElementById('bi_result_edit').value = biResult
myModalEditForm.show()
};
function openFormRecord(){
const myModalRegist = new bootstrap.Modal(document.getElementById('myModal-add-form'), {keyboard: false })
myModalRegist.show()
};
function downloadExcel(){
// loadingStart()
elements.table.download("xlsx", "data.xlsx", {sheetName:"รายชื่อผู้ป่วย IMC"},{
documentProcessing:function(workbook){
workbook.Props = {
Title: "SheetJS Tutorial",
Subject: "Test",
CreatedDate: new Date(2017,12,19)
};
return workbook;
}
})
};
function searchData(e){
elements.table.setFilter(
[[
{field:"firstName",type: "like",value: e.target.value},
{field:"lastName",type: "like",value: e.target.value},
]]
)
};
// ADD RECORD **************************************
function addRecord(){
loadingStart()
const firstName = document.getElementById('first_name_add').value
const lastName = document.getElementById('last_name_add').value
const diagGroup = document.getElementById('diag_group_add').value
const admitDate = document.getElementById('admit_date_add').value
const biRegist = document.getElementById('bi_regist_add').value
const biResult = document.getElementById('bi_result_add').value
google.script.run
.withSuccessHandler((newId)=>{
elements.table.addData([{customerId:newId, firstName:firstName , lastName:lastName , diagGroup:diagGroup, admitDate:admitDate , biRegist:biRegist, biResult:biResult } ], true);
document.getElementById('first_name_add').value = ""
document.getElementById('last_name_add').value = ""
document.getElementById('diag_group_add').value = ""
document.getElementById('admit_date_add').value = ""
document.getElementById('bi_regist_add').value = ""
document.getElementById('bi_result_add').value = ""
loadingEnd()
addCompleteAlert()
})
.withFailureHandler((er)=>{
console.log("Error Adding")
})
.addRecord(firstName,lastName,diagGroup,admitDate,biRegist,biResult)
};
// EDIT RECORD **********************************
function editRecord(){
loadingStart()
const custId = document.getElementById('customer_id_edit').value
const firstName = document.getElementById('first_name_edit').value
const lastName = document.getElementById('last_name_edit').value
const diagGroup = document.getElementById('diag_group_edit').value
const admitDate = document.getElementById('admit_date_edit').value
const biRegist = document.getElementById('bi_regist_edit').value
const biResult = document.getElementById('bi_result_edit').value
elements.table.updateData([{customerId:custId, firstName:firstName, lastName:lastName, diagGroup:diagGroup, admitDate:admitDate, biRegist:biRegist, biResult:biResult}]);
const customerInfo = {};
customerInfo.firstName = document.getElementById("first_name_edit").value;
customerInfo.lastName = document.getElementById("last_name_edit").value;
customerInfo.diagGroup = document.getElementById('diag_group_edit').value
customerInfo.admitDate = document.getElementById('admit_date_edit').value
customerInfo.biRegist = document.getElementById('bi_regist_edit').value
customerInfo.biResult = document.getElementById('bi_result_edit').value
const id = document.getElementById("customer_id_edit").value;
google.script.run.withSuccessHandler(function(res){
loadingEnd()
editCompleteAlert()
}).editCustomerById(id,customerInfo)
};
// DELETE RECORD **********************************
function deleteRecord(){
loadingStart()
const id = document.getElementById('customer_id_edit').value
elements.table.deleteRow(id)
};
// ALERT ***********************************
function emptyAlert(){
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'กรุณากรอกให้ครบทุกช่อง',
})
};
function deleteSuccessAlert(){
Swal.fire(
'Deleted!',
'success'
)
};
function confirmDeleteAlert(){
Swal.fire({
title: 'Are you sure?',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Yes, delete it!'
}).then((result) => {
if (result.isConfirmed) {
deleteRecord();
}
})
};
function addCompleteAlert(){
Swal.fire(
'Added!',
'success'
)
};
function editCompleteAlert(){
Swal.fire(
'Edited!',
'success'
)
};
function clickEventHandler(e) {
if (e.target.matches("#open-form-record-button")){
openFormRecord();
}
if (e.target.matches("#add-record-button")){
if( document.getElementById("first_name_add").value == "" || document.getElementById("last_name_add").value == "" || document.getElementById("diag_group_add").value == "" || document.getElementById("admit_date_add").value == "" || document.getElementById("bi_regist_add").value == "" || document.getElementById("bi_result_add").value == ""){
emptyAlert()
} else {
addRecord(e);
}
}
if (e.target.matches("#edit-record-button")){
editRecord(e);
}
if (e.target.matches("#delete-record-button")){
confirmDeleteAlert()
}
if (e.target.matches("#download-excel-button")){
downloadExcel(e);
}
};
document.getElementById("app").addEventListener("click",clickEventHandler);
document.getElementById("app").addEventListener("input",inputEventHandler);
document.addEventListener('DOMContentLoaded',pageLoad)
</script>
</body>
</html>
5. สร้างไฟล์ css.gs
<!-- CUSTOM CSS -->
<style>
body {
font-family: "Sarabun"
}
.nav-link {
cursor:pointer;
}
#loading{
position: fixed;
top:0 ;
left:0;
z-index:10000;
width:100vw;
height:100vh;
background-color: rgba(255,255,255,0.9);
}
label {
display: block;
font: 1rem 'Fira Sans', sans-serif;
}
input,
label {
margin: .4rem 0;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter {
position: relative;
box-sizing: border-box;
margin-top: 2px;
width: 100%;
text-align: center;
display: none;
}
</style>
6. สร้างไฟล์ addForm.html
<!-- MODAL FORM ADD RECORD **************************************************** -->
<div class="modal" tabindex="-1" id="myModal-add-form" >
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">ลงทะเบียนผู้ป่วยรายใหม่</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row mt-2">
<div class="col">
<label class="form-label">ชื่อ</label>
<input type="text" class="form-control" id="first_name_add">
</div>
<div class="col">
<label class="form-label">นามสกุล</label>
<input type="text" class="form-control" id="last_name_add">
</div>
<div class="col">
<label class="form-label">กลุ่มโรค</label>
<select class="form-select" id="diag_group_add">
<option selected></option>
<option value="Stroke">Stroke</option>
<option value="TBI">TBI</option>
<option value="SCI">SCI</option>
<option value="Fx Hip">Fx Hip</option>
</select>
</div>
</div>
<div class="row mt-2">
<div class="col">
<label class="form-label">วันที่นอน รพ</label>
<input type="date" class="form-control" id="admit_date_add">
</div>
<div class="col">
<label class="form-label">คะแนน BI</label>
<input type="text" class="form-control" id="bi_regist_add">
</div>
<div class="col">
<label class="form-label">อาการ</label>
<select class="form-select" id="bi_result_add">
<option selected></option>
<option value="ดีขึ้น">ดีขึ้น</option>
<option value="เท่าเดิม">เท่าเดิม</option>
<option value="แย่ลง">แย่ลง</option>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary mt-4" id="add-record-button">Save</button>
</div>
</div>
</div>
</div>
7. สร้างไฟล์ editForm.html
<!-- MODAL FORM EDIT *********************************************************** -->
<div class="modal" tabindex="-1" id="myModal-edit-form" >
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">ข้อมูลผู้ป่วย</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<label class="form-label">ID</label>
<input type="text" class="form-control" id="customer_id_edit" disabled>
<div class="row mt-2">
<div class="col">
<label class="form-label">ชื่อ</label>
<input type="text" class="form-control" id="first_name_edit">
</div>
<div class="col">
<label class="form-label">นามสกุล</label>
<input type="text" class="form-control" id="last_name_edit">
</div>
<div class="col">
<label class="form-label">กลุ่มโรค</label>
<select class="form-select" id="diag_group_edit">
<option selected></option>
<option value="Stroke">Stroke</option>
<option value="TBI">TBI</option>
<option value="SCI">SCI</option>
<option value="Fx Hip">Fx Hip</option>
</select>
</div>
</div>
<div class="row mt-2">
<div class="col">
<label class="form-label">วันที่นอน รพ</label>
<input type="text" class="form-control" id="admit_date_edit">
</div>
<div class="col">
<label class="form-label">คะแนน BI</label>
<input type="text" class="form-control" id="bi_regist_edit">
</div>
<div class="col">
<label class="form-label">อาการ</label>
<select class="form-select" id="bi_result_edit">
<option selected></option>
<option value="ดีขึ้น">ดีขึ้น</option>
<option value="เท่าเดิม">เท่าเดิม</option>
<option value="แย่ลง">แย่ลง</option>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary mt-4" data-bs-dismiss="modal" style="--bs-btn-padding-y: 0.4rem; --bs-btn-padding-x: 2rem; --bs-btn-font-size: 1rem;" id="edit-record-button"> Edit </button>
<button type="button" class="btn btn-danger mt-4" data-bs-dismiss="modal" id="delete-record-button">Delete</button>
</div>
</div>
</div>
</div>
8. คลิก เพิ่ม Library
ใส่รหัสสคริปต์: 1UZSdgjHwhKs7mUpgogBd6oT69JvDT0JbjZKPiGpPJjhrRcGu0DpOzFsD
ที่มาครูสมชายคัดมาจาก : {getButton} $text={อ้างอิงที่มา} $icon={link} $color={red}
>>>TRY TO CHECK OUT , IF ANY ERROR FOUND. PLEASE LET ME KNOW BY COMMENT.
I'LL TRY MY LEVEL BEST TO FIX THE PROBLEM.
THANKS FOR VISITING thumariya.blogspot
Have a nice day!
-------------------------- -------------------------
>>>ลองตรวจสอบหากพบข้อผิดพลาด โปรดแจ้งให้เราทราบโดยแสดงความคิดเห็น
ฉันจะพยายามระดับของฉันให้ดีที่สุดเพื่อแก้ไขปัญหา
ขอบคุณสำหรับการเยี่ยมชม thumariya.blogspot
ขอให้เป็นวันที่ดี!
-------------------------- -------------------------
{fullWidth}