code.gs
//CONSTANTS
const SPREADSHEETID = "1X--------------------yefc";
const DATARANGE = "holders!B3:Q";
const DATASHEET = "holders";
const DATASHEETID = "0";
const LASTCOL = "Q";
const IDRANGE = "holders!B3:B";
const DROPDOWNRANGE = "Helpers!A1:A195"; //COUNTRY LIST
//Display HTML page
function doGet() {
return HtmlService.createTemplateFromFile('Index').evaluate()
.setTitle('Shiloh Church Mini Bank')
.setFaviconUrl('https://www.pngall.com/wp-content/uploads/2016/05/Gold-PNG.png')
.addMetaTag('viewport', 'width=device-width, initial-scale=1')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
}
//PROCESS SUBMITTED FORM DATA
function processForm(formObject) {
if (formObject.recId && checkId(formObject.recId)) {
const values = [[
formObject.recId,
formObject.name,
formObject.description,
formObject.category,
formObject.countryOfOrigin,
formObject.condition,
formObject.price,
formObject.quantity,
new Date().toLocaleString()
]];
const updateRange = getRangeById(formObject.recId);
//Update the record
updateRecord(values, updateRange);
} else {
//Prepare new row of data
let values = [[
generateUniqueId(),
formObject.name,
formObject.description,
formObject.category,
formObject.countryOfOrigin,
formObject.condition,
formObject.price,
formObject.quantity,
new Date().toLocaleString()
]];
//Create new record
createRecord(values);
}
return getAllRecords();
}
/**
* CREATE RECORD
* REF:
* https://developers.google.com/sheets/api/guides/values#append_values
*/
function createRecord(values) {
try {
let valueRange = Sheets.newRowData();
valueRange.values = values;
let appendRequest = Sheets.newAppendCellsRequest();
appendRequest.sheetId = SPREADSHEETID;
appendRequest.rows = valueRange;
Sheets.Spreadsheets.Values.append(valueRange, SPREADSHEETID, DATARANGE, { valueInputOption: "RAW" });
} catch (err) {
console.log('Failed with error %s', err.message);
}
}
/**
* READ RECORD
* REF:
* https://developers.google.com/sheets/api/guides/values#read
*/
function readRecord(range) {
try {
let result = Sheets.Spreadsheets.Values.get(SPREADSHEETID, range);
return result.values;
} catch (err) {
console.log('Failed with error %s', err.message);
}
}
/**
* UPDATE RECORD
* REF:
* https://developers.google.com/sheets/api/guides/values#write_to_a_single_range
*/
function updateRecord(values, updateRange) {
try {
let valueRange = Sheets.newValueRange();
valueRange.values = values;
Sheets.Spreadsheets.Values.update(valueRange, SPREADSHEETID, updateRange, { valueInputOption: "RAW" });
} catch (err) {
console.log('Failed with error %s', err.message);
}
}
/**
* DELETE RECORD
* Ref:
* https://developers.google.com/sheets/api/guides/batchupdate
* https://developers.google.com/sheets/api/samples/rowcolumn#delete_rows_or_columns
*/
function deleteRecord(id) {
const rowToDelete = getRowIndexById(id);
const deleteRequest = {
"deleteDimension": {
"range": {
"sheetId": DATASHEETID,
"dimension": "ROWS",
"startIndex": rowToDelete,
"endIndex": rowToDelete + 1
}
}
};
Sheets.Spreadsheets.batchUpdate({ "requests": [deleteRequest] }, SPREADSHEETID);
return getAllRecords();
}
//GET ALL RECORDS
function getAllRecords() {
const allRecords = readRecord(DATARANGE);
return allRecords;
}
//GET RECORD FOR THE GIVEN ID
function getRecordById(id) {
if (!id || !checkId(id)) {
return null;
}
const range = getRangeById(id);
if (!range) {
return null;
}
const result = readRecord(range);
return result;
}
function getRowIndexById(id) {
if (!id) {
throw new Error('Invalid ID');
}
const idList = readRecord(IDRANGE);
for (var i = 0; i < idList.length; i++) {
if (id == idList[i][0]) {
var rowIndex = parseInt(i + 1);
return rowIndex;
}
}
}
//VALIDATE ID
function checkId(id) {
const idList = readRecord(IDRANGE).flat();
return idList.includes(id);
}
//GET DATA RANGE IN A1 NOTATION FOR GIVEN ID
function getRangeById(id) {
if (!id) {
return null;
}
const idList = readRecord(IDRANGE);
const rowIndex = idList.findIndex(item => item[0] === id);
if (rowIndex === -1) {
return null;
}
const range = `Data!A${rowIndex + 2}:${LASTCOL}${rowIndex + 2}`;
return range;
}
//INCLUDE HTML PARTS, EG. JAVASCRIPT, CSS, OTHER HTML FILES
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
//GENERATE UNIQUE ID
function generateUniqueId() {
let id = Utilities.getUuid();
return id;
}
function getCountryList() {
countryList = readRecord(DROPDOWNRANGE);
return countryList;
}
//SEARCH RECORDS
function searchRecords(formObject) {
let result = [];
try {
if (formObject.searchText) {//Execute if form passes search text
const data = readRecord(DATARANGE);
const searchText = formObject.searchText;
// Loop through each row and column to search for matches
for (let i = 0; i < data.length; i++) {
for (let j = 0; j < data[i].length; j++) {
const cellValue = data[i][j];
if (cellValue.toLowerCase().includes(searchText.toLowerCase())) {
result.push(data[i]);
break; // Stop searching for other matches in this row
}
}
}
}
} catch (err) {
console.log('Failed with error %s', err.message);
}
return result;
}
function genMail() {
// Set the ID of the Google Doc Template
var docTemplateId = "1jbL0DkvagHq3kvnmDD9xnUxYD0FMtk7tBzX3QauXbbI";
// Set the ID of the Google Sheet containing student data
var Id = "1X9qlLfO0uQ7DxkiSw_jY8QPRZevBmgZpqhcVpSQyefc"; //แก้ 1
var ss=SpreadsheetApp.openById(Id);
var sheet = ss.getSheetByName("genEmail");
var range = sheet.getDataRange();
var data = range.getDisplayValues();
// Start from the second row to skip header
for (var i = 1; i < data.length; i++) {
var lastName = data[i][0];
var idNo = data[i][1];
var address = data[i][2];
var deposit = data[i][3];
var withdraw = data[i][4];
var balance = data[i][5];
var status = data[i][6];
var bahtThai = data[i][7];
var dmyThai = data[i][8];
var emailAddress = data[i][9];
// Make a copy of the template document
var docCopy = DriveApp.getFileById(docTemplateId).makeCopy();
var docCopyId = docCopy.getId();
var doc = DocumentApp.openById(docCopyId);
var body = doc.getBody();
// Replace placeholders in the document with data from the sheet
body.replaceText('{{LlastName}}', lastName);
body.replaceText('{{IidNo}}', idNo);
body.replaceText('{{Aaddress}}', address);
body.replaceText('{{Ddeposit}}', deposit);
body.replaceText('{{Wwithdraw}}', withdraw);
body.replaceText('{{Bbalance}}', balance);
body.replaceText('{{Sstatus}}', status);
body.replaceText('{{BbahtThai}}', bahtThai);
body.replaceText('{{DdmyThai}}', dmyThai);
body.replaceText('{{Today}}', Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd"));
// Save and close the document
doc.saveAndClose();
// Generate PDF from the document
var pdfFile = DriveApp.getFileById(docCopyId).getAs("application/pdf");
// Rename the PDF file as "Quiz Online"
pdfFile.setName("แจ้งยอดเงินในบัญชีของท่าน"+ lastName );
// Send email with the PDF attachment
MailApp.sendEmail({
to: emailAddress,
subject: "Shiloh Church Mini Bank ขอแจ้งยอดเงินบัญชีของท่าน",
body: "เรียน " + lastName + ",\n\nShiloh Church Mini Bank ขอแจ้งยอดเงินบัญชีของท่าน ตามหนังสือที่แนบมาพร้อมนี้.\n\nขอแสดงตวามนับถือ,\nShiloh Church Mini Bank ",
attachments: [pdfFile]
});
// Delete the temporary document copy
DriveApp.getFileById(docCopyId).setTrashed(true);
}
}
**************************
Index.html
<!DOCTYPE html>
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.css" />
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" />
<link rel="stylesheet" href="https://cdn.datatables.net/rowreorder/1.3.3/css/rowReorder.dataTables.min.css" />
<link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.4.1/css/responsive.dataTables.min.css" />
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap-grid.min.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css
" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/dataTables.bootstrap5.min.css" />
<link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.5.0/css/responsive.bootstrap5.min.css" />
<?!= include('css');?>
<title>Product Details</title>
<?!= include('JavaScript'); ?>
<!-- See JavaScript.html file -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" />
<link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.4.1/css/responsive.dataTables.min.css" />
<style>
.btn-custom {
font-size: 0.75rem;
padding: 0.25rem 0.4rem;
}
a {
text-decoration: none;
}
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Thai&display=swap');
* {
font-family: 'Noto Sans Thai', sans-serif;
}
body{
font-size:0.875rem;
}
</style>
<style>
body {
font-family: "Prompt", sans-serif;
font-size: 15px;
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="col-md-12">
<nav class="navbar navbar-expand-lg bg-primary">
<div class="container-fluid">
<a class="navbar-brand text-white">ภาระกิจของ Shiloh Church Mini Bank</a>
<button type="button" class="btn btn-warning btn-sm" onclick="btnaddData()"> เพิ่มลูกค้า(สมาชิก)
</button>
<button type="button" class="btn btn-light btn-sm" onclick="btnDeposit()"> ฝากเงิน(Deposit)
</button>
<button type="button" class="btn btn-danger btn-sm" onclick="btnWithdraw()"> ถอนเงิน(Withdraw)
</button>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
</ul>
<form id="search-form" class="d-flex" role="search" onsubmit="handleSearchForm(this)">
<input class="form-control form-control-sm me-1" type="search" name="searchText" placeholder="Search" required>
<button class="btn btn-warning btn-sm" type="submit">ค้นหา</button>
</form>
</div>
</div>
</nav>
<table id="dataTable" class="table dt-responsive nowrap" style="width:100%"></table>
<!-- <table id="dataTable" class="display compact responsive nowrap" style="width:100%"></table> -->
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="myModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="staticBackdropLabel">Product Details</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<?!= include('FormProductDetails'); ?>
</div>
</div>
</div>
</div>
<!-- Modal Adddata-->
<div class="modal fade bd-modal-lg" role="dialog" id="adddataModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="staticBackdropLabel">เพิ่มลูกค้า(สมาชิก,บัญชี)</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<?!= include('addholders'); ?>
</div>
</div>
</div>
</div>
<!-- Modal Deposit -->
<div class="modal fade bd-modal-lg" id="depositModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="staticBackdropLabel">ฝากเงิน(Deposit)</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<?!= include('deposit'); ?>
</div>
</div>
</div>
</div>
<!-- Modal Withdraw-->
<div class="modal fade bd-modal-lg" id="withdrawModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="staticBackdropLabel">ถอนเงิน(Withdraw)</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<?!= include('withdraw'); ?>
</div>
</div>
</div>
</div>
<?!= include('SpinnerModal'); ?>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/responsive/2.4.1/js/dataTables.responsive.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/rowreorder/1.3.3/js/dataTables.rowReorder.min.js"></script>
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/dataTables.bootstrap5.min.js"></script>
<script src="https://cdn.datatables.net/responsive/2.5.0/js/dataTables.responsive.min.js"></script>
<script src="https://cdn.datatables.net/responsive/2.5.0/js/responsive.bootstrap5.min.js"></script>
<script src="https://kit.fontawesome.com/6a972cf3a7.js" crossorigin="anonymous"></script>
</body>
</html>
************************
addholders.html
<iframe style="position: absolute;top:0;left:0; width:100%;height:500px;border:0;" src="https://script.google.com/macros/s/AKfycbwf5xC5Lmptx11frKtU-bxHCaqA5AXpQOKizyKQ_DM5L5Uodg52dGyNi2QuhGoFzLhELA/exec"></iframe>
**********************************
deposit.html
<iframe style="position: absolute;top:0;left:0; width:100%;height:500px;border:0;" src="https://script.google.com/macros/s/AKfycbyp0VkLbzhAFLAAxjVVThBkusfCZzfubSdQUHm88ssbIdVqkR4mHXMV_9RW-xzajbYD/exec"></iframe>
*******************
withdraw.html
<iframe style="position: absolute;top:0;left:0; width:100%;height:500px;border:0;" src="https://script.google.com/macros/s/AKfycbyWK94Aykd3xV_cty9RDypSiyX-ZqpGSRW4bmjKO2o0kexqBOfXZFqw-MKh4t6_W9Mv5Q/exec"></iframe>
******************
JavaScript.html
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous"></script>
<script>
function btnaddData(){
$('#adddataModal').modal('show');
document.getElementById("ProductDetails").reset();
document.getElementById("message").innerHTML = ""
}
function btnDeposit(){
$('#depositModal').modal('show');
document.getElementById("ProductDetails").reset();
document.getElementById("message").innerHTML = ""
}
function btnWithdraw(){
$('#withdrawModal').modal('show');
document.getElementById("ProductDetails").reset();
document.getElementById("message").innerHTML = ""
}
function genMail() {
// $('#spinnerModal').modal('show');
google.script.run.genMail()
}
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener("load", functionInit, true);
//INITIALIZE FUNCTIONS ONLOAD
function functionInit(){
//$('#spinnerModal').modal('show');
preventFormSubmit();
getAllRecords();
createCountryDropdown();
};
//RETRIVE DATA FROM GOOGLE SHEET FOR COUNTRY DROPDOWN
function createCountryDropdown() {
google.script.run.withSuccessHandler(countryDropDown).getCountryList();
}
//POPULATE COUNTRY DROPDOWNS
function countryDropDown(values) { //Ref: https://stackoverflow.com/a/53771955/2391195
var list = document.getElementById('countryOfOrigin');
for (var i = 0; i < values.length; i++) {
var option = document.createElement("option");
option.value = values[i];
option.text = values[i];
list.appendChild(option);
}
}
//HANDLE FORM SUBMISSION
function handleFormSubmit(formObject) {
$('#spinnerModal').modal('show');
$('#myModal').modal('hide');
google.script.run.withSuccessHandler(createTable).processForm(formObject);
document.getElementById("ProductDetails").reset();
}
function deleteRecord(el) {
{
passedit()
async function passedit(){
const { value: password } = await Swal.fire({
position: 'top',
title: 'กรุณาใส่รหัสผ่าน',
confirmButtonColor: 'red',
confirmButtonText: 'ตกลง',
input: 'password',
inputLabel: 'เข้าสู่การลบข้อมูล',
inputPlaceholder: 'ใส่รหัสผ่านของคุณ',
inputAttributes: {
maxlength: 10,
autocapitalize: 'off',
autocorrect: 'off'
}
})
if (password==="7654321321") {
// Swal.fire(`Entered password: ${password}`)
Swal.fire({
position: 'top',
title: 'คุณแน่ใจไหม? ที่จะลบข้อมูล',
text: "คุณไม่สามารถกู้คืนได้น่ะ ต้องการลบข้อมูล! ใช่หรือไม่",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'ตกลง, ต้องการลบข้อมูลจริงๆ!',
cancelButtonText: 'ยกเลิก',
}).then((result) => {
if (result.isConfirmed) {
var recordId = el.parentNode.parentNode.cells[2].innerHTML;
google.script.run.withSuccessHandler(createTable).deleteRecord(recordId);
document.getElementById("ProductDetails").reset();
}
})
}else{
Swal.fire({
position: 'top',
icon: 'error',
title: 'รหัสผ่านไม่ถูกต้อง',
showConfirmButton: false,
timer: 1500
})
}
}
}
}
function editRecord(el){
passedit()
async function passedit(){
const { value: password } = await Swal.fire({
position: 'top',
title: 'กรุณาใส่รหัสผ่าน',
confirmButtonColor: 'violet',
confirmButtonText: 'ตกลง',
input: 'password',
inputLabel: 'เข้าสู่การแก้ไข',
inputPlaceholder: 'ใส่รหัสผ่านของคุณ',
inputAttributes: {
maxlength: 10,
autocapitalize: 'off',
autocorrect: 'off'
}
})
if (password==="7654321") {
// Swal.fire(`Entered password: ${password}`)
$('#spinnerModal').modal('show');
let id = el.parentNode.parentNode.cells[2].innerHTML;
google.script.run.withSuccessHandler(populateForm).getRecordById(id);
}else{
Swal.fire({
position: 'top',
icon: 'error',
title: 'รหัสผ่านไม่ถูกต้อง',
showConfirmButton: false,
timer: 1500
})
}
}
}
function populateForm(data){
$('#spinnerModal').modal('hide');
$('#myModal').modal('show');
document.getElementById('recId').value = data[0][0];
document.getElementById('name').value = data[0][1];
document.getElementById('description').value = data[0][2];
document.getElementById('category').value = data[0][3];
document.getElementById('countryOfOrigin').value = data[0][4];
document.getElementById(data[0][5]).checked = true;
document.getElementById('price').value = data[0][6];
document.getElementById('quantity').value = data[0][7];
document.getElementById("message").innerHTML = "<div class='alert alert-warning' role='alert'>Update Record [ID: "+data[0][1]+"]</div>";
}
//CREATE THE DATA TABLE
function createTable(dataArray) {
$('#spinnerModal').modal('hide');
$('#myModal').modal('hide');
if (dataArray && dataArray.length) {
var result =
"<table class='table table-sm' style='font-size:0.8em'>" +
"<thead style='white-space: nowrap'>" +
"<tr>" +
"<th scope='col'>ส่งEmail</th>" +
"<th scope='col'>ส่งline</th>" +
"<th scope='col'style='display:none;'>เลขที่่ลูกค้า</th>" +
"<th scope='col'>ชื่อลูกค้า(สมาชิก,บัญชี)</th>" +
// "<th scope='col'style='display:none;'>Description</th>" +
"<th scope='col'>ฝากทั้งหมด</th>" +
"<th scope='col'>ถอนทั้งหมด</th>" +
"<th scope='col'>หลังจากถอน</th>" +
"<th scope='col'>ค่าบริการทั้งหมด</th>" +
"<th scope='col'>จำนวนเงินคงเหลือ</th>" +
"<th scope='col'>สถานะ</th>" +
"<th scope='col'>ที่อยู่</th>" +
"<th scope='col'>วัน เดือน ปีเกิด</th>" +
"<th scope='col'>อายุ ปี</th>" +
"<th scope='col'>ระดับการศึกษา</th>" +
"<th scope='col'>อาชีพ</th>" +
"<th scope='col'>สถานภาพสมรส</th>" +
"<th scope='col'>ภาพสมาชิกฯ</th>" +
"<th scope='col'>เพศ</th>" +
"</tr>" +
"</thead>";
for (var i = 0; i < dataArray.length; i++) {
result += "<tr>";
result +=
"<td><button type='button' class='btn btn-danger btn-custom emailBtn' onclick='genMail(this);'>ส่ง Email</button></td>";
result +=
"<td><button type='button' class='btn btn-warning btn-custom lineBtn' onclick='genline(this);'>ส่ง line</button></td>";
for (var j = 0; j < dataArray[i].length; j++) {
if (j === 0) {
result +=
"<td style='display:none;'>" + dataArray[i][j] + "</td>"; // Hide the ID column data
}else if(j === 120){
result +=
"<td style='display:none;'>" + dataArray[i][j] + "</td>"; // Hide the Description column data
} else {
result += "<td>" + dataArray[i][j] + "</td>";
}
}
result += "</tr>";
}
result += "</table>";
var div = document.getElementById("dataTable");
div.innerHTML = result;
document.getElementById("message").innerHTML = "";
$(document).ready(function() {
$('#dataTable').DataTable({
columnDefs: [
{
target: 4,
visible: false,
searchable: false,
},
],
destroy:true,
order: [[2, 'desc']],
searching:false,
});
} );
} else {
var div = document.getElementById("dataTable");
div.innerHTML = "Data not found!";
}
}
//SEARCH RECORDS
function handleSearchForm(formObject) {
$('#spinnerModal').modal('show');
google.script.run.withSuccessHandler(createTable).searchRecords(formObject);
document.getElementById("search-form").reset();
}
function getAllRecords(){
$('#spinnerModal').modal('show');
google.script.run.withSuccessHandler(createTable).getAllRecords();
}
</script>
*********************************
SpinnerModal.html
<div class="modal fade" id="spinnerModal" tabindex="-1" role="dialog" aria-labelledby="spinnerModalLabel"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-body text-center">
<div class="spinner-border mt-3" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="mt-3">Loading...</p>
</div>
</div>
</div>
</div>
***********************************
css.html
<style>
@import url('https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200;0,300;0,400;0,600;0,700;1,200;1,300&display=swap');
</style>
<style>
.btn-group-xs > .btn, .btn-xs {
padding: .25rem .4rem;
font-size: .875rem;
line-height: .5;
border-radius: .2rem;
}
</style>
<style>
@import url('https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200;0,300;0,400;0,600;0,700;1,200;1,300&display=swap');
</style>
<style>
html,
body,
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: "Kanit", sans-serif;
}
.autocomplete {
position: relative;
}
#matchList {
position: absolute;
z-index: 99;
background-color: white;
left: 0;
right: 0;
/* vertical scroll bar */
max-height: 350px;
overflow-y: auto;
/* prevent horizontal scrollbar */
overflow-x: hidden;
}
#matchList:hover {
cursor: pointer;
}
li > span {
pointer-events: none;
}
</style>
*************************************************
FormProductDetails.html
<form id="ProductDetails" onsubmit="handleFormSubmit(this)">
<div id="message"></div>
<input type="text" id="recId" name="recId" value="" style="display: none">
<div class="mb-1">
<label for="name" class="form-label">Product Name:</label>
<input type="text" id="name" name="name" class="form-control form-control-sm" required>
</div>
<div class="mb-1">
<label for="description" class="form-label">Product Description:</label>
<textarea id="description" name="description" class="form-control form-control-sm" rows="2"></textarea>
</div>
<div class="mb-1">
<label for="category" class="form-label">Product Category:</label>
<select id="category" name="category" class="form-select form-select-sm" required>
<option value="">--Select a category--</option>
<option value="Electronics">Electronics</option>
<option value="Clothing">Clothing</option>
<option value="Home and Garden">Home and Garden</option>
<option value="Sports and Outdoors">Sports and Outdoors</option>
</select>
</div>
<div class="mb-1">
<div class="form-group col">
<label for="countryOfOrigin" class="form-label">Country</label>
<select class="form-select form-select-sm" id="countryOfOrigin" name="countryOfOrigin" required>
<option>--Select Country--</option>
</select>
</div>
</div>
<div class="mb-1">
<label class="form-label">Product Condition:</label><br>
<div class="form-check form-check-inline">
<input type="radio" id="new" name="condition" class="form-check-input" value="new" required>
<label for="new" class="form-check-label">New</label>
</div>
<div class="form-check form-check-inline">
<input type="radio" id="used" name="condition" class="form-check-input" value="used" required>
<label for="used" class="form-check-label">Used</label>
</div>
</div>
<div class="mb-1">
<label for="price" class="form-label">Price:</label>
<input type="number" id="price" name="price" class="form-control" step="0.01" required>
</div>
<div class="mb-1">
<label for="quantity" class="form-label">Quantity:</label>
<input type="number" id="quantity" name="quantity" class="form-control" required>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
ไม่มีความคิดเห็น:
แสดงความคิดเห็น
หมายเหตุ: มีเพียงสมาชิกของบล็อกนี้เท่านั้นที่สามารถแสดงความคิดเห็น