1458 lines
82 KiB
HTML
1458 lines
82 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Document</title>
|
||
<link href="../../../js/bootstrap5/bootstrap.min.css" rel="stylesheet" />
|
||
<link href="../../../js/fontawesome6/css/all.min.css" rel="stylesheet" />
|
||
<link href="../../item/jquery-ui/jquery-ui.min.css" rel="stylesheet" />
|
||
<link href="../../../js/mdi-font/css/materialdesignicons.min.css" rel="stylesheet" />
|
||
<script src="../../../js/axios.min.js"></script>
|
||
<script src="../../../js/bootstrap5/js/bootstrap.bundle.min.js"></script>
|
||
<script src="../../../js/jquery-4.0.0.min.js"></script>
|
||
<script src="../../item/jquery-ui/jquery-ui.min.js"></script>
|
||
|
||
<style>
|
||
.div_border {
|
||
border: 1px solid black;
|
||
}
|
||
|
||
.work_space {
|
||
min-height: 40vh;
|
||
min-width: 70vw;
|
||
max-width: 90vw;
|
||
max-height: 50vh;
|
||
}
|
||
|
||
body {
|
||
width: 90vw;
|
||
height: 90vh
|
||
}
|
||
|
||
li {
|
||
font-size: 16px;
|
||
list-style: none;
|
||
margin-top: 1rem;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="d-flex full-home no-print" style="height: 100vh;width:100%;">
|
||
<div id="designArea" class="designArea" style="width: 100%; height: auto">
|
||
<div class="row mt-2">
|
||
<div class="col-3">
|
||
版型設定:
|
||
<select id="styleSel" onchange="designer.changeStyle()" class="form-select">
|
||
<option value="">請選擇版型</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-3">
|
||
引用範本:
|
||
<select id="templateSel" onchange="designer.changeTemplate()" class="form-select">
|
||
<option value="">請選擇範本</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-2">
|
||
<button class="btn btn-primary" onclick="designer.save(event)">儲存牌位</button>
|
||
</div>
|
||
<div class="col-4">
|
||
<div style="display: flex; align-items: center; padding: 8px; background-color: #f5f5f5; border-radius: 4px; margin-bottom: 12px; font-family: sans-serif;">
|
||
<span style="margin-right: 8px; font-size: 14px; cursor: pointer;" onclick="designer.minusZoomScalee()">➖</span>
|
||
<input type="range" min="0.0" max="1.0" step="0.05" style="flex-grow: 1; cursor: pointer;" id="scaleSlider">
|
||
<span style="margin-left: 8px; font-size: 14px; cursor: pointer;" onclick="designer.plusZoomScalee()">➕</span>
|
||
<span id="scaleSize" style="margin-left: 12px; min-width: 45px; font-weight: bold; font-size: 14px; text-align: right;"></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="row work_space">
|
||
<div class="col-7 div_border printArea" style="height:80vh;overflow-y:auto;"></div>
|
||
<div class="col-5 div_border" style="font-size:12px;">
|
||
<div class="row" style="height: 50%; overflow-y: auto;">
|
||
<div style="display:inline-block;width:100%;height:30px;background-color:darkgray;">
|
||
<div class="row">
|
||
<div class="col-12"><h3>已選</h3></div>
|
||
<div class="col-10">
|
||
<div class="form-floating mb-3">
|
||
<input class="form-control" type="text" id="custom_txt" placeholder="請輸入名稱" />
|
||
<label for="custom_txt">請輸入名稱</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-2">
|
||
<button type="button" class="custom_add" onclick="designer.addNewItem()" style="width:20px;height:20px;font-size:25px">+</button>
|
||
</div>
|
||
</div>
|
||
<ul class="selectedItem" style="margin-left:1rem;margin-right:1rem;"></ul>
|
||
</div>
|
||
</div>
|
||
<div class="row" style="height:50%;overflow-y:auto;">
|
||
<div style="display:inline-block;width:100%;height:30px;background-color:darkgray;">
|
||
<div class="row">
|
||
<div class="col-12"><h3>可選</h3></div>
|
||
<div class="col-10">
|
||
<div class="form-floating mb-3">
|
||
<input class="form-control" type="text" id="filter_txt" onkeyup="designer.filterToSel()" placeholder="篩選條件" />
|
||
<label for="filter_txt">篩選條件</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-2">
|
||
<button type="button" data-bs-toggle="modal" data-bs-target="#familyModal" title="新增親友">
|
||
<i class="mdi mdi-account-multiple-plus" style="font-size:30px;"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<ul class="canselectItem" style="margin-left: 1rem;margin-right:1rem;"></ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="modal fade hide" id="familyModal" tabindex="-1" aria-labelledby="familyModalLabel" aria-hidden="true" style="z-index:10000 !important;">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="exampleModalLabel">新增親友</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="row">
|
||
<div class="col-12">
|
||
<div class="form-floating mb-3">
|
||
<input class="form-control" type="text" id="family_txt" placeholder="姓名" />
|
||
<label for="family_txt">姓名</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<div class="form-floating mb-3">
|
||
<select class="form-select" id="deceased_sel" placeholder="存歿">
|
||
<option value="False">存</option>
|
||
<option value="True">歿</option>
|
||
</select>
|
||
<label for="deceased_sel">存歿</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<div class="form-floating mb-3">
|
||
<input class="form-control" type="text" id="title_txt" placeholder="稱謂" />
|
||
<label for="title_txt">稱謂</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">關閉</button>
|
||
<button type="button" class="btn btn-primary" onclick="designer.saveFamily()">存檔</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="position-fixed top-50 start-50 p-3" style="z-index: 10001">
|
||
<div id="liveToast" class="toast hide " role="alert" aria-live="assertive" data-bs-delay="3000" aria-atomic="true" style="color:white;background-color:dimgray;opacity:1;font-size:24px;">
|
||
<div class="toast-header">
|
||
<strong class="me-auto">提示訊息</strong>
|
||
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
|
||
</div>
|
||
<div class="toast-body" id="toast_body"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<script type="text/javascript">
|
||
const designer = {
|
||
zoomScale: 0.5,
|
||
selected: { style: "" },
|
||
tabletTempNameList: [],
|
||
selectedTemplate: {},
|
||
actitem: "",
|
||
pageSize: "",
|
||
defaultStyle: "",
|
||
familyMembers: [],
|
||
tabletItem: {},
|
||
family_deceased_Y_selected: [],
|
||
family_deceased_N_selected: [],
|
||
family_left_title: [],
|
||
family_right_title: [],
|
||
family_address: "",
|
||
allStyle: [],
|
||
allStyleDetails: [],
|
||
allSize: [],
|
||
tabletElement: [],
|
||
http_host: "",
|
||
printData: [],
|
||
selectedElement: {},
|
||
selectStyle: {},
|
||
properTitle: [],
|
||
leftProperTitle: [],
|
||
rightProperTitle: [],
|
||
address: "",
|
||
alive: [],
|
||
tabletType: "A",
|
||
follower_id: "",
|
||
toast: null,
|
||
modal: null,
|
||
bg: [
|
||
{ name: "超薦1", path: "../../../admin/print/html/tablet-1_new.svg" },
|
||
{ name: "超薦2", path: "../../../admin/print/html/tablet-1B_new.svg" },
|
||
{ name: "消災1", path: "../../../admin/print/html/tablet-2.svg" },
|
||
{ name: "消災2", path: "../../../admin/print/html/tablet-2B.svg" },
|
||
{ name: "消災3", path: "../../../admin/print/html/tablet-2C.svg" },
|
||
{ name: "消災4", path: "../../../admin/print/html/tablet-2D.svg" }
|
||
],
|
||
async init() {
|
||
this.toast = new bootstrap.Toast($('#liveToast'));
|
||
this.modal = new bootstrap.Modal($('#familyModal'));
|
||
$("#scaleSize").html((this.zoomScale * 100) + "%");
|
||
$("#scaleSlider").val(this.zoomScale).on("input change", function () {
|
||
designer.zoomScale = parseFloat($(this).val());
|
||
$("#scaleSize").html(Math.floor(designer.zoomScale * 100) + "%");
|
||
$(".tablet-paper").css("transform", `scale(${designer.zoomScale})`);
|
||
});
|
||
},
|
||
async getTemplateNameList() {
|
||
$("#templateSel").empty().append('<option value="">請選擇範本</option>');
|
||
this.tabletTempNameList.length = 0;
|
||
if (!this.follower_id) return;
|
||
await axios.post('/api/follower/GetTabletTemplateList', { num: this.follower_id }).then(res => {
|
||
if (res.status == 200 && res.data.list) {
|
||
this.tabletTempNameList = res.data.list;
|
||
this.tabletTempNameList.forEach(x => {
|
||
$('#templateSel').append(`<option value="${x.num}">${x.name}</option>`);
|
||
});
|
||
}
|
||
});
|
||
},
|
||
async changeTemplate() {
|
||
let template_num = $("#templateSel").val();
|
||
if (!template_num) return;
|
||
this.selectedTemplate = this.tabletTempNameList.find(x => x.num == template_num);
|
||
if (!this.selectedTemplate) return;
|
||
|
||
if (this.selectedTemplate.tablet) {
|
||
let tablet = JSON.parse(this.selectedTemplate.tablet);
|
||
this.properTitle.length = 0; this.leftProperTitle.length = 0; this.rightProperTitle.length = 0; this.alive.length = 0;
|
||
this.family_deceased_Y_selected.length = 0; this.family_deceased_N_selected.length = 0;
|
||
this.family_left_title.length = 0; this.family_right_title.length = 0; this.family_address = "";
|
||
|
||
let mid_items = tablet.mid_items || [];
|
||
let left_items = tablet.left_items || [];
|
||
let mid_left = tablet.mid_left || [];
|
||
let mid_right = tablet.mid_right || [];
|
||
let address = tablet.addr_items || "";
|
||
|
||
Object.assign(this.family_deceased_N_selected, mid_items);
|
||
Object.assign(this.family_deceased_Y_selected, left_items);
|
||
Object.assign(this.family_left_title, mid_left);
|
||
Object.assign(this.family_right_title, mid_right);
|
||
this.family_address = address;
|
||
|
||
mid_items.forEach(y => this.properTitle.push(y.fam_name));
|
||
left_items.forEach(y => this.alive.push(y.fam_name));
|
||
mid_left.forEach(y => this.leftProperTitle.push(y.fam_name));
|
||
mid_right.forEach(y => this.rightProperTitle.push(y.fam_name));
|
||
this.address = address;
|
||
}
|
||
|
||
if (this.selectedTemplate.style_id) {
|
||
this.selectStyle.style = this.selectedTemplate.style_id;
|
||
this.selected.style = this.selectedTemplate.style_id;
|
||
$("#styleSel").val(this.selectedTemplate.style_id);
|
||
}
|
||
this.render();
|
||
},
|
||
async minusZoomScalee() {
|
||
this.zoomScale = Math.max(0, this.zoomScale - 0.05);
|
||
$("#scaleSize").html(Math.floor(this.zoomScale * 100) + "%");
|
||
$("#scaleSlider").val(this.zoomScale);
|
||
$(".tablet-paper").css("transform", `scale(${this.zoomScale})`);
|
||
},
|
||
async plusZoomScalee() {
|
||
this.zoomScale = Math.min(1.0, this.zoomScale + 0.05);
|
||
$("#scaleSize").html(Math.floor(this.zoomScale * 100) + "%");
|
||
$("#scaleSlider").val(this.zoomScale);
|
||
$(".tablet-paper").css("transform", `scale(${this.zoomScale})`);
|
||
},
|
||
async getActItem() {
|
||
await axios.post('/api/tablet/GetActItem', { itemNum: this.actitem }).then(response => {
|
||
if (response.data.result == "Y" && response.data.data) {
|
||
this.pageSize = response.data.data.pageSize;
|
||
this.defaultStyle = response.data.data.defaultStyle;
|
||
this.selected.style = response.data.data.defaultStyle;
|
||
this.selectStyle.style = response.data.data.defaultStyle;
|
||
$("#styleSel").val(this.defaultStyle);
|
||
}
|
||
});
|
||
},
|
||
async getAllStyleDetails() {
|
||
this.allStyleDetails.length = 0;
|
||
await axios.post('/api/tablet/GetStyleDetailData', {}).then(response => {
|
||
if (response.status == "200" && response.data.result == "Y") {
|
||
this.allStyleDetails = response.data.data;
|
||
}
|
||
});
|
||
},
|
||
async getPaperSize() {
|
||
this.allSize.length = 0;
|
||
await axios.post('/api/tablet/GetPaperSize', {}).then(response => {
|
||
if (response.status == "200") {
|
||
this.allSize = response.data.data;
|
||
}
|
||
});
|
||
},
|
||
async getTabletElement() {
|
||
this.tabletElement.length = 0;
|
||
await axios.post('/api/tablet/GetTabletElement', {}).then(response => {
|
||
if (response.status == "200") {
|
||
this.tabletElement = response.data.data;
|
||
}
|
||
});
|
||
},
|
||
async getTabletStyles() {
|
||
this.allStyle.length = 0;
|
||
await axios.post('/api/tablet/GetStyleData', {}).then(response => {
|
||
if (response.status == "200" && response.data.data) {
|
||
response.data.data.forEach(x => {
|
||
if (x.styleID !== "000001") {
|
||
this.allStyle.push(x);
|
||
$("#styleSel").append(`<option value="${x.styleID}">${x.name}</option>`);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
},
|
||
async getData() {
|
||
this.printData.length = 0;
|
||
this.properTitle.length = 0; this.leftProperTitle.length = 0; this.rightProperTitle.length = 0; this.alive.length = 0;
|
||
let param = [{ order_no: this.tabletItem.order_no, num: this.tabletItem.num }];
|
||
|
||
await axios.post('/api/orderdetail/GetDetailToPrint', { param: param }).then(response => {
|
||
if (response.status == 200) {
|
||
this.printData = response.data;
|
||
this.printData.forEach(x => {
|
||
if (x.style != null && x.style != undefined) {
|
||
this.selectStyle.style = x.style;
|
||
this.selected.style = x.style;
|
||
this.defaultStyle = x.style;
|
||
$("#styleSel").val(x.style);
|
||
}
|
||
if (x.f_num_tablet != "") {
|
||
let tablet = JSON.parse(x.f_num_tablet);
|
||
let mid_items = tablet?.mid_items;
|
||
let left_items = tablet?.left_items;
|
||
let mid_left = tablet?.mid_left;
|
||
let mid_right = tablet?.mid_right;
|
||
let address = tablet?.addr_items === undefined ? "" : tablet?.addr_items;
|
||
if (address === "" && x.address != "") {
|
||
address = x.address;
|
||
}
|
||
this.family_deceased_Y_selected.length = 0;
|
||
this.family_deceased_N_selected.length = 0;
|
||
this.family_left_title.length = 0;
|
||
this.family_right_title.length = 0;
|
||
|
||
Object.assign(this.family_deceased_N_selected, mid_items);
|
||
Object.assign(this.family_deceased_Y_selected, left_items);
|
||
Object.assign(this.family_left_title, mid_left);
|
||
Object.assign(this.family_right_title, mid_right);
|
||
this.family_address = address;
|
||
|
||
if (mid_items) mid_items.forEach(y => this.properTitle.push(y.fam_name));
|
||
if (mid_left) mid_left.forEach(y => this.leftProperTitle.push(y.fam_name));
|
||
if (mid_right) mid_right.forEach(y => this.rightProperTitle.push(y.fam_name));
|
||
if (address) this.address = address;
|
||
if (left_items) left_items.forEach(y => this.alive.push(y.fam_name));
|
||
}
|
||
});
|
||
this.render();
|
||
}
|
||
});
|
||
},
|
||
async render() {
|
||
$(".printArea").empty();
|
||
$(".selectedItem").empty();
|
||
$(".canselectItem").empty();
|
||
this.tabletType = "A";
|
||
let canvas = $(`<div class="canvas-area flex-grow-1 overflow-auto d-flex flex-row align-items-center position-relative"></div>`);
|
||
let tabletpaper;
|
||
|
||
let mid = [...this.properTitle];
|
||
let left = [...this.alive];
|
||
let ltitle = [...this.leftProperTitle];
|
||
let rtitle = [...this.rightProperTitle];
|
||
let myAddress = this.address != "" ? [this.address] : [];
|
||
|
||
let x = this.selectStyle;
|
||
let style = this.allStyle.find(y => y.styleID == (x.style ? x.style : $("#styleSel").val()));
|
||
if (!x.style) {
|
||
this.selectStyle.style = style.styleID;
|
||
this.selected.style = style.styleID;
|
||
}
|
||
|
||
let size = this.allSize.find(y => y.paperID == style.paperSize);
|
||
let pageSize = this.allSize.find(y => y.paperID == style.paperSize);
|
||
let printSize = this.allSize.find(y => y.paperID == style.printSize);
|
||
tabletpaper = $(`<div class="tablet-paper" style="transform-origin:top left;transform:scale(${this.zoomScale})"></div>`);
|
||
let img = this.bg.find(y => y.name == style.backendImg);
|
||
let details = this.allStyleDetails.filter(y => y.styleID == style.styleID);
|
||
let ancestorFontSize = 16;
|
||
|
||
details.forEach(d => {
|
||
if (d.isActive != "hidden") {
|
||
let element = this.tabletElement.find(y => y.elementID == d.elementID);
|
||
let newFontSize = this.scaleFontSize(mid, d.fontSize, d.width);
|
||
let html = "";
|
||
|
||
if (d.elementID === 'title1') {
|
||
if (mid.length == 0) mid.push("請選擇");
|
||
let th = Number(d.textHeight) || 0;
|
||
let span = Number(d.textSpan) || 0;
|
||
let namesPerCol = Math.max(1, Math.floor((Number(d.height) + span) / (th + span)));
|
||
let cols = Math.max(1, Math.ceil(mid.length / namesPerCol));
|
||
let colWidth = Math.floor(Number(d.width) / cols);
|
||
html = this.renderNameList(mid, d, newFontSize, style, colWidth);
|
||
} else if (d.elementID === "alive") {
|
||
this.tabletType = "B";
|
||
if (left.length == 0) left.push("請選擇");
|
||
newFontSize = d.fontSize;
|
||
html = this.renderLiveList(left, d);
|
||
} else if (d.elementID === "titletriangle") {
|
||
if (mid.length == 0) mid.push("請選擇");
|
||
html = this.renderRoster(mid, d);
|
||
} else if (d.elementID === "combined" || d.elementID === "tricombined") {
|
||
ancestorFontSize = d.fontSize;
|
||
if (mid.length == 0) mid.push("請選擇");
|
||
html = this.renderCombined(mid, d);
|
||
} else if (d.elementID === "lefttitle") {
|
||
if (ltitle.length == 0) ltitle.push("請選擇");
|
||
html = this.renderNormalWithSpace(ltitle, d);
|
||
} else if (d.elementID === "righttitle") {
|
||
if (rtitle.length == 0) rtitle.push("請選擇");
|
||
html = this.renderNormalWithSpace(rtitle, d);
|
||
} else if (d.elementID == "address") {
|
||
if (myAddress.length == 0) myAddress.push("請選擇");
|
||
html = this.renderNormal(myAddress.join(""), d);
|
||
}
|
||
|
||
if (newFontSize < 10) newFontSize = 10;
|
||
|
||
let content = $(`<div class="tablet-element vertical-text ">${element.sampleContent}</div>`).css({
|
||
position: "absolute", left: d.startX + "mm", top: d.startY + "mm", fontSize: newFontSize + 'px',
|
||
fontFamily: d.fontFamily, "font-weight": "bold", "z-index": 9999, visibility: d.isActive, "align-items": "center"
|
||
}).html(html);
|
||
tabletpaper.append(content);
|
||
}
|
||
});
|
||
|
||
let pageStyle = `<style id="pageStyle">
|
||
* { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; color-adjust: exact !important; }
|
||
.vertical-text { writing-mode: vertical-rl !important; -webkit-writing-mode: vertical-rl !important; text-orientation: mixed !important; }
|
||
body { overflow: visible !important; }
|
||
@media print {
|
||
:host { width:auto !important; height:auto !important; }
|
||
@page { size:${printSize.width}mm ${printSize.height}mm !important; margin:0; }
|
||
html, body, form, .full-home, .printArea, .canvas-area { height: auto !important; width: auto !important; overflow: visible !important; margin: 0 !important; padding: 0 !important; display: block !important; }
|
||
.no-print, #customMenu { display: none !important; }
|
||
.canvas-area { display:flex !important; flex-direction: row !important; justify-content:center !important; align-items:center !important; }
|
||
.tablet-paper { position: relative !important; display: block !important; break-inline:avoid; page-break-inline:avoid; break-after: page !important; page-break-after: always !important; margin: 0 !important; border: none !important; background-repeat: no-repeat; background-size: 100% 100%; }
|
||
.tablet-element { position: absolute !important; white-space: normal; color: black !important; }
|
||
}
|
||
.roster-container { width: 100%; height: 100%; writing-mode: vertical-rl; display: flex; flex-direction: row; align-items: center; justify-content: center; gap: 20px; }
|
||
.roster-row { display: flex; flex-direction: row-reverse; justify-content: center; gap: 8px; margin-left: 10px; }
|
||
.name-group { display: flex; flex-direction: column; justify-content: center; align-items: center; }
|
||
.roster-name { text-orientation: upright; white-space: normal; line-height: 1.2; font-family: DFKai-sb; width: fit-content; }
|
||
.ancestor-wrapper { writing-mode: horizontal-tb; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; width: fit-content; }
|
||
.main-name { line-height: 1.2; }
|
||
.sub-text { font-size: ${ancestorFontSize}px; line-height: 1.2; margin-top: 4px; white-space: normal; writing-mode:vertical-rl; }
|
||
.canvas-area { width: ${pageSize.width}mm; height: ${pageSize.height}mm; break-after: page; page-break-after: always; display:flex !important; justify-content:center; }
|
||
.tablet-paper { background-color: white; display: inline-block; width: ${size.width}mm !important; height: ${size.height}mm !important; position: relative; margin-bottom: 0; background-image: url(${img.path}); background-size: 100% 100%; break-inline:avoid; page-break-inline:avoid; }
|
||
.tablet-element { cursor: move; padding: 4px; color: black !important; border: 1px solid transparent; transition: writing-mode 0.3s, transform 0.2s; }
|
||
.tablet-element:hover { border-color: rgba(13, 110, 253, 0.3); }
|
||
.tablet-paper:last-child { page-break-after: auto; }
|
||
.tablet-element span { z-index: 999; }
|
||
.selectedItem .canselectItem { font-size: 18px; }
|
||
.selectedItem, .rounded-pill .canselectItem, .rounded-pill { font-size: 12px; }
|
||
</style>`;
|
||
|
||
$("#pageStyle").remove();
|
||
$("head").append(pageStyle);
|
||
$(canvas).append(tabletpaper);
|
||
$(".printArea").append(canvas);
|
||
|
||
$(".tablet-element").on("click", (e) => {
|
||
e.preventDefault();
|
||
this.selectedElement = $(e.currentTarget);
|
||
let element = $(e.currentTarget).children().first();
|
||
this.renderItem(element);
|
||
});
|
||
},
|
||
async renderItem(element) {
|
||
$(".selectedItem").empty();
|
||
$(".canselectItem").empty();
|
||
|
||
if (element.hasClass("liveList")) {
|
||
this.alive.forEach(x => {
|
||
let f = this.familyMembers.find(z => z.fam_name == x);
|
||
$(".selectedItem").append(`<li><span style="opacity:0.5">卍</span>
|
||
<span class="selected">${x}</span>
|
||
<span><i class="rounded-pill rounded-3 ${(f && f.fam_title) ? 'p-1' : ''}" style="background-color:lightgray">${(f && f.fam_title) ? f.fam_title : ""}</i></span>
|
||
<span class="itemRemove" style="float:right;margin-left:2rem;cursor:pointer;">−</span>
|
||
<span class="itemUp" style="float:right;margin-left:2rem;cursor:pointer;">↑</span>
|
||
<span class="itemDown" style="float:right;margin-left:2rem;cursor:pointer;">↓</span></li>`);
|
||
});
|
||
|
||
let items = this.familyMembers.filter(x => x.deceased == false).map(x => x.fam_name);
|
||
let finalItem = items.filter(y => !this.alive.includes(y));
|
||
|
||
finalItem.forEach(yy => {
|
||
let f = this.familyMembers.find(z => z.fam_name == yy);
|
||
$(".canselectItem").append(`<li><span style="opacity:0.5">卍</span> <span class="unselect">${yy}</span>
|
||
<span><i class="rounded-pill rounded-3 ${(f && f.fam_title) ? 'p-1' : ''}" style="background-color:lightgray">${(f && f.fam_title) ? f.fam_title : ""}</i></span>
|
||
<span class='itemAppend' style="float:right;cursor:pointer;">+</span></li>`);
|
||
});
|
||
} else if (element.hasClass("address")) {
|
||
$(".selectedItem").append(`<li><span style="opacity:0.5">卍</span>
|
||
<span class="selected">${this.address == undefined ? "" : this.address}</span>
|
||
<span class="itemRemove" style="float:right;margin-left:2rem;cursor:pointer;">−</span>`);
|
||
} else if (element.hasClass("lefttitle")) {
|
||
this.leftProperTitle.forEach(x => {
|
||
let f = this.familyMembers.find(z => z.fam_name == x);
|
||
$(".selectedItem").append(`<li><span style="opacity:0.5">卍</span><span class="selected">${x}</span>
|
||
<span><i class="rounded-pill rounded-3 ${(f && f.fam_title) ? 'p-1' : ''}" style="background-color:lightgray">${(f && f.fam_title) ? f.fam_title : ""}</i></span>
|
||
<span class="itemRemove" style="float:right;margin-left:2rem;cursor:pointer;">−</span>`);
|
||
});
|
||
|
||
let items = this.familyMembers.filter(x => (this.tabletType == "A" && x.deceased == false) || (this.tabletType == "B" && x.deceased == true)).map(x => x.fam_name);
|
||
let finalItem = items.filter(y => !this.leftProperTitle.includes(y));
|
||
|
||
finalItem.forEach(yy => {
|
||
let f = this.familyMembers.find(z => z.fam_name == yy);
|
||
$(".canselectItem").append(`<li><span style="opacity:0.5">卍</span> <span class="unselect">${yy}</span>
|
||
<span><i class="rounded-pill rounded-3 ${(f && f.fam_title) ? 'p-1' : ''}" style="background-color:lightgray">${(f && f.fam_title) ? f.fam_title : ""}</i></span>
|
||
<span class='itemAppend' style="float:right;cursor:pointer;">+</span></li>`);
|
||
});
|
||
} else if (element.hasClass("righttitle")) {
|
||
this.rightProperTitle.forEach(x => {
|
||
let f = this.familyMembers.find(z => z.fam_name == x);
|
||
$(".selectedItem").append(`<li><span style="opacity:0.5">卍</span><span class="selected">${x}</span>
|
||
<span><i class="rounded-pill rounded-3 ${(f && f.fam_title) ? 'p-1' : ''}" style="background-color:lightgray">${(f && f.fam_title) ? f.fam_title : ""}</i></span>
|
||
<span class="itemRemove" style="float:right;margin-left:2rem;cursor:pointer;">−</span>`);
|
||
});
|
||
|
||
let items = this.familyMembers.filter(x => (this.tabletType == "A" && x.deceased == false) || (this.tabletType == "B" && x.deceased == true)).map(x => x.fam_name);
|
||
let finalItem = items.filter(y => !this.rightProperTitle.includes(y));
|
||
|
||
finalItem.forEach(yy => {
|
||
let f = this.familyMembers.find(z => z.fam_name == yy);
|
||
$(".canselectItem").append(`<li><span style="opacity:0.5">卍</span> <span class="unselect">${yy}</span>
|
||
<span><i class="rounded-pill rounded-3 ${(f && f.fam_title) ? 'p-1' : ''}" style="background-color:lightgray">${(f && f.fam_title) ? f.fam_title : ""}</i></span>
|
||
<span class='itemAppend' style="float:right;cursor:pointer;">+</span></li>`);
|
||
});
|
||
} else {
|
||
let hasControls = !element.hasClass("ancestor-wrapper");
|
||
this.properTitle.forEach(y => {
|
||
let f = this.familyMembers.find(z => z.fam_name == y);
|
||
let controlHtml = hasControls ? `<span class="itemUp" style="float:right;margin-left:2rem;cursor:pointer;">↑</span><span class="itemDown" style="float:right;margin-left:2rem;cursor:pointer;">↓</span>` : '';
|
||
$(".selectedItem").append(`<li><span style="opacity:0.5">卍</span><span class="selected">${y}</span>
|
||
<span><i class="rounded-pill rounded-3 ${(f && f.fam_title) ? 'p-1' : ''}" style="background-color:lightgray">${(f && f.fam_title) ? f.fam_title : ""}</i></span>
|
||
<span class="itemRemove" style="float:right;margin-left:2rem;cursor:pointer;">−</span>${controlHtml}</li>`);
|
||
});
|
||
|
||
if (hasControls) {
|
||
let items = this.familyMembers.filter(x => (this.tabletType == "A" && x.deceased == false) || (this.tabletType == "B" && x.deceased == true)).map(x => x.fam_name);
|
||
let finalItem = items.filter(y => !this.properTitle.includes(y));
|
||
finalItem.forEach(yy => {
|
||
let f = this.familyMembers.find(z => z.fam_name == yy);
|
||
$(".canselectItem").append(`<li><span style="opacity:0.5">卍</span> <span class="unselect">${yy}</span>
|
||
<span><i class="rounded-pill rounded-3 ${(f && f.fam_title) ? 'p-1' : ''}" style="background-color:lightgray">${(f && f.fam_title) ? f.fam_title : ""}</i></span>
|
||
<span class='itemAppend' style="float:right;cursor:pointer;">+</span></li>`);
|
||
});
|
||
}
|
||
}
|
||
this.bindEvent();
|
||
},
|
||
async addNewItem() {
|
||
let customVal = $("#custom_txt").val();
|
||
if (customVal == "") {
|
||
alert("名稱不可空白");
|
||
return false;
|
||
}
|
||
|
||
let target = $(this.selectedElement).children().first();
|
||
let error = "";
|
||
|
||
if (target.hasClass("liveList")) {
|
||
if (this.alive.includes(customVal)) error = "名稱已存在";
|
||
if (error) return alert(error), false;
|
||
this.alive.push(customVal);
|
||
this.family_deceased_Y_selected.push({ IsShuWen: false, deceased: false, fam_gender: "", fam_name: customVal, fam_file: "", nospace: true, num: 0, option_break: false });
|
||
} else if (target.hasClass("nameList") || target.hasClass("rosterList")) {
|
||
if (this.properTitle.includes(customVal)) error = "名稱已存在";
|
||
if (error) return alert(error), false;
|
||
this.properTitle.push(customVal);
|
||
this.family_deceased_N_selected.push({ IsShuWen: false, deceased: false, fam_gender: "", fam_name: customVal, fam_file: "", nospace: true, num: 0, option_break: false });
|
||
} else if (target.hasClass("ancestor-wrapper")) {
|
||
if (this.properTitle.includes(customVal)) error = "名稱已存在";
|
||
if (error) return alert(error), false;
|
||
if (this.properTitle.length >= 2) {
|
||
alert("多姓氏合併必須第一個名稱為姓,第二個名稱為氏歷代祖先之類,且最多兩個名稱");
|
||
} else {
|
||
this.properTitle.push(customVal);
|
||
this.family_deceased_N_selected.push({ IsShuWen: false, deceased: false, fam_gender: "", fam_name: customVal, fam_file: "", nospace: true, num: 0, option_break: false });
|
||
}
|
||
} else if (target.hasClass("lefttitle")) {
|
||
if (this.leftProperTitle.includes(customVal)) error = "名稱已存在";
|
||
if (error) return alert(error), false;
|
||
this.leftProperTitle.length = 0;
|
||
this.family_left_title.length = 0;
|
||
this.leftProperTitle.push(customVal);
|
||
this.family_left_title.push({ IsShuWen: false, deceased: false, fam_gender: "", fam_name: customVal, fam_file: "", nospace: true, num: -1, option_break: false });
|
||
} else if (target.hasClass("righttitle")) {
|
||
if (this.rightProperTitle.includes(customVal)) error = "名稱已存在";
|
||
if (error) return alert(error), false;
|
||
this.rightProperTitle.length = 0;
|
||
this.family_right_title.length = 0;
|
||
this.rightProperTitle.push(customVal);
|
||
this.family_right_title.push({ IsShuWen: false, deceased: false, fam_gender: "", fam_name: customVal, fam_file: "", nospace: true, num: 0, option_break: false });
|
||
} else if (target.hasClass("address")) {
|
||
this.address = customVal;
|
||
this.family_address = this.address;
|
||
}
|
||
$("#custom_txt").val("");
|
||
this.renderItem($(this.selectedElement).children().first());
|
||
this.rerenderPart();
|
||
},
|
||
async bindEvent() {
|
||
let self = this;
|
||
$(".itemAppend, .itemRemove, .itemUp, .itemDown").off("click");
|
||
|
||
$(".itemAppend").on("click", function (e) {
|
||
let curr = $(e.currentTarget.parentElement).find(".unselect").first();
|
||
let target = self.familyMembers.find(x => x.fam_name == curr.text());
|
||
if (target) {
|
||
let elClass = $(self.selectedElement).children().first();
|
||
let obj = { IsShuWen: false, deceased: false, fam_gender: "", fam_name: target.fam_name, fam_file: "", nospace: true, num: target.num, option_break: false };
|
||
|
||
if (elClass.hasClass("liveList")) {
|
||
if (self.tabletItem.has_yang_limit && self.tabletItem.yang_limit_count > 0 && self.alive.length + 1 > self.tabletItem.yang_limit_count) {
|
||
$("#toast_body").html(`陽上人數不得超過${self.tabletItem.yang_limit_count}人`); self.toast.show(); return;
|
||
}
|
||
self.alive.push(target.fam_name);
|
||
self.family_deceased_Y_selected.push(obj);
|
||
} else if (elClass.hasClass("nameList") || elClass.hasClass("rosterList")) {
|
||
if (self.tabletItem.has_chao_limit && self.tabletItem.chao_limit_count > 0 && self.properTitle.length + 1 > self.tabletItem.chao_limit_count) {
|
||
$("#toast_body").html(`祈福或超渡人數不得超過${self.tabletItem.chao_limit_count}人`); self.toast.show(); return;
|
||
}
|
||
self.properTitle.push(target.fam_name);
|
||
self.family_deceased_N_selected.push(obj);
|
||
} else if (elClass.hasClass("lefttitle")) {
|
||
self.leftProperTitle.push(target.fam_name);
|
||
self.family_left_title.push(obj);
|
||
} else if (elClass.hasClass("righttitle")) {
|
||
self.rightProperTitle.push(target.fam_name);
|
||
self.family_right_title.push(obj);
|
||
}
|
||
}
|
||
self.renderItem($(self.selectedElement).children().first());
|
||
self.rerenderPart();
|
||
});
|
||
|
||
$(".itemRemove").on("click", function (e) {
|
||
let currName = $(e.currentTarget.parentElement).find(".selected").first().text();
|
||
let elClass = $(self.selectedElement).children().first();
|
||
|
||
if (elClass.hasClass("liveList")) {
|
||
self.alive = self.alive.filter(x => x !== currName);
|
||
self.family_deceased_Y_selected = self.family_deceased_Y_selected.filter(x => x.fam_name != currName);
|
||
} else if (elClass.hasClass("nameList") || elClass.hasClass("rosterList") || elClass.hasClass("ancestor-wrapper")) {
|
||
self.properTitle = self.properTitle.filter(x => x !== currName);
|
||
self.family_deceased_N_selected = self.family_deceased_N_selected.filter(x => x.fam_name != currName);
|
||
} else if (elClass.hasClass("address")) {
|
||
self.address = currName; self.family_address = currName;
|
||
} else if (elClass.hasClass("lefttitle")) {
|
||
self.leftProperTitle = self.leftProperTitle.filter(x => x !== currName);
|
||
self.family_left_title = self.family_left_title.filter(x => x.fam_name !== currName);
|
||
} else if (elClass.hasClass("righttitle")) {
|
||
self.rightProperTitle = self.rightProperTitle.filter(x => x !== currName);
|
||
self.family_right_title = self.family_right_title.filter(x => x.fam_name !== currName);
|
||
}
|
||
self.renderItem($(self.selectedElement).children().first());
|
||
self.rerenderPart();
|
||
});
|
||
|
||
$(".itemUp").on("click", function (e) {
|
||
let currName = $(e.currentTarget.parentElement).find(".selected").first().text();
|
||
let elClass = $(self.selectedElement).children().first();
|
||
|
||
const swap = (arr, i) => { if (i > 0) [arr[i - 1], arr[i]] = [arr[i], arr[i - 1]]; };
|
||
|
||
if (elClass.hasClass("liveList")) {
|
||
let idx = self.alive.indexOf(currName);
|
||
swap(self.alive, idx); swap(self.family_deceased_Y_selected, idx);
|
||
} else if (elClass.hasClass("nameList") || elClass.hasClass("rosterList") || elClass.hasClass("ancestor-wrapper")) {
|
||
let idx = self.properTitle.indexOf(currName);
|
||
swap(self.properTitle, idx); swap(self.family_deceased_N_selected, idx);
|
||
} else if (elClass.hasClass("lefttitle")) {
|
||
let idx = self.leftProperTitle.indexOf(currName);
|
||
swap(self.leftProperTitle, idx); swap(self.family_left_title, idx);
|
||
} else if (elClass.hasClass("righttitle")) {
|
||
let idx = self.rightProperTitle.indexOf(currName);
|
||
swap(self.rightProperTitle, idx); swap(self.family_right_title, idx);
|
||
}
|
||
self.renderItem($(self.selectedElement).children().first());
|
||
self.rerenderPart();
|
||
});
|
||
|
||
$(".itemDown").on("click", function (e) {
|
||
let currName = $(e.currentTarget.parentElement).find(".selected").first().text();
|
||
let elClass = $(self.selectedElement).children().first();
|
||
|
||
const swap = (arr, i) => { if (i > -1 && i < arr.length - 1) [arr[i], arr[i + 1]] = [arr[i + 1], arr[i]]; };
|
||
|
||
if (elClass.hasClass("liveList")) {
|
||
let idx = self.alive.indexOf(currName);
|
||
swap(self.alive, idx); swap(self.family_deceased_Y_selected, idx);
|
||
} else if (elClass.hasClass("nameList") || elClass.hasClass("rosterList") || elClass.hasClass("ancestor-wrapper")) {
|
||
let idx = self.properTitle.indexOf(currName);
|
||
swap(self.properTitle, idx); swap(self.family_deceased_N_selected, idx);
|
||
} else if (elClass.hasClass("lefttitle")) {
|
||
let idx = self.leftProperTitle.indexOf(currName);
|
||
swap(self.leftProperTitle, idx); swap(self.family_left_title, idx);
|
||
} else if (elClass.hasClass("righttitle")) {
|
||
let idx = self.rightProperTitle.indexOf(currName);
|
||
swap(self.rightProperTitle, idx); swap(self.family_right_title, idx);
|
||
}
|
||
self.renderItem($(self.selectedElement).children().first());
|
||
self.rerenderPart();
|
||
});
|
||
},
|
||
async rerenderPart() {
|
||
let x = this.selectStyle;
|
||
let style = this.allStyle.find(y => y.styleID == x.style);
|
||
let details = this.allStyleDetails.filter(y => y.styleID == x.style);
|
||
let elClass = $(this.selectedElement).children().first();
|
||
|
||
$(this.selectedElement).empty();
|
||
|
||
if (elClass.hasClass("liveList")) {
|
||
let d = details.find(y => y.elementID == "alive");
|
||
$(this.selectedElement).append(this.renderLiveList([...this.alive], d));
|
||
} else if (elClass.hasClass("lefttitle")) {
|
||
let d = details.find(y => y.elementID == "lefttitle");
|
||
$(this.selectedElement).append(this.renderNormalWithSpace([...this.leftProperTitle], d));
|
||
} else if (elClass.hasClass("righttitle")) {
|
||
let d = details.find(y => y.elementID == "righttitle");
|
||
$(this.selectedElement).append(this.renderNormalWithSpace([...this.rightProperTitle], d));
|
||
} else if (elClass.hasClass("address")) {
|
||
let d = details.find(y => y.elementID == "address");
|
||
$(this.selectedElement).append(this.renderNormal([this.address], d));
|
||
} else {
|
||
let mid = [...this.properTitle];
|
||
if (elClass.hasClass("nameList")) {
|
||
let d = details.find(y => y.elementID == "title1");
|
||
let newfontSize = this.scaleFontSize(mid, d.fontSize, d.textWidth);
|
||
this.selectedElement.css("font-size", newfontSize + "px");
|
||
$(this.selectedElement).append(this.renderNameList(mid, d, style.fontSize, style, 0));
|
||
} else if (elClass.hasClass("rosterList")) {
|
||
let d = details.find(y => y.elementID == "titletriangle");
|
||
let newfontSize = Math.max(10, this.scaleFontSize(mid, d.fontSize, d.textWidth));
|
||
this.selectedElement.css("font-size", newfontSize + "px");
|
||
$(this.selectedElement).append(this.renderRoster(mid, d));
|
||
} else if (elClass.hasClass("ancestor-wrapper")) {
|
||
let d = details.find(y => y.elementID == "combined");
|
||
let newfontSize = Math.max(10, this.scaleFontSize(mid, d.fontSize, d.textWidth));
|
||
this.selectedElement.css("font-size", newfontSize + "px");
|
||
$(this.selectedElement).append(this.renderCombined(mid, d));
|
||
}
|
||
}
|
||
},
|
||
countFontSize(name, el, fontSize, rows) {
|
||
if (Number(name.length) * 2 * Number(fontSize) > el.height) {
|
||
fontSize = Number(fontSize) - 2;
|
||
let rowWidth = Math.floor(Number(el.width) / (rows + 1));
|
||
fontSize = Math.floor(rowWidth / 2);
|
||
let finalSize = this.countFontSize(name, el, fontSize, rows + 1);
|
||
return finalSize === 0 ? fontSize : finalSize;
|
||
}
|
||
return 0;
|
||
},
|
||
calcIndividualFontSize(name, el, maxW) {
|
||
let s = Number(el.style ? el.style.fontSize : (el.fontSize ? el.fontSize : 18));
|
||
let maxH = Number(el.textHeight);
|
||
let l = Number(name.length);
|
||
|
||
while (s >= 12) {
|
||
let s_px = s * 1.333;
|
||
let charsPerCol = Math.max(1, Math.floor(maxH / s_px));
|
||
let cols = Math.ceil(l / charsPerCol);
|
||
let neededWidth = (cols === 1) ? s_px : cols * (s_px * 1.1);
|
||
|
||
if (neededWidth <= maxW && (cols > 1 || l * s_px <= maxH)) {
|
||
return s;
|
||
}
|
||
s -= 1;
|
||
}
|
||
return 12;
|
||
},
|
||
changeStyle() {
|
||
this.selected.style = $("#styleSel").val();
|
||
this.selectStyle.style = $("#styleSel").val();
|
||
this.render();
|
||
},
|
||
renderNormalWithSpace(mid, d) {
|
||
let txt = $(`<div class='${d.elementID}'></div>`).css({
|
||
"z-index": 9999, visibility: d.visibility, width: d.width, height: d.height, padding: "1px",
|
||
"writing-mode": "vertical-rl", display: "flex", "flex-direction": "row", "flex-wrap": "wrap", margin: "auto",
|
||
"column-gap": `${d.textSpan}px`, "align-items": "flex-start", "justify-content": "start"
|
||
});
|
||
mid.forEach(x => {
|
||
$(txt).append($(`<div>${x}</div>`).css({ "margin-bottom": "10px", "margin-left": "5px", "text-justify": "inter-character", "white-space": "pre-line" }));
|
||
});
|
||
return txt;
|
||
},
|
||
renderNormal(mid, d) {
|
||
return $(`<div class='${d.elementID}'>${mid}</div>`).css({ "z-index": 9999, visibility: d.visibility, width: d.width, height: d.height });
|
||
},
|
||
/*renderNameList(names, d, newFontSize, style, colWidth) {
|
||
let h = parseFloat(d.height), w = parseFloat(d.width), th = parseFloat(d.textHeight) || h;
|
||
let v_gap = parseFloat(d.textSpan) || 0, h_gap = 5;
|
||
let shrinkLimit = h < 300 ? 12 : (h < 500 ? 8 : 6);
|
||
let long_s = parseFloat(d.fontSize), short_s = parseFloat(d.fontSize);
|
||
|
||
let testNames = [...names];
|
||
if (h<500&&testNames.length == 1 && testNames[0].includes("暨無始劫以來累世冤親債主")) testNames[0] = testNames[0].split("暨")[0] + "暨";
|
||
|
||
let items = testNames.map(name => ({ name: name, l: name.length, isShort: (testNames.length > 1) && ((name.length * 40) <= (th + (v_gap / 2))), isMulti: false, size: 0 }));
|
||
let sizes = [], shrink_turn = 'long';
|
||
|
||
while (true) {
|
||
let cols_width = [], current_col_h = 0, current_col_w = 0, any_wrapped = false;
|
||
for (let item of items) {
|
||
let s = item.isShort ? short_s : long_s;
|
||
if (item.isShort) s = Math.min(s, Math.floor(th / (item.l * 1.333)));
|
||
item.size = s;
|
||
let size_px = s * 1.333;
|
||
|
||
if (item.isShort) {
|
||
let item_h = Math.max(th, item.l * size_px);
|
||
if (current_col_h === 0) { current_col_h = item_h; current_col_w = size_px; }
|
||
else if ((current_col_h + v_gap + item_h) <= h) { current_col_h += (v_gap + item_h); current_col_w = Math.max(current_col_w, size_px); }
|
||
else { cols_width.push(current_col_w); current_col_h = item_h; current_col_w = size_px; }
|
||
} else {
|
||
if (current_col_h > 0) { cols_width.push(current_col_w); current_col_h = 0; current_col_w = 0; }
|
||
let item_w = size_px;
|
||
if ((item.l * size_px) > (h - 10)) {
|
||
item.isMulti = true; any_wrapped = true;
|
||
item_w = Math.ceil(item.l / Math.max(1, Math.floor((h - 10) / size_px))) * (size_px * 1.1);
|
||
} else { item.isMulti = false; }
|
||
cols_width.push(item_w);
|
||
}
|
||
}
|
||
if (current_col_h > 0) cols_width.push(current_col_w);
|
||
|
||
if (cols_width.reduce((a, b) => a + b, 0) + (cols_width.length > 1 ? (cols_width.length - 1) * h_gap : 0) <= w && (!any_wrapped || long_s === shrinkLimit)) {
|
||
sizes = items.map(x => ({ name: x.name, size: x.isShort ? Math.min(x.size, Math.floor(th / (x.l * 1.333))) : x.size, isMulti: x.isMulti, isShort: x.isShort }));
|
||
break;
|
||
}
|
||
|
||
if (any_wrapped && long_s > shrinkLimit) long_s--;
|
||
else {
|
||
let hasLong = items.some(x => !x.isShort), hasShort = items.some(x => x.isShort);
|
||
if (hasLong && hasShort) {
|
||
if (shrink_turn === 'long') { if (long_s > shrinkLimit) { long_s--; shrink_turn = 'short'; } else if (short_s > shrinkLimit) { short_s--; shrink_turn = 'long'; } else break; }
|
||
else { if (short_s > shrinkLimit) { short_s--; shrink_turn = 'long'; } else if (long_s > shrinkLimit) { long_s--; shrink_turn = 'short'; } else break; }
|
||
} else if (hasLong) { if (long_s > shrinkLimit) long_s--; else break; }
|
||
else { if (short_s > shrinkLimit) short_s--; else break; }
|
||
}
|
||
}
|
||
|
||
if (sizes.length === 0) sizes = names.map(name => ({ name: name, size: shrinkLimit, isMulti: false, isShort: true }));
|
||
|
||
let $namelist = $(`<div class='nameList'></div>`).css({ "writing-mode": "vertical-rl", display: "flex", "flex-direction": "row", "flex-wrap": "wrap", "align-content": "center", "align-items": "center", margin: "auto", width: `${w}px`, height: `${h}px`, border: "0px solid transparent", padding: "1px", "column-gap": `${v_gap}px`, "font-family": d.fontFamily });
|
||
sizes.forEach(item => {
|
||
let alignStyle = item.isMulti || (!item.isMulti && !item.isShort) ? "start" : "justify";
|
||
$namelist.append($(`<span style="font-size: ${item.size}pt;">${item.name}</span>`).css({ display: "block", "min-height": item.isShort ? `${th}px` : `${h}px`, "max-height": `${h}px`, width: "auto", "line-height": "1.1", "text-align": alignStyle, "text-align-last": alignStyle, "margin-left": "5px", "text-justify": "inter-character", "word-break": "break-all" }));
|
||
});
|
||
|
||
return $namelist;
|
||
},*/
|
||
renderNameList(names, d, newFontSize, style, colWidth) {
|
||
let h = Number(d.height);
|
||
let w = Number(d.width);
|
||
let th = Number(d.textHeight) || h;
|
||
let v_gap = Number(d.textSpan) || 0;
|
||
let h_gap = 5;
|
||
let shrinkLimit = 6;
|
||
|
||
if (h < 500) {
|
||
shrinkLimit = 8;
|
||
} else if (h < 300) {
|
||
shrinkLimit = 12;
|
||
}
|
||
|
||
let long_s = Number(d.fontSize);
|
||
let short_s = Number(d.fontSize);
|
||
|
||
let renderNames = [...names];
|
||
|
||
if (h < 500 && renderNames.length == 1 && renderNames[0].includes("暨無始劫以來累世冤親債主")) {
|
||
renderNames = renderNames[0].split("暨");
|
||
renderNames[0] = renderNames[0] + "暨";
|
||
}
|
||
|
||
let items = renderNames.map(name => {
|
||
let l = name.length;
|
||
let isShort = (l * 40) <= (th + (v_gap / 2));
|
||
return { name: name, l: l, isShort: isShort, isMulti: false, size: 0 };
|
||
});
|
||
|
||
let maxShortLen = Math.max(...items.filter(x => x.isShort).map(x => x.l), 1);
|
||
let allShort = items.every(x => x.isShort);
|
||
let fitsInHalf = items.every(x => (x.l * short_s * 1.333) <= (h / 2));
|
||
|
||
let isSpecial1 = allShort && fitsInHalf && items.length === 1;
|
||
let isSpecial2 = allShort && fitsInHalf && items.length === 2;
|
||
let isSpecial4 = allShort && fitsInHalf && (items.length === 4 || items.length === 6 || items.length === 8);
|
||
let isSpecial = isSpecial1 || isSpecial2 || isSpecial4;
|
||
|
||
let sizes = [];
|
||
let shrink_turn = 'long';
|
||
|
||
while (true) {
|
||
let totalWidth = 0;
|
||
let current_col_h = 0;
|
||
let current_col_w = 0;
|
||
let cols_width = [];
|
||
let any_wrapped = false;
|
||
|
||
for (let i = 0; i < items.length; i++) {
|
||
let item = items[i];
|
||
let s = item.isShort ? short_s : long_s;
|
||
item.size = s;
|
||
let size_px = s * 1.333;
|
||
|
||
if (item.isShort) {
|
||
let item_h = Math.max(th, maxShortLen * size_px);
|
||
|
||
if (isSpecial) {
|
||
if (isSpecial1 || isSpecial2) item_h = h / 2;
|
||
if (isSpecial4) item_h = (h / 2) - (v_gap / 2);
|
||
} else {
|
||
let natural_h = maxShortLen * size_px;
|
||
if (item_h > natural_h * 1.5) {
|
||
item_h = natural_h * 1.5;
|
||
}
|
||
}
|
||
|
||
if (current_col_h === 0) {
|
||
current_col_h = item_h;
|
||
current_col_w = size_px;
|
||
} else if ((current_col_h + v_gap + item_h) <= h) {
|
||
current_col_h += (v_gap + item_h);
|
||
if (size_px > current_col_w) current_col_w = size_px;
|
||
} else {
|
||
cols_width.push(current_col_w);
|
||
current_col_h = item_h;
|
||
current_col_w = size_px;
|
||
}
|
||
} else {
|
||
if (current_col_h > 0) {
|
||
cols_width.push(current_col_w);
|
||
current_col_h = 0;
|
||
current_col_w = 0;
|
||
}
|
||
|
||
let item_w = size_px;
|
||
|
||
if ((item.l * size_px) > (h - 10)) {
|
||
item.isMulti = true;
|
||
any_wrapped = true;
|
||
|
||
let chars_per_col = Math.floor((h - 10) / size_px);
|
||
if (chars_per_col < 1) chars_per_col = 1;
|
||
let item_cols = Math.ceil(item.l / chars_per_col);
|
||
item_w = item_cols * (size_px * 1.1);
|
||
} else {
|
||
item.isMulti = false;
|
||
}
|
||
|
||
cols_width.push(item_w);
|
||
}
|
||
}
|
||
|
||
if (current_col_h > 0) cols_width.push(current_col_w);
|
||
|
||
totalWidth = cols_width.reduce((a, b) => a + b, 0) + (cols_width.length > 1 ? (cols_width.length - 1) * h_gap : 0);
|
||
|
||
if (totalWidth <= w && (!any_wrapped || long_s === shrinkLimit)) {
|
||
sizes = items.map(x => {
|
||
let final_s = x.size;
|
||
if (x.isShort) {
|
||
let max_s_for_th = Math.floor(th / (maxShortLen * 1.333));
|
||
if (final_s > max_s_for_th) {
|
||
final_s = max_s_for_th;
|
||
}
|
||
}
|
||
return { name: x.name, size: final_s, isMulti: x.isMulti, isShort: x.isShort };
|
||
});
|
||
break;
|
||
}
|
||
|
||
let hasLong = items.some(x => !x.isShort);
|
||
let hasShort = items.some(x => x.isShort);
|
||
|
||
if (hasLong && hasShort) {
|
||
if (shrink_turn === 'long') {
|
||
if (long_s > shrinkLimit) {
|
||
long_s--;
|
||
shrink_turn = 'short';
|
||
} else if (short_s > shrinkLimit) {
|
||
short_s--;
|
||
shrink_turn = 'long';
|
||
} else {
|
||
break;
|
||
}
|
||
} else {
|
||
if (short_s > shrinkLimit) {
|
||
short_s--;
|
||
shrink_turn = 'long';
|
||
} else if (long_s > shrinkLimit) {
|
||
long_s--;
|
||
shrink_turn = 'short';
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
} else if (hasLong) {
|
||
if (long_s > shrinkLimit) {
|
||
long_s--;
|
||
} else {
|
||
break;
|
||
}
|
||
} else {
|
||
if (short_s > shrinkLimit) {
|
||
short_s--;
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (sizes.length === 0) {
|
||
sizes = renderNames.map(name => {
|
||
return { name: name, size: shrinkLimit, isMulti: false, isShort: true };
|
||
});
|
||
}
|
||
|
||
let flexDir = isSpecial2 ? "column" : "row";
|
||
let flexJustify = isSpecial ? "center" : "flex-start";
|
||
let flexAlign = "center";
|
||
|
||
if (isSpecial4) {
|
||
v_gap = Number(h) / 4;
|
||
}
|
||
|
||
let $namelist = $(`<div class='nameList'></div>`).css({
|
||
"writing-mode": "vertical-rl",
|
||
display: "flex",
|
||
"flex-direction": flexDir,
|
||
"flex-wrap": "wrap",
|
||
"align-content": "center",
|
||
"align-items": flexAlign,
|
||
"justify-content": flexJustify,
|
||
margin: "auto",
|
||
width: `${w}px`,
|
||
height: `${h}px`,
|
||
border: "0px solid transparent",
|
||
padding: "1px",
|
||
"column-gap": `${v_gap}px`,
|
||
"font-family": d.fontFamily
|
||
});
|
||
|
||
sizes.forEach(item => {
|
||
let size_px = item.size * 1.333;
|
||
let natural_max_h = maxShortLen * size_px;
|
||
let boxH_num = item.isShort ? Math.max(th, natural_max_h) : h;
|
||
|
||
if (isSpecial) {
|
||
if (isSpecial1 || isSpecial2) boxH_num = h / 2;
|
||
if (isSpecial4) boxH_num = (h / 2) - (v_gap) - 2;
|
||
} else if (item.isShort) {
|
||
if (boxH_num > natural_max_h * 1.5) {
|
||
boxH_num = natural_max_h * 1.5;
|
||
}
|
||
}
|
||
|
||
let minH = `${boxH_num}px`;
|
||
let alignStyle = item.isMulti || (!item.isMulti && !item.isShort) ? "start" : "justify";
|
||
|
||
let spanDisplay = "block";
|
||
let spanJustifyContent = "flex-start";
|
||
|
||
let spanMarginTop = "0px";
|
||
if (isSpecial1 || isSpecial2) {
|
||
spanMarginTop = `-${h / 4}px`;
|
||
}
|
||
|
||
if (isSpecial1 || isSpecial2 || isSpecial4) {
|
||
alignStyle = "justify";
|
||
spanJustifyContent = "space-between";
|
||
}
|
||
|
||
let nameLen = item.name.length;
|
||
let contentH = nameLen * size_px;
|
||
let emptySpace = boxH_num - contentH;
|
||
let gapsCount = nameLen > 1 ? (nameLen - 1) : 1;
|
||
let avgGap = emptySpace / gapsCount;
|
||
|
||
if (!isSpecial && alignStyle === "justify" && avgGap > (size_px * 1.5)) {
|
||
alignStyle = "justify";
|
||
spanDisplay = "block";
|
||
spanJustifyContent = "start";
|
||
}
|
||
|
||
let $span = $(`<span style="font-size: ${item.size}pt;">${item.name}</span>`).css({
|
||
"display": spanDisplay,
|
||
"justify-content": spanJustifyContent,
|
||
"align-items": "center",
|
||
"min-height": minH,
|
||
"max-height": `${h}px`,
|
||
"width": "auto",
|
||
"line-height": "1.1",
|
||
"text-align": alignStyle,
|
||
"text-align-last": alignStyle,
|
||
"margin-left": "5px",
|
||
"margin-top": spanMarginTop,
|
||
"text-justify": "inter-character",
|
||
"word-break": "break-all"
|
||
});
|
||
|
||
$namelist.append($span);
|
||
});
|
||
|
||
return $namelist;
|
||
},
|
||
|
||
/*renderLiveList(names, el) {
|
||
let h = parseFloat(el.height), w = parseFloat(el.width), th = parseFloat(el.textHeight) || h;
|
||
let v_gap = parseFloat(el.textSpan) || 0, h_gap = 5;
|
||
let shrinkLimit = h < 300 ? 8 : (h < 500 ? 6 : 4);
|
||
let s = parseFloat(el.fontSize);
|
||
|
||
while (s >= shrinkLimit) {
|
||
let size_px = s * 1.333, current_col_h = 0, current_col_w = 0, cols_width = [], any_wrapped = false;
|
||
for (let name of names) {
|
||
let item_h = Math.max(th, name.length * size_px);
|
||
if (item_h > (h - 5)) {
|
||
any_wrapped = true;
|
||
if (current_col_h > 0) { cols_width.push(current_col_w); current_col_h = 0; current_col_w = 0; }
|
||
cols_width.push(Math.ceil(name.length / Math.max(1, Math.floor((h - 5) / size_px))) * (size_px * 1.1));
|
||
} else {
|
||
if (current_col_h === 0) { current_col_h = item_h; current_col_w = size_px; }
|
||
else if (current_col_h + v_gap + item_h <= h) { current_col_h += v_gap + item_h; current_col_w = Math.max(current_col_w, size_px); }
|
||
else { cols_width.push(current_col_w); current_col_h = item_h; current_col_w = size_px; }
|
||
}
|
||
}
|
||
if (current_col_h > 0) cols_width.push(current_col_w);
|
||
if (cols_width.reduce((a, b) => a + b, 0) + (cols_width.length > 1 ? (cols_width.length - 1) * h_gap : 0) <= w && (!any_wrapped || s === shrinkLimit)) break;
|
||
s -= 1;
|
||
}
|
||
|
||
s = Math.max(s, shrinkLimit);
|
||
let $namelist = $(`<div class='liveList'></div>`).css({ "writing-mode": "vertical-rl", "display": "flex", "flex-flow": "wrap", "align-content": "center", "align-items": "center", "margin": "auto", "width": `${w}px`, "height": `${h}px`, "border": "0px solid transparent", "padding": "0px", "font-family": el.fontFamily, "column-gap": `${v_gap}px` });
|
||
names.forEach(name => $namelist.append(this.renderLiveSpan(name, el, s)));
|
||
return $namelist;
|
||
},
|
||
|
||
renderLiveSpan(name, el, fontSize) {
|
||
return $(`<span style="font-size: ${fontSize}pt;">${name}</span>`).css({ "display": "block", "min-height": `${parseFloat(el.textHeight) || parseFloat(el.height)}px`, "max-height": `${parseFloat(el.height)}px`, "width": "auto", "text-align": "justify", "text-align-last": "justify", "margin-left": "0px", "text-justify": "inter-character", "word-break": "break-all", "white-space": "pre-line" });
|
||
},*/
|
||
renderLiveList(names, el) {
|
||
let h = parseFloat(el.height);
|
||
let w = parseFloat(el.width);
|
||
let th = parseFloat(el.textHeight) || h;
|
||
|
||
let v_gap = parseFloat(el.textSpan) || 0;
|
||
let h_gap = 5;
|
||
let shrinkLimit = 4;
|
||
|
||
if (Number(el.height) < 300) {
|
||
shrinkLimit = 8;
|
||
} else if (Number(el.height) < 500) {
|
||
shrinkLimit = 6;
|
||
}
|
||
|
||
let s = parseFloat(el.fontSize);
|
||
|
||
if (names.length == 2) {
|
||
h = th + v_gap;
|
||
}
|
||
|
||
let maxLen = Math.max(...names.map(x => x.length), 1);
|
||
|
||
while (s >= shrinkLimit) {
|
||
let size_px = s * 1.333;
|
||
let current_col_h = 0;
|
||
let current_col_w = 0;
|
||
let cols_width = [];
|
||
let any_wrapped = false;
|
||
|
||
for (let i = 0; i < names.length; i++) {
|
||
let l = names[i].length;
|
||
|
||
let natural_max_h = maxLen * size_px;
|
||
let item_h = Math.max(th, natural_max_h);
|
||
|
||
if (item_h > natural_max_h * 1.5) {
|
||
item_h = natural_max_h * 1.5;
|
||
}
|
||
|
||
if (item_h > (h - 5)) {
|
||
any_wrapped = true;
|
||
|
||
if (current_col_h > 0) {
|
||
cols_width.push(current_col_w);
|
||
current_col_h = 0;
|
||
current_col_w = 0;
|
||
}
|
||
|
||
let chars_per_col = Math.floor((h - 5) / size_px);
|
||
if (chars_per_col < 1) chars_per_col = 1;
|
||
|
||
let item_cols = Math.ceil(l / chars_per_col);
|
||
cols_width.push(item_cols * (size_px * 1.1));
|
||
} else {
|
||
if (current_col_h === 0) {
|
||
current_col_h = item_h;
|
||
current_col_w = size_px;
|
||
} else if (current_col_h + v_gap + item_h <= h) {
|
||
current_col_h += v_gap + item_h;
|
||
if (size_px > current_col_w) current_col_w = size_px;
|
||
} else {
|
||
cols_width.push(current_col_w);
|
||
current_col_h = item_h;
|
||
current_col_w = size_px;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (current_col_h > 0) cols_width.push(current_col_w);
|
||
|
||
let totalWidth = cols_width.reduce((a, b) => a + b, 0) + (cols_width.length > 1 ? (cols_width.length - 1) * h_gap : 0);
|
||
|
||
if (totalWidth <= w && (!any_wrapped || s === shrinkLimit)) {
|
||
break;
|
||
}
|
||
|
||
s -= 1;
|
||
}
|
||
|
||
if (s < shrinkLimit) s = shrinkLimit;
|
||
|
||
let $namelist = $(`<div class='liveList'></div>`).css({
|
||
"writing-mode": "vertical-rl",
|
||
"display": "flex",
|
||
"flex-flow": "wrap",
|
||
"align-content": "center",
|
||
"align-items": "center",
|
||
"margin": "auto",
|
||
"width": `${w}px`,
|
||
"height": `${h}px`,
|
||
"border": "0px solid transparent",
|
||
"padding": "0px",
|
||
"font-family": el.fontFamily,
|
||
"column-gap": `${v_gap}px`
|
||
});
|
||
|
||
names.forEach(name => {
|
||
$namelist.append(this.renderLiveSpan(name, el, s, maxLen));
|
||
});
|
||
|
||
return $namelist;
|
||
},
|
||
|
||
renderLiveSpan(name, el, fontSize, maxLen = 1) {
|
||
let h = parseFloat(el.height);
|
||
let th = parseFloat(el.textHeight) || h;
|
||
let size_px = fontSize * 1.333;
|
||
let l = name.length;
|
||
|
||
let natural_max_h = maxLen * size_px;
|
||
let boxH_num = Math.max(th, natural_max_h);
|
||
|
||
if (boxH_num > natural_max_h * 1.5) {
|
||
boxH_num = natural_max_h * 1.5;
|
||
}
|
||
|
||
let minH = `${boxH_num}px`;
|
||
let alignStyle = "justify";
|
||
let spanDisplay = "block";
|
||
let spanJustifyContent = "flex-start";
|
||
|
||
let contentH = l * size_px;
|
||
let emptySpace = boxH_num - contentH;
|
||
let gapsCount = l > 1 ? (l - 1) : 1;
|
||
let avgGap = emptySpace / gapsCount;
|
||
|
||
if (alignStyle === "justify" && avgGap > (size_px * 1.5)) {
|
||
alignStyle = "justify";
|
||
spanDisplay = "block";
|
||
spanJustifyContent = "space-between";
|
||
}
|
||
|
||
return $(`<span style="font-size: ${fontSize}pt;">${name}</span>`).css({
|
||
"display": spanDisplay,
|
||
"justify-content": spanJustifyContent,
|
||
"align-items": "center",
|
||
"min-height": minH,
|
||
"max-height": `${h}px`,
|
||
"width": "auto",
|
||
"text-align": alignStyle,
|
||
"text-align-last": alignStyle,
|
||
"margin-left": "0px",
|
||
"margin-top": "0px",
|
||
"text-justify": "inter-character",
|
||
"word-break": "break-all",
|
||
"white-space": "pre-line"
|
||
});
|
||
},
|
||
|
||
renderRoster(names, el) {
|
||
if (!names.length) return '';
|
||
const mid = names.length === 1 ? 1 : Math.floor(names.length / 2);
|
||
let h = $(`<div class="rosterList"></div>`).css({ width: el.width, height: el.height, "writing-mode": "vertical-rl", display: "flex", "flex-direction": "row", "align-items": "center", "justify-content": "start", gap: "20px" });
|
||
h.append(this.renderNameGroups(names.slice(0, mid), el));
|
||
if (names.slice(mid).length) h.append(this.renderNameGroups(names.slice(mid), el));
|
||
return h;
|
||
},
|
||
|
||
renderCombined(mid, d) {
|
||
const parts = mid.join("\n").split('\n');
|
||
return `<div class="ancestor-wrapper" style="width:${d.width}px !important;height:${d.height}px !important;" >
|
||
<span class="main-name" >${parts[0] || ''}</span>
|
||
<span class="sub-text">${parts[1] || ''}</span>
|
||
</div>`;
|
||
},
|
||
|
||
renderNameGroups(items, el) {
|
||
let g = $(`<div class="rosterspan"></div>`).css({ "display": "flex", "flex-direction": "column", "justify-content": "center", "height": el.textHeight, "white-space": "pre-line" });
|
||
items.forEach(x => g.append($(`<div style="letter-spacing: 10px;text-align: justify; text-align-last: justify;">${x}</div>`)));
|
||
return g;
|
||
},
|
||
|
||
async autoScale(names, base) {
|
||
const max = Math.max(...names.map(n => n.length), 0);
|
||
return max > 5 ? Math.max(base * (5 / max), base * 0.6) : base;
|
||
},
|
||
|
||
scaleFontSize(txtContent, fontSize, elementWidth) {
|
||
let font = this.getTextSize("講", parseInt(fontSize));
|
||
if ((Math.ceil(txtContent.length / 2) * font.width) * 2 > parseFloat(elementWidth)) {
|
||
let newfontSize = parseInt(fontSize) - 1;
|
||
return newfontSize <= 10 ? newfontSize : this.scaleFontSize(txtContent, newfontSize, elementWidth);
|
||
}
|
||
return fontSize;
|
||
},
|
||
|
||
getTextSize(txt, fontsize) {
|
||
let span = document.createElement("span");
|
||
span.style.cssText = `visibility: hidden; position: absolute; font-size: ${fontsize}px; font-family: "";`;
|
||
span.innerText = txt;
|
||
document.body.appendChild(span);
|
||
let result = { width: span.offsetWidth, height: span.offsetHeight };
|
||
document.body.removeChild(span);
|
||
return result;
|
||
},
|
||
|
||
filterToSel() {
|
||
document.querySelectorAll(".canselectItem li").forEach(x => {
|
||
let curr = $(x).children().eq(1);
|
||
if (curr && curr.text().includes($("#filter_txt").val())) {
|
||
$(x).css("display", "");
|
||
} else {
|
||
$(x).css("display", "none");
|
||
}
|
||
});
|
||
},
|
||
|
||
async saveFamily() {
|
||
if (!this.follower_id) return false;
|
||
let detail = { follower_num: this.follower_id, fam_name: $("#family_txt").val(), fam_title: $("#title_txt").val(), deceased: $("#deceased_sel").val() !== "False", num: 0 };
|
||
this.modal.toggle();
|
||
await axios.post('/api/tablet/saveFamily', detail).then(response => {
|
||
if (response.status == 200 && response.data.result == "Y") {
|
||
this.familyMembers.push(response.data.data);
|
||
this.modal.toggle();
|
||
if (this.selectedElement) this.renderItem($(this.selectedElement).children().first());
|
||
$("#toast_body").html("新增成功"); $("#family_txt").val(""); $("#title_txt").val(""); $("#deceased_sel").val("False"); this.toast.show();
|
||
}
|
||
});
|
||
},
|
||
|
||
async save(event) {
|
||
event.preventDefault();
|
||
let tablet = { mid_items: this.family_deceased_N_selected, left_items: this.family_deceased_Y_selected, style: this.selectStyle.style, mid_left: this.family_left_title, mid_right: this.family_right_title, addr_items: this.family_address };
|
||
let detail = {
|
||
num: this.tabletItem.num <= 0 ? null : this.tabletItem.num, order_no: this.tabletItem.order_no, parent_num: this.tabletItem.parent_num, actItem_num: this.tabletItem.actitem_num_selected?.val,
|
||
f_num: this.tabletItem.f_num_selected?.val, f_num_tablet: JSON.stringify(tablet), print_id: this.tabletItem.print_id, address: this.tabletItem.address,
|
||
from_id: this.tabletItem.from_id_selected?.val, from_id_tablet: this.tabletItem.from_id_tablet, start_date: this.tabletItem.category == 1 ? this.tabletItem.start_date : null,
|
||
due_date: this.tabletItem.category == 1 ? this.tabletItem.due_date : null, extend_date: this.tabletItem.category == 1 ? this.tabletItem.extend_date : null,
|
||
price: this.tabletItem.price, qty: this.tabletItem.qty, keyin1: this.tabletItem.keyin1_selected?.val, demo: this.tabletItem.demo, pay: this.tabletItem.pay,
|
||
pay_date: this.tabletItem.pay_date, customize_data: this.tabletItem.customize_data, style: this.selectStyle.style
|
||
};
|
||
await axios.post('/api/order/SaveDetailData', detail).then(() => {
|
||
window.parent.postMessage({ source: 'editorNew.btn.click', data: { tabletItem: this.tabletItem, tablet_data: tablet, style: this.selectStyle.style } }, '/');
|
||
});
|
||
},
|
||
|
||
async resetScreen() {
|
||
$(".printArea").empty(); $(".selectItem").empty(); $(".canselectItem").empty();
|
||
}
|
||
};
|
||
|
||
$(() => $(window).on("message", function (event) {
|
||
let e = event.originalEvent;
|
||
if (e.origin === window.parent.location.origin) {
|
||
const data = e.data;
|
||
designer.family_deceased_Y_selected = []; designer.family_deceased_N_selected = []; designer.family_left_title = []; designer.family_right_title = [];
|
||
designer.http_host = data.host; designer.follower_id = data.follower_id;
|
||
|
||
if (data.tabletItem) {
|
||
designer.tabletItem = data.tabletItem;
|
||
if (data.familyMembers) designer.familyMembers = data.familyMembers;
|
||
designer.selected.style = data.tabletItem.style || "";
|
||
designer.actitem = data.tabletItem.actitem_num_selected?.val || "";
|
||
|
||
if (designer.tabletItem.f_num_tablet) {
|
||
try {
|
||
const parsedData = JSON.parse(designer.tabletItem.f_num_tablet);
|
||
if (designer.item_type === 'B') {
|
||
designer.family_deceased_Y_selected = parsedData.mid_items || [];
|
||
designer.family_deceased_N_selected = parsedData.left_items || [];
|
||
} else {
|
||
designer.family_deceased_Y_selected = [];
|
||
designer.family_deceased_N_selected = parsedData.mid_items || [];
|
||
}
|
||
} catch (err) { console.error('解析牌位資料時發生錯誤:', err); }
|
||
}
|
||
designer.resetScreen();
|
||
designer.getActItem().then(() => new Promise(res => setTimeout(res, 300))).then(() => {
|
||
designer.getTemplateNameList();
|
||
designer.getData();
|
||
});
|
||
}
|
||
}
|
||
}));
|
||
|
||
$(async () => {
|
||
await designer.init();
|
||
await Promise.all([
|
||
designer.getTabletElement(),
|
||
designer.getPaperSize(),
|
||
designer.getTabletStyles()
|
||
]);
|
||
await designer.getAllStyleDetails();
|
||
});
|
||
</script>
|
||
</body>
|
||
</html> |