pleasanter

This commit is contained in:
Kenichiro NOGI 2025-07-10 10:15:35 +09:00
parent 51a95c5e21
commit 7176dc33ec
162 changed files with 27281 additions and 0 deletions

View File

@ -0,0 +1,4 @@
{
"apiKey": "c38903157cbffc30961f50bc29d0991a6cd8af495ab3009b05c5f98e82b2e61b94ba2d5c0a48fc518b1cd74c9e427b01051a228f670f3c5282544dfbec93db87",
"url": "https://neo999.next-hd.net/pleasanter/"
}

View File

@ -0,0 +1,4 @@
{
"apiKey": "870f99de74072e53f2637371bda5fc6e1313a85f1e2ac548419f71c5295beeb06809fef39eec98de14e7fce1faeade65625cc5dea3bf71964aa3c9ce6f048380",
"url": "https://neo999.next-hd.net/pleasanter/"
}

View File

@ -0,0 +1,6 @@
{
"Name": "DeleteResultsComments",
"Description": "Resultsテーブルの指定されたレコードからコメントのデータを削除する",
"Api": true,
"ApiVersion": 1.1
}

View File

@ -0,0 +1,10 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@name :DeleteResultsComments
@description :
@disabled: false
*/
UPDATE "Results"
SET "Comments" = @Comments
WHERE "ResultId" = @ResultId

View File

@ -0,0 +1,6 @@
{
"Name": "GetUserMailAddresses",
"Description": "Get the mail addresses of the user.",
"Api": true,
"ApiVersion": 1.1
}

View File

@ -0,0 +1,10 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@name :GetUserMailAddresses
@description :
@disabled: false
*/
SELECT "MailAddress" FROM "MailAddresses"
WHERE "OwnerId" = @OwnerId

View File

@ -0,0 +1,231 @@
/*#ViewSelectorField {
top: 0px;
}
*/
/*
#BottomMargin::after {
content: " 右上のヘルプメニューに「目安箱」を設置しました。\A プリザンターに関する各種お問合せはそちらよりお寄せください。\A\A\A";
font-size: 150%;
color: #4169e1;
white-space: pre;
}*/
.status-red {
color: white !important;
background: red !important;
}
.status-blue {
color: white !important;
background: blue !important;
}
.status-green {
color: white !important;
background: green !important;
}
.status-yellow {
color: black !important;
background: yellow !important;
}
.status-white {
color: black !important;
background: white !important;
}
.status-grey {
color: white !important;
background: grey !important;
}
.status-black {
color: white !important;
background: black !important;
}
.status-purple {
color: white !important;
background: purple !important;
}
.status-orange {
color: black !important;
background: orange !important;
}
.status-pink {
color: black !important;
background: pink !important;
}
.status-brown {
color: white !important;
background: brown !important;
}
.status-big-red {
color: white !important;
background: red !important;
font-size: 150% !important;
}
.status-big-blue {
color: white !important;
background: blue !important;
font-size: 150% !important;
}
.status-big-green {
color: white !important;
background: green !important;
font-size: 150% !important;
}
.status-big-yellow {
color: black !important;
background: yellow !important;
font-size: 150% !important;
}
.status-big-white {
color: black !important;
background: white !important;
font-size: 150% !important;
}
.status-big-grey {
color: white !important;
background: grey !important;
font-size: 150% !important;
}
.status-big-black {
color: white !important;
background: black !important;
font-size: 150% !important;
}
.status-big-purple {
color: white !important;
background: purple !important;
font-size: 150% !important;
}
.status-big-orange {
color: black !important;
background: orange !important;
font-size: 150% !important;
}
.status-big-pink {
color: black !important;
background: pink !important;
font-size: 150% !important;
}
.status-big-brown {
color: white !important;
background: brown !important;
font-size: 150% !important;
}
div#PublishWarning {
background: blue;
}
#Breadcrumb>li>a>span.label {
font-size: 200%;
font-weight: bold;
}
#Breadcrumb>li>span {
font-size: 200%;
font-weight: bold;
margin: 0 3px 0 3px;
}
/*コメント付記スタイル*/
.commentAdd {
float: left;
margin-left: 121px;
font-weight: bold;
color: black;
&.nowrap {
white-space: nowrap;
}
&.big {
font-size: 1.3em;
}
&.small {
font-size: 0.7em;
}
&.right {
float: right;
}
&.red {
color: red;
}
&.blue {
color: blue;
}
&.green {
color: green;
}
&.grey {
color: grey;
}
&.purple {
color: purple;
}
&.skyblue {
color: skyblue;
}
&.yellow {
color: yellow;
}
}
/*フォントサイズ変更スタイル*/
.fontSize60 {
font-size: 0.6em !important;
height: auto;
}
.fontSize80 {
font-size: 0.8em !important;
height: auto;
}
.fontSize120 {
font-size: 1.2em !important;
height: auto;
}
.fontSize130 {
font-size: 1.3em !important;
height: auto;
}
.fontSize150 {
font-size: 1.5em !important;
height: auto;
}
.fontSize200 {
font-size: 2em !important;
height: auto;
}

View File

@ -0,0 +1,419 @@
.new-status-big-red {
background: red !important;
background-color: red !important;
color: white !important;
font-size: 150% !important;
}
.new-status-big-green {
background: green !important;
background-color: green !important;
color: white !important;
font-size: 150% !important;
}
.new-status-big-blue {
background: blue !important;
background-color: blue !important;
color: white !important;
font-size: 150% !important;
}
.new-status-big-yellow {
background: yellow !important;
background-color: yellow !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-orange {
background: orange !important;
background-color: orange !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-purple {
background: purple !important;
background-color: purple !important;
color: white !important;
font-size: 150% !important;
}
.new-status-big-pink {
background: pink !important;
background-color: pink !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-brown {
background: brown !important;
background-color: brown !important;
color: white !important;
font-size: 150% !important;
}
.new-status-big-cyan {
background: cyan !important;
background-color: cyan !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-magenta {
background: magenta !important;
background-color: magenta !important;
color: white !important;
font-size: 150% !important;
}
.new-status-big-teal {
background: teal !important;
background-color: teal !important;
color: white !important;
font-size: 150% !important;
}
.new-status-big-lime {
background: lime !important;
background-color: lime !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-violet {
background: violet !important;
background-color: violet !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-grey {
background: grey !important;
background-color: grey !important;
color: white !important;
font-size: 150% !important;
}
.new-status-big-black {
background: black !important;
background-color: black !important;
color: white !important;
font-size: 150% !important;
}
.new-status-big-white {
background: white !important;
background-color: white !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-gold {
background: gold !important;
background-color: gold !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-silver {
background: silver !important;
background-color: silver !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-navy {
background: navy !important;
background-color: navy !important;
color: white !important;
font-size: 150% !important;
}
.new-status-big-maroon {
background: maroon !important;
background-color: maroon !important;
color: white !important;
font-size: 150% !important;
}
.new-status-big-olive {
background: olive !important;
background-color: olive !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-aqua {
background: aqua !important;
background-color: aqua !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-beige {
background: beige !important;
background-color: beige !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-chocolate {
background: chocolate !important;
background-color: chocolate !important;
color: white !important;
font-size: 150% !important;
}
.new-status-big-coral {
background: coral !important;
background-color: coral !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-crimson {
background: crimson !important;
background-color: crimson !important;
color: white !important;
font-size: 150% !important;
}
.new-status-big-indigo {
background: indigo !important;
background-color: indigo !important;
color: white !important;
font-size: 150% !important;
}
.new-status-big-ivory {
background: ivory !important;
background-color: ivory !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-khaki {
background: khaki !important;
background-color: khaki !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-plum {
background: plum !important;
background-color: plum !important;
color: black !important;
font-size: 150% !important;
}
.new-status-big-light-red {
background: lightcoral;
background-color: lightcoral;
color: black;
font-size: 150% !important;
}
.new-status-big-light-green {
background: lightgreen;
background-color: lightgreen;
color: black;
font-size: 150% !important;
}
.new-status-big-light-blue {
background: lightblue;
background-color: lightblue;
color: black;
font-size: 150% !important;
}
.new-status-big-light-yellow {
background: lightyellow;
background-color: lightyellow;
color: black;
font-size: 150% !important;
}
.new-status-big-light-orange {
background: lightsalmon;
background-color: lightsalmon;
color: black;
font-size: 150% !important;
}
.new-status-big-light-purple {
background: lavender;
background-color: lavender;
color: black;
font-size: 150% !important;
}
.new-status-big-light-pink {
background: lightpink;
background-color: lightpink;
color: black;
font-size: 150% !important;
}
.new-status-big-light-brown {
background: burlywood;
background-color: burlywood;
color: black;
font-size: 150% !important;
}
.new-status-big-light-cyan {
background: paleturquoise;
background-color: paleturquoise;
color: black;
font-size: 150% !important;
}
.new-status-big-light-magenta {
background: orchid;
background-color: orchid;
color: black;
font-size: 150% !important;
}
.new-status-big-light-teal {
background: mediumaquamarine;
background-color: mediumaquamarine;
color: black;
font-size: 150% !important;
}
.new-status-big-light-lime {
background: yellowgreen;
background-color: yellowgreen;
color: black;
font-size: 150% !important;
}
.new-status-big-light-violet {
background: thistle;
background-color: thistle;
color: black;
font-size: 150% !important;
}
.new-status-big-light-grey {
background: gainsboro;
background-color: gainsboro;
color: black;
font-size: 150% !important;
}
.new-status-big-light-black {
background: darkgray;
background-color: darkgray;
color: white;
font-size: 150% !important;
}
.new-status-big-light-white {
background: whitesmoke;
background-color: whitesmoke;
color: black;
font-size: 150% !important;
}
.new-status-big-light-gold {
background: palegoldenrod;
background-color: palegoldenrod;
color: black;
font-size: 150% !important;
}
.new-status-big-light-silver {
background: lightgray;
background-color: lightgray;
color: black;
font-size: 150% !important;
}
.new-status-big-light-navy {
background: slategray;
background-color: slategray;
color: white;
font-size: 150% !important;
}
.new-status-big-light-maroon {
background: rosybrown;
background-color: rosybrown;
color: black;
font-size: 150% !important;
}
.new-status-big-light-olive {
background: darkkhaki;
background-color: darkkhaki;
color: black;
font-size: 150% !important;
}
.new-status-big-light-aqua {
background: aquamarine;
background-color: aquamarine;
color: black;
font-size: 150% !important;
}
.new-status-big-light-beige {
background: moccasin;
background-color: moccasin;
color: black;
font-size: 150% !important;
}
.new-status-big-light-chocolate {
background: peru;
background-color: peru;
color: black;
font-size: 150% !important;
}
.new-status-big-light-coral {
background: peachpuff;
background-color: peachpuff;
color: black;
font-size: 150% !important;
}
.new-status-big-light-crimson {
background: indianred;
background-color: indianred;
color: black;
font-size: 150% !important;
}
.new-status-big-light-indigo {
background: mediumpurple;
background-color: mediumpurple;
color: black;
font-size: 150% !important;
}
.new-status-big-light-ivory {
background: ivory;
background-color: ivory;
color: black;
font-size: 150% !important;
}
.new-status-big-light-khaki {
background: lightgoldenrodyellow;
background-color: lightgoldenrodyellow;
color: black;
font-size: 150% !important;
}
.new-status-big-light-plum {
background: plum;
background-color: plum;
color: black;
font-size: 150% !important;
}

View File

@ -0,0 +1,359 @@
.new-status-red {
background: red !important;
background-color: red !important;
color: white !important;
}
.new-status-green {
background: green !important;
background-color: green !important;
color: white !important;
}
.new-status-blue {
background: blue !important;
background-color: blue !important;
color: white !important;
}
.new-status-yellow {
background: yellow !important;
background-color: yellow !important;
color: black !important;
}
.new-status-orange {
background: orange !important;
background-color: orange !important;
color: black !important;
}
.new-status-purple {
background: purple !important;
background-color: purple !important;
color: white !important;
}
.new-status-pink {
background: pink !important;
background-color: pink !important;
color: black !important;
}
.new-status-brown {
background: brown !important;
background-color: brown !important;
color: white !important;
}
.new-status-cyan {
background: cyan !important;
background-color: cyan !important;
color: black !important;
}
.new-status-magenta {
background: magenta !important;
background-color: magenta !important;
color: white !important;
}
.new-status-teal {
background: teal !important;
background-color: teal !important;
color: white !important;
}
.new-status-lime {
background: lime !important;
background-color: lime !important;
color: black !important;
}
.new-status-violet {
background: violet !important;
background-color: violet !important;
color: black !important;
}
.new-status-grey {
background: grey !important;
background-color: grey !important;
color: white !important;
}
.new-status-black {
background: black !important;
background-color: black !important;
color: white !important;
}
.new-status-white {
background: white !important;
background-color: white !important;
color: black !important;
}
.new-status-gold {
background: gold !important;
background-color: gold !important;
color: black !important;
}
.new-status-silver {
background: silver !important;
background-color: silver !important;
color: black !important;
}
.new-status-navy {
background: navy !important;
background-color: navy !important;
color: white !important;
}
.new-status-maroon {
background: maroon !important;
background-color: maroon !important;
color: white !important;
}
.new-status-olive {
background: olive !important;
background-color: olive !important;
color: black !important;
}
.new-status-aqua {
background: aqua !important;
background-color: aqua !important;
color: black !important;
}
.new-status-beige {
background: beige !important;
background-color: beige !important;
color: black !important;
}
.new-status-chocolate {
background: chocolate !important;
background-color: chocolate !important;
color: white !important;
}
.new-status-coral {
background: coral !important;
background-color: coral !important;
color: black !important;
}
.new-status-crimson {
background: crimson !important;
background-color: crimson !important;
color: white !important;
}
.new-status-indigo {
background: indigo !important;
background-color: indigo !important;
color: white !important;
}
.new-status-ivory {
background: ivory !important;
background-color: ivory !important;
color: black !important;
}
.new-status-khaki {
background: khaki !important;
background-color: khaki !important;
color: black !important;
}
.new-status-plum {
background: plum !important;
background-color: plum !important;
color: black !important;
}
.new-status-light-red {
background: lightcoral;
background-color: lightcoral;
color: black;
}
.new-status-light-green {
background: lightgreen;
background-color: lightgreen;
color: black;
}
.new-status-light-blue {
background: lightblue;
background-color: lightblue;
color: black;
}
.new-status-light-yellow {
background: lightyellow;
background-color: lightyellow;
color: black;
}
.new-status-light-orange {
background: lightsalmon;
background-color: lightsalmon;
color: black;
}
.new-status-light-purple {
background: lavender;
background-color: lavender;
color: black;
}
.new-status-light-pink {
background: lightpink;
background-color: lightpink;
color: black;
}
.new-status-light-brown {
background: burlywood;
background-color: burlywood;
color: black;
}
.new-status-light-cyan {
background: paleturquoise;
background-color: paleturquoise;
color: black;
}
.new-status-light-magenta {
background: orchid;
background-color: orchid;
color: black;
}
.new-status-light-teal {
background: mediumaquamarine;
background-color: mediumaquamarine;
color: black;
}
.new-status-light-lime {
background: yellowgreen;
background-color: yellowgreen;
color: black;
}
.new-status-light-violet {
background: thistle;
background-color: thistle;
color: black;
}
.new-status-light-grey {
background: gainsboro;
background-color: gainsboro;
color: black;
}
.new-status-light-black {
background: darkgray;
background-color: darkgray;
color: white;
}
.new-status-light-white {
background: whitesmoke;
background-color: whitesmoke;
color: black;
}
.new-status-light-gold {
background: palegoldenrod;
background-color: palegoldenrod;
color: black;
}
.new-status-light-silver {
background: lightgray;
background-color: lightgray;
color: black;
}
.new-status-light-navy {
background: slategray;
background-color: slategray;
color: white;
}
.new-status-light-maroon {
background: rosybrown;
background-color: rosybrown;
color: black;
}
.new-status-light-olive {
background: darkkhaki;
background-color: darkkhaki;
color: black;
}
.new-status-light-aqua {
background: aquamarine;
background-color: aquamarine;
color: black;
}
.new-status-light-beige {
background: moccasin;
background-color: moccasin;
color: black;
}
.new-status-light-chocolate {
background: peru;
background-color: peru;
color: black;
}
.new-status-light-coral {
background: peachpuff;
background-color: peachpuff;
color: black;
}
.new-status-light-crimson {
background: indianred;
background-color: indianred;
color: black;
}
.new-status-light-indigo {
background: mediumpurple;
background-color: mediumpurple;
color: black;
}
.new-status-light-ivory {
background: ivory;
background-color: ivory;
color: black;
}
.new-status-light-khaki {
background: lightgoldenrodyellow;
background-color: lightgoldenrodyellow;
color: black;
}
.new-status-light-plum {
background: plum;
background-color: plum;
color: black;
}

View File

@ -0,0 +1,11 @@
//メッセージ追加表示
$p.ex.setMyMessage = function (cssColor = 'alert-success', message, clear = 1) {
//クリアが指定されていたら事前にメッセージ消去
clear && $p.clearMessage();
$p.setMessage('#Message', JSON.stringify({
Css: 'alert-success ' + cssColor,
Text: message
}));
}

View File

@ -0,0 +1,23 @@
//コメントのリストを取得し1つずつ表示する
try {
let resultId = model.ResultId;
let comments = model.Comments;
let commentArray = JSON.parse(comments);
context.Log(('ResultId: ' + resultId));
for (let comment of commentArray.slice(0, 5)) {
context.Log(JSON.stringify(comment));
}
let newComments = JSON.stringify(commentArray.slice(0, 5));
let json = {
"Comments": newComments,
"ResultId": resultId
}
extendedSql.ExecuteTable('DeleteResultsComments', JSON.stringify(json));
} catch (error) {
context.Log(('エラーが発生しました: ' + error.message));
}

View File

@ -0,0 +1,4 @@
{
"apiKey": "c38903157cbffc30961f50bc29d0991a6cd8af495ab3009b05c5f98e82b2e61b94ba2d5c0a48fc518b1cd74c9e427b01051a228f670f3c5282544dfbec93db87",
"url": "https://neo999.next-hd.net/pleasanter/"
}

View File

@ -0,0 +1,140 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 1.シフト情報保存
@name : 1.シフト情報保存
@siteIds : 310514
@siteTitles : イオン多摩平シフト希望
@disabled: false
*/
$p.events.on_editor_load = function () {
if ($p.action() == 'new') {
let now = new Date();
let nextMonth = new Date(now.getFullYear(), now.getMonth() + 1, 1);
let yyyy = nextMonth.getFullYear();
let mm = String(nextMonth.getMonth() + 1).padStart(2, '0');
let ymStr = `${yyyy}${mm}`;
$p.set($('#Results_ClassA'), ymStr);
}
//任意の処理
setupCalendar();
}
//保存前野処理
$p.events.before_validate = function (args) {
//曜日判定
let week = ['月', '火', '水', '木', '金', '土', '日'];
if ($('#Results_ClassC').val().includes('すべて可')) {
$p.set($('#Results_ClassC'), JSON.stringify('["すべて可"]'));
} else if (isSubset($('#Results_ClassC').val(), week)) {
$p.set($('#Results_ClassC'), JSON.stringify('["すべて可"]'));
} else if ($('#Results_ClassC').val().length === 0) {
$p.set($('#Results_ClassC'), JSON.stringify('["すべて可"]'));
}
/*
//最低勤務時間
if ($('#Results_NumA').val() == '0') {
$p.set($('#Results_ClassG'), "月あたり最低勤務時間:指定無し");
} else {
$p.set($('#Results_ClassG'), "月あたり最低勤務時間:" + $('#Results_NumA').val() + "時間");
}
//最大勤務時間
if ($('#Results_NumB').val() == '0') {
$p.set($('#Results_ClassH'), "月あたり最大勤務時間:指定無し");
} else {
$p.set($('#Results_ClassH'), "月あたり最大勤務時間:" + $('#Results_NumB').val() + "時間");
}
*/
//曜日
let classCStr = "希望曜日:" + $('#Results_ClassC').val().join(',');
//時間帯
let classD1 = $('#Results_ClassD').val();
let classD2;
let classDStr;
if (classD1.includes('いつでも')) {
$p.set($('#Results_ClassD'), JSON.stringify('["いつでも"]'));
classDStr = "時間:いつでも";
} else if (classD1.length === 0) {
$p.set($('#Results_ClassD'), JSON.stringify('["いつでも"]'));
classDStr = "時間:いつでも";
} else {
classD2 = convertToNumbers(classD1);
classDStr = "時間:" + formatRanges(classD2);
}
//カレンダーチェック内容保存
let checked = getCheckedDates();
$p.set($('#Results_ClassW'), JSON.stringify(checked));
//個別指定
let classWArray = checked.map(date => Number(date.split('-')[2]));
let classWStr = "個別希望日:" + classWArray.join(',');
$p.set($('#Results_ClassE'), classWArray.join(', '));
if (classWArray.length === 0) {
classWStr = "個別希望日:なし";
}
let list = [];
if (classCStr) list.push(classCStr);
if (classDStr) list.push(classDStr);
if (classWStr) list.push(classWStr);
let classZStr = list.join('');
//希望シフトの内容をすべて連結して保存
$p.set($('#Results_ClassZ'), classZStr);
//年月を保存
$p.set($('#Results_ClassY'), $('#Results_ClassA').val());
//名前を保存
$p.set($('#Results_ClassX'), $('#Results_ClassB option:selected').text());
}
//配列ABを比較
function isSubset(A, B) {
return B.every(value => A.includes(value));
}
//数字範囲を省略して返却
function formatRanges(arr) {
arr.sort((a, b) => a - b); //配列を昇順にソート
let result = [];
let start = arr[0], end = arr[0];
for (let i = 1; i < arr.length; i++) {
if (arr[i] === end + 1) {
//連続する数値の場合、範囲を拡張
end = arr[i];
} else {
//連続が途切れたら結果に追加し、新しい範囲を開始
result.push(start === end ? `${start}` : `${start}-${end}`);
start = end = arr[i];
}
}
//最後の範囲を追加
result.push(start === end ? `${start}` : `${start}-${end}`);
return result.join(",");
}
//配列の中身をすべて数値に置き換える
function convertToNumbers(arr) {
return arr.map(value => Number(value));
}

View File

@ -0,0 +1,289 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 2.カレンダー表示
@name : 2.カレンダー表示
@siteIds : 310514
@siteTitles : イオン多摩平シフト希望
@disabled: false
*/
//カレンダーを生成して挿入する関数
function renderCalendar(year, month, checkedDates = [], selectedHoursArray = []) {
$('#custom-calendar-container').remove();
let containerHtml = `<div id="custom-calendar-container">`; // メインコンテナ
let calendarAndControlsFlexContainer = `<div id="custom-calendar">`; // カレンダーと操作ボタンのFlexコンテナ
// カレンダー本体
let calendarTableHtml = `<div><table border="1"><thead><tr>
<th></th><th></th><th></th><th></th><th></th><th></th><th></th>
</tr></thead><tbody><tr>`;
let firstDay = new Date(year, month - 1, 1);
let lastDay = new Date(year, month, 0);
for (let i = 0; i < firstDay.getDay(); i++) calendarTableHtml += "<td></td>";
for (let d = 1; d <= lastDay.getDate(); d++) {
let dateObj = new Date(year, month - 1, d);
let dayOfWeek = dateObj.getDay();
let dateStr = `${year}-${String(month).padStart(2, '0')}-${String(d).padStart(2, '0')}`;
let checked = checkedDates.includes(dateStr) ? 'checked' : '';
calendarTableHtml += `<td><label><input type="checkbox" class="calendar-checkbox" value="${dateStr}" data-day="${dayOfWeek}" ${checked}><br>${d}</label></td>`;
if ((firstDay.getDay() + d) % 7 === 0 && d !== lastDay.getDate()) calendarTableHtml += "</tr><tr>";
}
let lastDayOfWeek = new Date(year, month - 1, lastDay.getDate()).getDay();
for (let i = lastDayOfWeek + 1; i <= 6; i++) calendarTableHtml += "<td></td>";
calendarTableHtml += "</tr></tbody></table></div>"; // カレンダーテーブルの閉じタグ
calendarAndControlsFlexContainer += calendarTableHtml;
// 操作コントロール(ボタンとタイムバー)のコンテナ
let controlsContainerHtml = `<div class="controls-container">`;
// 一括操作ボタン
controlsContainerHtml += `
<div>
<button type="button" id="calendar-check-all">全てチェック</button>
<button type="button" id="calendar-uncheck-all">全て解除</button>
</div>`;
// 曜日ボタン
controlsContainerHtml += `<div class="day-toggle-buttons">
<button type="button" class="calendar-day-toggle" data-day="1"></button>
<button type="button" class="calendar-day-toggle" data-day="2"></button>
<button type="button" class="calendar-day-toggle" data-day="3"></button>
<button type="button" class="calendar-day-toggle" data-day="4"></button>
<button type="button" class="calendar-day-toggle" data-day="5"></button>
<button type="button" class="calendar-day-toggle" data-day="6"></button>
<button type="button" class="calendar-day-toggle" data-day="0"></button>
</div>`;
// 時間選択バー
controlsContainerHtml += `
<div id="time-selector-container">
<label>希望時間帯 (1021) - 開始と終了時間を選択:</label>
<div id="time-bar">`;
for (let hour = 10; hour <= 21; hour++) {
controlsContainerHtml += `<div class="time-slot" data-hour="${hour}" style="color: darkblue;">${hour}</div>`;
}
controlsContainerHtml += `</div>
<p>選択された時間: <span id="selected-hours-display">なし</span></p>
</div>
`;
controlsContainerHtml += `</div>`; // controls-container の閉じタグ
calendarAndControlsFlexContainer += controlsContainerHtml;
calendarAndControlsFlexContainer += `</div>`; // custom-calendar (Flexコンテナ) の閉じタグ
containerHtml += calendarAndControlsFlexContainer;
containerHtml += "</div>"; // custom-calendar-container の閉じタグ
$('#SectionFields1Container').after(containerHtml);
// ボタンイベント (変更なし)
$('#calendar-check-all').off('click').on('click', function () {
$('#custom-calendar .calendar-checkbox').prop('checked', true);
});
$('#calendar-uncheck-all').off('click').on('click', function () {
$('#custom-calendar .calendar-checkbox').prop('checked', false);
});
let dayToggleState = { 0: false, 1: false, 2: false, 3: false, 4: false, 5: false, 6: false };
$('.calendar-day-toggle').off('click').on('click', function () {
const day = $(this).data('day');
dayToggleState[day] = !dayToggleState[day];
$('#custom-calendar .calendar-checkbox[data-day="' + day + '"]').prop('checked', dayToggleState[day]);
if (dayToggleState[day]) {
$(this).css('background', '#0078d7').css('color', '#fff');
} else {
$(this).css('background', '').css('color', '');
}
});
// 時間選択バーのロジック (変更なし)
const timeSlots = $('.time-slot');
const selectedHoursDisplay = $('#selected-hours-display');
let isDragging = false;
let selectionStartHour = -1;
let selectionEndHour = -1;
if (selectedHoursArray && selectedHoursArray.length > 0) {
if (selectedHoursArray.length >= 1) {
selectionStartHour = Math.min(...selectedHoursArray);
selectionEndHour = Math.max(...selectedHoursArray);
updateSelectionVisuals();
if (selectedHoursArray.length >= 2) {
selectedHoursDisplay.text(selectedHoursArray.sort((a, b) => a - b).join(','));
} else {
selectedHoursDisplay.text('最低2時間選択してください');
}
}
}
timeSlots.on('mousedown touchstart', function (e) { // touchstart を追加
e.preventDefault();
isDragging = true;
const currentHour = parseInt($(this).data('hour'));
selectionStartHour = currentHour;
selectionEndHour = currentHour;
updateSelectionVisuals();
});
timeSlots.on('mousemove touchmove', function (e) { // touchmove を追加
if (isDragging) {
let pageX;
if (e.type === 'touchmove') {
pageX = e.originalEvent.touches[0].pageX;
} else {
pageX = e.pageX;
}
// マウス/タッチ位置から最も近いスロットを見つける
let closestSlot = null;
let minDistance = Infinity;
timeSlots.each(function () {
const slot = $(this);
const slotCenterX = slot.offset().left + slot.width() / 2;
const distance = Math.abs(pageX - slotCenterX);
if (distance < minDistance) {
minDistance = distance;
closestSlot = slot;
}
});
if (closestSlot) {
const currentHour = parseInt(closestSlot.data('hour'));
selectionEndHour = currentHour;
updateSelectionVisuals();
}
}
});
$(document).on('mouseup touchend', function () { // touchend を追加
if (isDragging) {
isDragging = false;
const start = Math.min(selectionStartHour, selectionEndHour);
const end = Math.max(selectionStartHour, selectionEndHour);
const selectedCount = (start !== -1 && end !== -1) ? (end - start + 1) : 0;
if (selectedCount < 2 && selectedCount > 0) {
$p.ex.setMyMessage('alert-error new-status-red', '開始時間と終了時間を選択してください');
timeSlots.css('background-color', '');
selectedHoursDisplay.text('なし');
$p.set($('#Results_ClassD'), JSON.stringify([]));
selectionStartHour = -1;
selectionEndHour = -1;
} else if (selectedCount >= 2) {
$p.clearMessage();
saveSelectedHoursToField();
} else {
$p.clearMessage();
timeSlots.css('background-color', '');
selectedHoursDisplay.text('なし');
$p.set($('#Results_ClassD'), JSON.stringify([]));
selectionStartHour = -1;
selectionEndHour = -1;
}
}
});
function updateSelectionVisuals() {
timeSlots.css('background-color', '');
const start = Math.min(selectionStartHour, selectionEndHour);
const end = Math.max(selectionStartHour, selectionEndHour);
if (start !== -1 && end !== -1) {
for (let i = start; i <= end; i++) {
$(`.time-slot[data-hour="${i}"]`).css('background-color', '#a0c4ff');
}
}
}
function saveSelectedHoursToField() {
const selected = [];
if (selectionStartHour !== -1 && selectionEndHour !== -1) {
const start = Math.min(selectionStartHour, selectionEndHour);
const end = Math.max(selectionStartHour, selectionEndHour);
if ((end - start + 1) >= 2) {
for (let i = start; i <= end; i++) {
selected.push(i.toString());
}
selectedHoursDisplay.text(selected.join(',') || 'なし');
$p.set($('#Results_ClassD'), JSON.stringify(selected));
console.log('Selected hours saved to Results_ClassD:', JSON.stringify(selected));
} else {
selectedHoursDisplay.text('開始時間と終了時間を選択してください');
$p.set($('#Results_ClassD'), JSON.stringify([]));
console.log('Selection less than 2 hours, not saved.');
}
} else {
selectedHoursDisplay.text('なし');
$p.set($('#Results_ClassD'), JSON.stringify([]));
}
}
}
//チェックされた日付を取得する関数 (変更なし)
function getCheckedDates() {
return $('.calendar-checkbox:checked').map(function () {
return this.value;
}).get();
}
//選択された時間を取得する関数 (Results_ClassDから読み込む)
function getSelectedHours() {
const classD = $('#Results_ClassD').val();
let hoursArray = [];
if (classD[0] === 'いつでも') {
hoursArray = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21];
} else {
for (let i = 0; i < classD.length; i++) {
hoursArray.push(parseFloat(classD[i]));
}
}
return hoursArray;
}
/*
console.log(hoursString);
if (hoursString) {
try {
const parsedHours = JSON.parse(hoursString);
if (Array.isArray(parsedHours) && parsedHours.every(h => typeof h === 'number')) {
return parsedHours;
}
} catch (e) {
console.error("Error parsing selected hours from Results_ClassD:", e);
if (typeof hoursString === 'string' && hoursString.includes(',')) {
return hoursString.split(',').map(h => parseInt(h.trim(), 10)).filter(h => !isNaN(h));
}
}
}
return [];
}
*/
//年月選択UIとイベント (変更なし)
function setupCalendarUI(initialYear, initialMonth, checkedDates = [], initialSelectedHoursArray = []) {
renderCalendar(initialYear, initialMonth, checkedDates, initialSelectedHoursArray);
$p.on('change', 'ClassA', function () {
let y = parseFloat($('#Results_ClassA').val().split('年')[0]);
let m = parseFloat($('#Results_ClassA').val().split('年')[1].split('月')[0]);
renderCalendar(y, m, getCheckedDates(), getSelectedHours());
});
}
function setupCalendar() {
let initialYear = parseFloat($('#Results_ClassA').val().split('年')[0]);
let initialMonth = parseFloat($('#Results_ClassA').val().split('年')[1].split('月')[0]);
let initialCheckedDates = $('#Results_ClassW').val() ? JSON.parse($('#Results_ClassW').val()) : [];
let initialSelectedHoursArray = getSelectedHours();
setupCalendarUI(initialYear, initialMonth, initialCheckedDates, initialSelectedHoursArray);
}

View File

@ -0,0 +1,89 @@
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>カレンダー選択jQuery版</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
table {
border-collapse: collapse;
width: 100%;
}
th,
td {
padding: 10px;
text-align: center;
border: 1px solid #ddd;
}
td input {
margin: 5px;
}
</style>
</head>
<body>
<h2>指定した月のカレンダー</h2>
<label for="year">年:</label>
<input type="number" id="year" value="2025">
<label for="month">月:</label>
<input type="number" id="month" value="5">
<button id="generate">カレンダー作成</button>
<table id="calendar"></table>
<button id="getDates">選択した日付を取得</button>
<p id="selectedDates"></p>
<script>
$(document).ready(function () {
$("#generate").click(function () {
generateCalendar();
});
$("#getDates").click(function () {
getSelectedDates();
});
function generateCalendar() {
let year = $("#year").val();
let month = $("#month").val();
let firstDay = new Date(year, month - 1, 1);
let lastDay = new Date(year, month, 0);
let daysInMonth = lastDay.getDate();
let weekDays = ["日", "月", "火", "水", "木", "金", "土"];
let html = "<thead><tr>";
$.each(weekDays, function (index, day) {
html += `<th>${day}</th>`;
});
html += "</tr></thead><tbody><tr>";
// 空白セルの追加
for (let i = 0; i < firstDay.getDay(); i++) {
html += "<td></td>";
}
for (let day = 1; day <= daysInMonth; day++) {
let dateValue = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
html += `<td>${day}<br><input type="checkbox" value="${dateValue}"></td>`;
if (new Date(year, month - 1, day).getDay() === 6) {
html += "</tr><tr>"; // 土曜日なら改行
}
}
html += "</tr></tbody>";
$("#calendar").html(`<table>${html}</table>`);
}
function getSelectedDates() {
let selectedDates = $("#calendar input:checked").map(function () {
return $(this).val();
}).get();
$("#selectedDates").text("選択した日付: " + selectedDates.join(", "));
}
});
</script>
</body>
</html>

View File

@ -0,0 +1,26 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 選択年月リスト作成
@name : 選択年月リスト作成
@siteIds : 310514
@siteTitles : イオン多摩平シフト希望
@disabled: false
*/
try {
//年月を当月から3ヶ月後まで自動表示
let now = new Date();
for (let i = 0; i < 3; i++) {
let date = new Date(now.getFullYear(), now.getMonth() + i, 1);
let year = date.getFullYear();
let month = (date.getMonth() + 1).toString().padStart(2, '0');
let ym = year + '年' + month + '月';
columns.ClassA.AddChoiceHash(ym, ym);
}
} catch (e) {
context.Log(e.stack);
}

View File

@ -0,0 +1,40 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 1.基本スタイル
@name : 1.基本スタイル
@siteIds : 310514
@siteTitles : イオン多摩平シフト希望
@disabled: false
*/
label.error {
pointer-events: none;
z-index: 100;
}
.code-readonly {
pointer-events: none;
background-color: lightgrey;
font-weight: bold;
}
.code-readonly2,
.code-readonly2+button,
.code-readonly2+div.ui-icon {
pointer-events: none;
font-weight: bold;
}
.code-readonly2 select,
.code-readonly2 input,
.code-readonly2 button.ui-multiselect,
.code-readonly2 .control-markup,
span[data-readonly="1"] {
border: dashed 1px black !important;
}
select[data-validate-required="1"],
input[data-validate-required="1"] {
border: dashed 1px red !important;
}

View File

@ -0,0 +1,183 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 2.カレンダースタイル
@name : 2.カレンダースタイル
@siteIds : 310514
@siteTitles : イオン多摩平シフト希望
@disabled: false
*/
/* グローバルコンテナ */
#custom-calendar-container {
display: flex;
flex-direction: column;
width: 100%;
}
/* カレンダーとコントロールのコンテナ */
#custom-calendar {
display: flex;
flex-direction: column;
/* スマホ表示では縦並び */
align-items: stretch;
/* 幅を合わせる */
width: 100%;
background: #fff;
padding: 10px;
border-radius: 6px;
margin-bottom: 10px;
margin-left: 0 !important;
/* 初期値として左マージンをリセット */
}
/* カレンダーテーブルの直接の親div */
#custom-calendar>div:first-child {
overflow-x: auto;
/* テーブルがはみ出る場合はスクロール */
width: 100%;
margin-bottom: 15px;
/* ボタンとの間隔 */
}
/* テーブル全体 */
#custom-calendar table {
border-collapse: collapse;
width: 100%;
background: #fff;
min-width: 300px;
/* 最小幅を設定 */
}
/* テーブルヘッダーとセル共通 */
#custom-calendar th,
#custom-calendar td {
border: 1px solid #ccc;
text-align: center;
vertical-align: middle;
height: 40px;
/* 基本の高さを維持 */
width: auto;
/* 幅は自動調整、または特定の列で指定 */
padding: 5px;
/* 少しパディングを調整 */
font-size: 1.2em;
/* フォントサイズを少し大きく */
}
/* 曜日行 */
#custom-calendar thead th {
background: #f0f0f0;
color: #333;
}
/* 日曜日 */
#custom-calendar thead th:first-child,
#custom-calendar tbody td:nth-child(1) {
background: #e0f0ff;
color: #0070c0;
}
/* 土曜日 */
#custom-calendar thead th:last-child,
#custom-calendar tbody td:nth-child(7) {
background: #fff4e0;
color: #ff8000;
}
/* チェックボックスと日付のラベル */
#custom-calendar label {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
cursor: pointer;
}
/* タップしやすくするために td 内の label を block にする */
#custom-calendar td label {
display: block;
}
/* 操作コントロール(ボタンとタイムバー)のコンテナ */
.controls-container {
display: flex;
flex-direction: column;
gap: 15px;
width: 100%;
margin-left: 0 !important;
/* 初期値として左マージンをリセット */
}
/* 曜日ボタングループ */
.day-toggle-buttons {
display: flex;
flex-wrap: wrap;
gap: 5px;
justify-content: center;
/* スマホ表示では中央揃え */
}
/* 曜日ボタン個別 */
.calendar-day-toggle {
padding: 6px 6px;
font-size: 0.9em;
}
/* タイムバーコンテナ */
#time-bar {
width: 100%;
display: flex;
margin: 3px 0;
flex-wrap: nowrap;
-webkit-overflow-scrolling: touch;
}
/* タイムスロット */
.time-slot {
min-width: 25px;
text-align: center;
border: 1px solid #ccc;
font-size: 1.3em !important;
/* !important は元の指定を尊重 */
/* font-size: 0.85em; 重複していたため、どちらかを選択または調整 */
}
/* タブレット以上の幅でレイアウト変更 */
@media (min-width: 768px) {
#custom-calendar {
flex-direction: row;
/* 横並びに戻す */
align-items: flex-start;
width: fit-content;
/* 元の指定に近い形に戻す */
float: left;
/* 元の指定 */
margin-left: 121px !important;
/* 元の指定に戻す */
}
#custom-calendar>div:first-child {
/* カレンダーテーブルのコンテナ */
width: auto;
/* 自動幅に戻す */
margin-bottom: 0;
margin-right: 15px;
/* 右側にマージン */
}
.controls-container {
width: auto;
/* 自動幅に戻す */
margin-left: 16px !important;
/* 元のマージンに戻す */
}
.day-toggle-buttons {
justify-content: flex-start;
/* 左揃えに戻す */
}
}

View File

@ -0,0 +1,4 @@
{
"apiKey": "c38903157cbffc30961f50bc29d0991a6cd8af495ab3009b05c5f98e82b2e61b94ba2d5c0a48fc518b1cd74c9e427b01051a228f670f3c5282544dfbec93db87",
"url": "https://neo999.next-hd.net/pleasanter/"
}

View File

@ -0,0 +1,302 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 1.シフト希望表示
@name :
@siteIds : 310511
@siteTitles : イオン多摩平シフト管理
@disabled: false
*/
let apiKey = '6504c8a807677a3a576e10327f3c19876c55736ee45d4a845796b9e7f5e087bfd4bd0d8184863da8cf1733ca635111432ab334aea59102b06a96ee6d2c05190d';
let subWin;
//シフト希望データの保存先
let subTableId = '310514';
let now = new Date();
let monthStr = now.getFullYear() + '年' +
(now.getMonth() + 1).toString().padStart(2, '0') + '月';
let shiftData;
let totalCount = 0;
// 名前とクラスのマッピング
const nameColorMap =
{
/*" ": { "backgroundColor": "#9370DB", "fontColor": "#000000" },
"長谷川 望": { "backgroundColor": "#008000", "fontColor": "#FFFFFF" },
"河村 あゆみ": { "backgroundColor": "#0000FF", "fontColor": "#FFFFFF" },
"渡部 直輝": { "backgroundColor": "#FFFF00", "fontColor": "#000000" },
"小坂 志織": { "backgroundColor": "#FFA500", "fontColor": "#000000" },
"佐藤 春樹": { "backgroundColor": "#800080", "fontColor": "#FFFFFF" },
"河関 宏昌": { "backgroundColor": "#FFC0CB", "fontColor": "#000000" },
"中嶋 透": { "backgroundColor": "#A52A2A", "fontColor": "#FFFFFF" },
"西川 眞": { "backgroundColor": "#F08080", "fontColor": "#000000" },
"岡本 祥子": { "backgroundColor": "#90EE90", "fontColor": "#000000" },
"青柳 麻衣": { "backgroundColor": "#ADD8E6", "fontColor": "#000000" },
"田渕 希美": { "backgroundColor": "#FFFFE0", "fontColor": "#000000" },
"松村 花純": { "backgroundColor": "#FFDAB9", "fontColor": "#000000" },
"菱田 朱夏": { "backgroundColor": "#E6E6FA", "fontColor": "#000000" },
"奥山 喜美花": { "backgroundColor": "#FFB6C1", "fontColor": "#000000" },
"山口 賢人": { "backgroundColor": "#DEB887", "fontColor": "#000000" },
"小島 芙優": { "backgroundColor": "#E0FFFF", "fontColor": "#000000" },
"滝澤 みづき": { "backgroundColor": "#DA70D6", "fontColor": "#000000" },
"八代 美波": { "backgroundColor": "#20B2AA", "fontColor": "#000000" },
"伊藤 亜子": { "backgroundColor": "#32CD32", "fontColor": "#000000" },
"鈴木 梨紗都": { "backgroundColor": "#D8BFD8", "fontColor": "#000000" },*/
"店長会議": { "backgroundColor": "#000000", "fontColor": "#FFFFFF" },
"イオンセミナー": { "backgroundColor": "#DC143C", "fontColor": "#FFFFFF" },
"説明会": { "backgroundColor": "#4B0082", "fontColor": "#FFFFFF" },
"ティッシュ配布": { "backgroundColor": "#FFD700", "fontColor": "#000000" },
"消防訓練": { "backgroundColor": "#800000", "fontColor": "#FFFFFF" },
"欠員": { "backgroundColor": "#FF0000", "fontColor": "#FFFFFF" },
"法定点検": { "backgroundColor": "#800000", "fontColor": "#FFFFFF" },
"ラック申請": { "backgroundColor": "#00FFFF", "fontColor": "#000000" },
"チラシ申請": { "backgroundColor": "#00FFFF", "fontColor": "#000000" },
"アプリ申請": { "backgroundColor": "#00FFFF", "fontColor": "#000000" },
}
$p.events.on_calendar_load = function () {
//処理内容
$p.ex.init('#Calendar');
//ペンマークの削除
$('div.title>.ui-icon-pencil').remove();
//色分け
$('div.item').each(function () {
const $item = $(this);
const itemId = $item.attr('data-id');
const span = '<span class="ui-icon ui-icon-check custom-check" data-id="' + itemId + '" style="cursor:pointer;"></span>';
// $(this)の子タグの下にspanを追加
$(this).children().last().prepend(span);
const titleText = $(this).text().trim();
const name = titleText.split('-')[0].trim();
const startTime = titleText.split('-')[1]?.trim() || '';
const endTime = titleText.split('-')[2]?.trim() || '';
const restTime = endTime && startTime ? Math.max(0, parseInt(endTime, 10) - parseInt(startTime, 10) - 4) : 0;
if (restTime > 0) {
$(this).css('background-color', 'yellow');
$(this).css('color', 'black');
$(this).css('border', '2px solid black'); // 休憩時間がある場合は赤枠
} else {
$(this).css('border', '1px dashed black'); // 休憩時間がない場合は透明な枠
}
$(this).css('background-color', nameColorMap[name]?.backgroundColor);
$(this).css('color', nameColorMap[name]?.fontColor);
});
// クリックイベントを追加
$(document).off('click', '.custom-check').on('click', '.custom-check', function (e) {
e.stopPropagation();
const itemId = $(this).data('id');
$p.ex.changeTimeDataWindow(itemId, e.pageX, e.pageY);
});
$('span.data.link').each(function () {
const titleText = $(this).text().trim();
const name = titleText.split(/\d+/)[0].trim();
$(this).css('background-color', nameColorMap[name]?.backgroundColor);
$(this).css('color', nameColorMap[name]?.fontColor);
});
}
$p.events.on_editor_load = function () {
//処理内容
$p.ex.init('#EditorTabsContainer');
}
$p.events.on_grid_load = function () {
//処理内容
$p.ex.init('.grid-wrap');
}
$p.ex.init = function (target) {
$(target).css({
'width': '60%',
'float': 'left'
});
//ウインドウがすでにある場合は削除
if ($('#shiftListWindow').length) $('#shiftListWindow').remove();
subWin = document.createElement('div');
subWin.id = 'shiftListWindow';
subWin.innerText = '';
subWin.style.width = '40%';
subWin.style.float = 'left';
subWin.style.textAlign = 'center';
$(target).after(subWin);
let savedMonth = localStorage.getItem('selectedMonth');
let initialMonth = savedMonth || monthStr;
//シフトデータ挿入
$p.ex.getShiftKibouData(initialMonth);
}
$p.events.before_validate = function (args) {
}
//シフト希望日データ取得
$p.ex.getShiftKibouData = async function (monthStr) {
//プリザンターへゲット処理
const pleasanterUrl = 'https://' + location.hostname + '/pleasanter/api/items/' + subTableId + '/get'
const jsonBody = {
'ApiVersion': 1.1,
'ApiKey': apiKey,
'View': {
'ColumnSorterHash': {
'ClassB': 'asc'
},
'ColumnFilterHash': {
'ClassA': '["' + monthStr + '"]'
},
}
};
const pleasanterRes = await fetch(pleasanterUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(jsonBody)
});
const resData = await pleasanterRes.json();
//console.log(resData);
//リスト消して
if ($('#listTable').length) $('#listTable').remove();
if ($('#monthSelect').length) $('#monthSelect').remove();
// 年月セレクトボックス作成
let now = new Date();
// ローカルストレージから選択値を取得
let savedMonth = localStorage.getItem('selectedMonth');
let initialMonth = savedMonth || monthStr;
let selectHtml = `<select id="monthSelect">`;
for (let i = 0; i < 4; i++) {
let d = new Date(now.getFullYear(), now.getMonth() + i, 1);
let y = d.getFullYear();
let m = (d.getMonth() + 1).toString().padStart(2, '0');
let ym = `${y}${m}`;
let selected = (ym === initialMonth) ? 'selected' : '';
selectHtml += `<option value="${ym}" ${selected}>${ym}</option>`;
}
selectHtml += `</select>`;
// テーブルテンプレート
let templateHtml =
`<table id="listTable" class="radius-table">
<tr>
<th>名前</th>
<th>希望シフト内容</th>
</tr>
{{#listData}}
<tr class="{{type}}">
<td class="userName">{{userName}}</td>
<td>{{shiftData}}</td>
</tr>
{{/listData}}
</table>`;
let listData = [];
let userName = '   ';
let userName0;
//シフト希望データの作成
shiftData = '名前,種別,勤務可能日,勤務可能時間帯,その他条件\n';
$.each(resData.Response.Data, function (index, value) {
if (userName0 != value.ClassHash.ClassX) {
userName = value.ClassHash.ClassX;
} else {
userName = '   ';
}
let data = {
'userName': userName,
'shiftData': value.ClassHash.ClassZ
}
listData.push(data);
userName0 = value.ClassHash.ClassX;
//AI用のシフトデーt作成
let dateList = JSON.parse(value.ClassHash.ClassW).join('');
//let weekList = JSON.parse(value.ClassHash.ClassC).join('');
let timeList = JSON.parse(value.ClassHash.ClassD).join('');
//shiftData += `${value.ClassHash.ClassX},${value.ClassHash.ClassP},${value.ClassHash.ClassZ},${value.ClassHash.ClassE},${value.ClassHash.ClassF},${value.ClassHash.ClassG},${value.ClassHash.ClassH}\n`;
shiftData += `${value.ClassHash.ClassX},${value.ClassHash.ClassP},${dateList},${timeList},${value.ClassHash.ClassF}\n`;
});
//最後に欠員の情報を配置
shiftData += '欠員,社員,いつでも,いつでも,いつでも,他の社員が勤務している時間帯は不可,他のメンバーの勤務を優先し、誰も割当できない時間帯に勤務する\n';
//console.log(shiftData);
let template = Hogan.compile(templateHtml);
let outputHtml = template.render({
"listData": listData
});
// selectボックスとテーブルを挿入
$('#shiftListWindow').append(selectHtml + outputHtml);
// ▼▼ ここからボタン追加 ▼▼
// 既存のボタンがあれば削除
if ($('#generateShiftBtn').length) $('#generateShiftBtn').remove();
if ($('#deleteShiftDataBtn').length) $('#deleteShiftDataBtn').remove();
// ボタンを作成してテーブルの下に追加
const $btn1 = $('<button id="generateShiftBtn" style="margin:10px;padding:8px 24px;font-size:1.1em;border-radius:8px;background:#0078d7;color:#fff;border:none;cursor:pointer;">AIでシフト自動生成</button>');
// ボタンを作成してテーブルの下に追加
const $btn2 = $('<button id="deleteShiftDataBtn" style="margin:10px;padding:8px 24px;font-size:1.1em;border-radius:8px;background:#0078d7;color:#fff;border:none;cursor:pointer;">シフトをすべて削除</button>');
//対象年月のシフトデータの件数を取得
getPleasanterCountByMonth().then(count => {
console.log('件数:' + count);
totalCount = count;
if (count > 0) {
$('#shiftListWindow').append($btn2);
$btn2.on('click', function () {
deletePleasanterDataByDateRange();
});
//$('#deleteShiftDataBtn').show();
} else {
$('#shiftListWindow').append($btn1);
//$('#deleteShiftDataBtn').hide();
}
});
// ボタンクリック時にcreatePrompotText(shiftData)を実行
$btn1.on('click', function () {
createPrompotText(shiftData);
});
// ▲▲ ここまでボタン追加 ▲▲
// selectボックスのイベント
$('#monthSelect').on('change', function () {
let selectedMonth = $(this).val();
// 選択値をローカルストレージに保存
localStorage.setItem('selectedMonth', selectedMonth);
$p.ex.getShiftKibouData(selectedMonth);
});
}

View File

@ -0,0 +1,354 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 2.予定の自動生成
@name :
@siteIds : 310511
@siteTitles : イオン多摩平シフト管理
@disabled: false
*/
async function createPrompotText(shiftData) {
if (totalCount > 0) {
window.alert('対象年月のシフトデータはすでに存在します。\nAIで生成し直す場合は、シフトをすべて削除してから実行してください。');
return false;
}
// 実行確認のポップアップ
if (!window.confirm('シフト希望に基づいて対象月のシフトを生成しますか?')) {
return false;
}
let selectMonth = $('#monthSelect').val();
let prompt = `
#指示
営業所の店長として次の条件で勤務シフトを作成しCSV形式で出力しなさい
#営業時間
午前10時から午後9時 年中無休
#メンバーとそれぞれのシフト可能内容のCSVデータ
${shiftData}
#シフトの条件として下記のルールをすべて完璧に守って構成を作成しなさい
下記に列挙したルールをすべて厳密に厳守してシフトを構成しなさい
営業時間午前10時から午後9時の各時間に必ず1名以上の勤務者がいること
開始時間は10から20までとすること
終了時間は11から21までとすること
開始時間は終了時間よりも必ず少ない数字にすること
同じ時間帯に同時に勤務するメンバーは2名までとすること
勤務時間は午前10時から午後9時の間で1時間単位で設定すること
1日の勤務時間は4時間よりも多い場合は休憩時間を1時間とし休憩時間は勤務時間の真ん中あたりに設定すること
休憩時間は必ず1時間とする勤務時間が奇数の場合は後半の勤務時間を1時間多くすること
休憩時間を除く勤務時間の合計は最大8時間までとすること
1日の勤務時間が4時間以下の場合は休憩時間を含めない
勤務可能日,勤務可能曜日,勤務可能時間帯よりもその他の条件を最優先に考慮すること
勤務可能日,勤務可能曜日,勤務可能時間帯よりもその他の条件を最優先に考慮すること
昼12時から13時には2名の勤務が必ず入るようにすること
同じメンバーが1日に2回以上の勤務時間が入らないようにすること
同じメンバーが5日以上連続して絶対に勤務しないこと
社員よりパートを優先的に配置しパートで配置しきれない日は社員を配置するここと
欠員という名前のメンバーの種別は欠員とすること
対象年月のすべての日程の営業時間午前10時から午後9時において何も割り当てられていない時間帯が無いようにすること
他の勤務者がいる時間帯には欠員は配置しないこと
対象年月のすべての日程の営業時間午前10時から午後9時において誰も勤務できない時間帯がある場合は欠員を割り当てること
#対象年月
${selectMonth}
#出力形式
次のカラムで項目名を含めて構成されるCSV形式のみを出力すること
時間部分には必ず整数を設定すること
対象年月はyyyy年mm月の形式で出力すること
対象年月,対象日付,種別,名前,開始時間,終了時間,勤務時間,休憩時間
`;
//console.log(prompt);
generateAndSaveSchedule(prompt);
/*
// ▼▼▼ プロンプトをテキストファイルでダウンロード ▼▼▼
const now = new Date();
const ymdhms = [
now.getFullYear(),
String(now.getMonth() + 1).padStart(2, '0'),
String(now.getDate()).padStart(2, '0'),
String(now.getHours()).padStart(2, '0'),
String(now.getMinutes()).padStart(2, '0'),
String(now.getSeconds()).padStart(2, '0')
].join('');
const promptFileName = `シフト自動生成プロンプト_${selectMonth}_${ymdhms}.txt`;
const promptBlob = new Blob([prompt], { type: 'text/plain' });
const promptUrl = URL.createObjectURL(promptBlob);
const promptA = document.createElement('a');
promptA.href = promptUrl;
promptA.download = promptFileName;
document.body.appendChild(promptA);
promptA.click();
setTimeout(() => {
document.body.removeChild(promptA);
URL.revokeObjectURL(promptUrl);
}, 100);
// ▲▲▲ プロンプトをテキストファイルでダウンロード ▲▲▲
*/
}
// モーダル表示用関数
function showLoadingModal(message = "AIでシフトを自動生成中です...") {
if ($('#gemini-loading-modal').length) return;
const modalHtml = `
<div id="gemini-loading-modal" style="
position: fixed; z-index: 9999; left: 0; top: 0; width: 100vw; height: 100vh;
background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center;">
<div style="
background: #fff; padding: 30px 40px; border-radius: 12px; box-shadow: 0 2px 16px #888;
font-size: 1.3em; color: #333; text-align: center;">
<span class="gemini-spinner" style="
display: inline-block; width: 32px; height: 32px; border: 4px solid #ccc; border-top: 4px solid #0078d7;
border-radius: 50%; animation: gemini-spin 1s linear infinite; margin-bottom: 16px;"></span><br>
${message}
</div>
</div>
<style>
@keyframes gemini-spin {
0% { transform: rotate(0deg);}
100% { transform: rotate(360deg);}
}
</style>
`;
$('body').append(modalHtml);
}
// モーダル非表示用関数
function hideLoadingModal() {
$('#gemini-loading-modal').remove();
}
// Google Gemini API でプロンプト送信→CSV取得→プリザンターへ登録
async function generateAndSaveSchedule(promptText) {
showLoadingModal();
try {
// 1. Google Gemini API へプロンプト送信
const geminiApiKey = 'AIzaSyAy_BhxPbZmyA7uN6wOrFZpOc3GJQhLAu8';
const geminiApiUrl = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=' + geminiApiKey;
const geminiBody = {
'contents': [{ 'parts': [{ 'text': promptText }] }]
};
const geminiRes = await fetch(geminiApiUrl, {
'method': 'POST',
'headers': { 'Content-Type': 'application/json' },
'body': JSON.stringify(geminiBody)
});
const geminiData = await geminiRes.json();
// Geminiの返答からCSVテキストを抽出
const csvText = geminiData.candidates?.[0]?.content?.parts?.[0]?.text || '';
// 2. CSVをパース
const rows = csvText.trim().split('\n').map(line => line.split(','));
const filteredRows = rows.filter(arr => arr.length >= 2);
//console.log('CSV Data:', filteredRows);
const jsonArray = convertFilteredRowsToJson(filteredRows);
console.log('JSON Data:', jsonArray);
uploadShiftData(jsonArray);
// ▼▼▼ ここからCSV自動ダウンロード処理Shift_JIS対応 ▼▼▼
// 年月の取得(例: プロンプト内や画面のselectから取得
let ym = '';
if ($('#monthSelect').length) {
ym = $('#monthSelect').val();
} else {
const ymMatch = promptText.match(/#対象年月\s*([0-9]{4}年[0-9]{1,2}月)/);
ym = ymMatch ? ymMatch[1] : '年月未取得';
}
// ファイル名生成(末尾に年月日時分秒を追加)
const now = new Date();
const ymdhms = [
now.getFullYear(),
String(now.getMonth() + 1).padStart(2, '0'),
String(now.getDate()).padStart(2, '0'),
String(now.getHours()).padStart(2, '0'),
String(now.getMinutes()).padStart(2, '0'),
String(now.getSeconds()).padStart(2, '0')
].join('');
const fileName = `イオン多摩平自動生成シフト表_${ym}_${ymdhms}.csv`;
// Shift_JISでエンコードしてダウンロード
let sjisArray = Encoding.convert(Encoding.stringToCode(csvText), 'SJIS', 'UNICODE');
let sjisUint8 = new Uint8Array(sjisArray);
const blob = new Blob([sjisUint8], { type: 'text/csv' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = fileName;
document.body.appendChild(a);
//a.click();
setTimeout(() => {
document.body.removeChild(a);
URL.revokeObjectURL(url);
}, 100);
// ▲▲▲ ここまでCSV自動ダウンロード処理Shift_JIS対応 ▲▲▲
} finally {
hideLoadingModal();
window.location.reload();
}
}
async function uploadShiftData(jsonArray) {
const tableId = $p.siteId();
const uploadUrl = `https://${location.hostname}/pleasanter/api/items/${tableId}/bulkupsert`;
const uploadBody = {
'ApiVersion': 1.1,
'ApiKey': apiKey,
'Data': jsonArray
}
//プリザンターから対象のデータをすべて一括削除
const uploadRes = await fetch(uploadUrl, {
'method': 'POST',
'headers': { 'Content-Type': 'application/json' },
'body': JSON.stringify(uploadBody)
});
const resData = await uploadRes.json();
console.log(resData);
}
// filteredRows からJSON配列へ変換項目名置き換えルール適用
function convertFilteredRowsToJson(filteredRows) {
if (!filteredRows || filteredRows.length < 2) return [];
// 1行目をヘッダーとして取得
const header = filteredRows[0];
// 置き換えルール
const keyMap = {
'対象年月': 'ClassA',
'対象日付': 'DateA',
'種別': 'ClassP',
'名前': 'ClassB',
'開始時間': 'NumA',
'終了時間': 'NumB',
'勤務時間': 'NumC',
'休憩時間': 'NumD'
};
// ヘッダーをPleasanter用キーに変換
const mappedHeader = header.map(col => keyMap[col.trim()] || col.trim());
// データ行をJSON化
const jsonArray = filteredRows.slice(1).map(row => {
let obj = {};
obj.ClassHash = {};
obj.NumHash = {};
obj.DateHash = {};
mappedHeader.forEach((key, idx) => {
const val = row[idx] !== undefined ? row[idx].trim() : '';
if (key.startsWith('Class')) {
obj.ClassHash[key] = val;
} else if (key.startsWith('Num')) {
obj.NumHash[key] = val;
} else if (key.startsWith('Date')) {
obj.DateHash[key] = val;
} else {
obj[key] = val;
}
});
return obj;
});
return jsonArray;
}
// 使い方例
// const jsonArray = convertFilteredRowsToJson(filteredRows);
/**
* プリザンターのテーブルからDateA項目が指定年月の範囲にあるデータを一括削除する
*/
async function deletePleasanterDataByDateRange() {
// 実行確認のポップアップ
if (!window.confirm('本当にこの年月のデータを一括削除してよろしいですか?')) {
return false;
}
//自分自身
let tableId = $p.siteId();
//選択した年月を取得
if ($('#monthSelect').length) {
ym = $('#monthSelect').val();
} else {
return false;
}
const year = ym.split('年')[0]; // "2025"
const month = ym.split('年')[1].replace('月', ''); // "06"
//期間の開始日と終了日を作成
const fromDate = year + '/' + month + '/01';
//終了年月の月末日を計算
const lastDate = new Date(fromDate);
lastDate.setMonth(lastDate.getMonth() + 1);
lastDate.setDate(0); // 月末日を取得
const toDate = `${year}/${month}/${lastDate.getDate()}`; // "2025/06/30"
//一括削除
const deleteUrl = `https://${location.hostname}/pleasanter/api/items/${tableId}/bulkdelete`;
const deleteBody = {
'ApiVersion': 1.1,
'ApiKey': apiKey,
'View': {
'ColumnFilterHash': {
'DateA': `["${fromDate} 00:00:00,${toDate} 23:59:59"]`,
'ClassP': '["社員","パート","欠員"]'
}
}
}
//プリザンターから対象のデータをすべて一括削除
const deleteRes = await fetch(deleteUrl, {
'method': 'POST',
'headers': { 'Content-Type': 'application/json' },
'body': JSON.stringify(deleteBody)
});
const resData = await deleteRes.json();
//console.log(resData);
window.location.reload();
}
/**
* #hiddenタグに保存されている件数をチェック
*/
async function getPleasanterCountByMonth() {
let ym = '';
//選択した年月を取得
if ($('#monthSelect').length) {
ym = $('#monthSelect').val();
} else {
return 0;
}
const year = ym.split('年')[0]; // "2025"
const month = ym.split('年')[1].replace('月', ''); // "06"
return parseFloat($('#' + year + '_' + month + '_Count').val()) || 0;
}

View File

@ -0,0 +1,137 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 3.予定編集ウインドウ
@name :
@siteIds : 310511
@siteTitles : イオン多摩平シフト管理
@disabled: false
*/
//$(document).on('click', 'div.item', function (e) {
$p.ex.changeTimeDataWindow = function (dataId, pageX, pageY) {
const $item = $('div.item[data-id="' + dataId + '"]');
$('#edit-modal').remove();
const itemId = $item.attr('data-id');
const posX = pageX;
const posY = pageY;
// 既存データ取得
const textParts = $item.text().trim().split('-');
const startTime = textParts[1] ? textParts[1].trim() : '';
const endTime = textParts[2] ? textParts[2].trim() : '';
// 休憩時間NumDがデータに含まれていれば取得、なければ自動計算
let restTime = '';
if (textParts[3]) {
restTime = textParts[3].trim();
} else if (startTime !== '' && endTime !== '') {
const diff = parseInt(endTime, 10) - parseInt(startTime, 10);
restTime = (diff > 4) ? 1 : 0;
} else {
restTime = 0;
}
// モーダルHTML休憩時間も追加
const modalHtml = `
<div id="edit-modal" style="
position: absolute; left: ${posX}px; top: ${posY}px; z-index: 99999;
background: #fff; border: 1px solid #888; border-radius: 8px; padding: 16px; box-shadow: 0 2px 12px #888;">
<label>開始時間: <input type="number" id="edit-start" min="0" max="23" value="${startTime}" style="width:60px;"> </label><br>
<label>終了時間: <input type="number" id="edit-end" min="0" max="23" value="${endTime}" style="width:60px;"> </label><br>
<label>休憩時間: <input type="number" id="edit-rest" min="0" max="8" value="${restTime}" style="width:60px;" readonly> </label>
</div>
`;
$('body').append(modalHtml);
$('body').css('overflow', 'hidden');
// 入力制限ロジック
$('#edit-start, #edit-end').on('input', function () {
let start = parseInt($('#edit-start').val(), 10);
let end = parseInt($('#edit-end').val(), 10);
// startTimeはendTimeより大きくできない
if (!isNaN(end)) {
$('#edit-start').attr('max', end);
} else {
$('#edit-start').attr('max', 23);
}
// endTimeはstartTimeより小さくできない
if (!isNaN(start)) {
$('#edit-end').attr('min', start);
} else {
$('#edit-end').attr('min', 0);
}
// 休憩時間自動計算
if (!isNaN(start) && !isNaN(end)) {
const diff = end - start;
const rest = (diff > 4) ? 1 : 0;
$('#edit-rest').val(rest);
} else {
$('#edit-rest').val(0);
}
});
setTimeout(() => {
$(document).on('mousedown.editModal', async function (event) {
if (!$(event.target).closest('#edit-modal').length) {
// 入力値取得
const newStart = $('#edit-start').val();
const newEnd = $('#edit-end').val();
const newRest = $('#edit-rest').val();
// 変更がない場合は何もせず閉じる
if (newStart === startTime && newEnd === endTime && newRest == restTime) {
$('#edit-modal').remove();
$(document).off('mousedown.editModal');
$('body').css('overflow', '');
return;
}
// 更新リクエスト送信
const pleasanterUrl = 'https://' + location.hostname + '/pleasanter/api/items/' + itemId + '/update';
const jsonBody = {
'ApiVersion': 1.1,
'ApiKey': apiKey,
'NumHash': {
'NumA': newStart,
'NumB': newEnd,
'NumD': newRest // 休憩時間を追加
}
};
try {
const pleasanterRes = await fetch(pleasanterUrl, {
'method': 'POST',
'headers': { 'Content-Type': 'application/json' },
'body': JSON.stringify(jsonBody)
});
const resData = await pleasanterRes.json();
if (resData.StatusCode === 200) {
$('#edit-modal').remove();
$(document).off('mousedown.editModal');
$('body').css('overflow', '');
location.reload();
} else {
alert('更新に失敗しました');
$('#edit-modal').remove();
$(document).off('mousedown.editModal');
$('body').css('overflow', '');
}
} catch (err) {
alert('通信エラーが発生しました');
$('#edit-modal').remove();
$(document).off('mousedown.editModal');
$('body').css('overflow', '');
}
}
});
}, 10);
}
// モーダル内クリック時は閉じない
$(document).on('click', '#edit-modal', function (e) {
e.stopPropagation();
});

View File

@ -0,0 +1,44 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 1.選択年月リスト作成
@name : 1.選択年月リスト作成
@siteIds : 310511
@siteTitles : イオン多摩平シフト管理
@disabled: false
*/
try {
// 年月を当月から2ヶ月後まで自動表示
let now = new Date();
for (let i = 0; i < 3; i++) {
let date = new Date(now.getFullYear(), now.getMonth() + i, 1);
let year = date.getFullYear();
let month = (date.getMonth() + 1).toString().padStart(2, '0');
let ym = year + '年' + month + '月';
columns.ClassA.AddChoiceHash(ym, ym);
//対象年月ごとの件数を調べてHTML内に保管する
let ymList = [ym]
let classP = ['社員', 'パート'];
let view = {
'View': {
'ColumnFilterHash': {
'ClassA': JSON.stringify(ymList),
'ClassP': JSON.stringify(classP)
}
}
};
let count = items.Count(310511, JSON.stringify(view));
let key = year + '_' + month + '_Count'
hidden.Add(key, count);
}
} catch (e) {
context.Log(e.stack);
}

View File

@ -0,0 +1,76 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : シフト希望表示
@name :
@siteIds : 310511
@siteTitles : イオン多摩平シフト管理
@disabled: false
*/
#listTable {
margin: 5px;
border-collapse: separate !important;
}
#monthSelect {
margin: 5px;
border-radius: 10px;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
font-size: 1.3em;
}
table {
th,
td {
border-color: #999 !important;
}
}
.radius-table {
border-radius: 10px !important;
border-spacing: 0;
border: none;
border-left: 1px solid #999;
border-top: 1px solid #999;
}
.radius-table th {
background-color: lightpink;
text-align: cennter;
white-space: nowrap;
}
.radius-table .userName {
white-space: nowrap;
}
.radius-table td {
text-align: left;
}
.radius-table tr>* {
padding: 5px 10px;
border: none;
border-right: 1px solid #999;
border-bottom: 1px solid #999;
}
.radius-table tr:first-child>*:first-child {
border-radius: 10px 0 0 0;
}
.radius-table tr:first-child>*:last-child {
border-radius: 0 10px 0 0;
}
.radius-table tr:last-child>*:first-child {
border-radius: 0 0 0 10px;
}
.radius-table tr:last-child>*:last-child {
border-radius: 0 0 10px 0;
}

View File

@ -0,0 +1,3 @@
{
"markdown.validate.enabled": true
}

View File

@ -0,0 +1,12 @@
:::mermaid
graph LR;
A(START) --> |作成| B(新規作成)
B --> |一時保管| C(登録未完)
B --> |登録完了| D(登録済み)
C --> |登録完了| D
D --> |保留| E(保留)
D --> |取消| F(取消)
D --> |依頼終了| G(終了)
G --> |復活?| D
:::

View File

@ -0,0 +1,759 @@
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Icons</title>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.13.0/themes/smoothness/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.0/jquery-ui.js"></script>
<style>
body {
font-size: 75%;
font-family: "Trebuchet MS", "Arial", "Helvetica", "Verdana", "sans-serif";
}
ul {
list-style-type: none;
padding: 0;
margin: 0;
}
li {
width: 17em;
float: left;
padding: 0.5em;
}
.ui-icon,
.text {
display: inline-block;
vertical-align: middle;
}
</style>
</head>
<body>
<ul class="ui-helper-clearfix">
<li>
<span class="ui-icon ui-icon-blank"></span>
<span class="text">ui-icon-blank</span>
</li>
<li>
<span class="ui-icon ui-icon-caret-1-n"></span>
<span class="text">ui-icon-caret-1-n</span>
</li>
<li>
<span class="ui-icon ui-icon-caret-1-ne"></span>
<span class="text">ui-icon-caret-1-ne</span>
</li>
<li>
<span class="ui-icon ui-icon-caret-1-e"></span>
<span class="text">ui-icon-caret-1-e</span>
</li>
<li>
<span class="ui-icon ui-icon-caret-1-se"></span>
<span class="text">ui-icon-caret-1-se</span>
</li>
<li>
<span class="ui-icon ui-icon-caret-1-s"></span>
<span class="text">ui-icon-caret-1-s</span>
</li>
<li>
<span class="ui-icon ui-icon-caret-1-sw"></span>
<span class="text">ui-icon-caret-1-sw</span>
</li>
<li>
<span class="ui-icon ui-icon-caret-1-w"></span>
<span class="text">ui-icon-caret-1-w</span>
</li>
<li>
<span class="ui-icon ui-icon-caret-1-nw"></span>
<span class="text">ui-icon-caret-1-nw</span>
</li>
<li>
<span class="ui-icon ui-icon-caret-2-n-s"></span>
<span class="text">ui-icon-caret-2-n-s</span>
</li>
<li>
<span class="ui-icon ui-icon-caret-2-e-w"></span>
<span class="text">ui-icon-caret-2-e-w</span>
</li>
<li>
<span class="ui-icon ui-icon-triangle-1-n"></span>
<span class="text">ui-icon-triangle-1-n</span>
</li>
<li>
<span class="ui-icon ui-icon-triangle-1-ne"></span>
<span class="text">ui-icon-triangle-1-ne</span>
</li>
<li>
<span class="ui-icon ui-icon-triangle-1-e"></span>
<span class="text">ui-icon-triangle-1-e</span>
</li>
<li>
<span class="ui-icon ui-icon-triangle-1-se"></span>
<span class="text">ui-icon-triangle-1-se</span>
</li>
<li>
<span class="ui-icon ui-icon-triangle-1-s"></span>
<span class="text">ui-icon-triangle-1-s</span>
</li>
<li>
<span class="ui-icon ui-icon-triangle-1-sw"></span>
<span class="text">ui-icon-triangle-1-sw</span>
</li>
<li>
<span class="ui-icon ui-icon-triangle-1-w"></span>
<span class="text">ui-icon-triangle-1-w</span>
</li>
<li>
<span class="ui-icon ui-icon-triangle-1-nw"></span>
<span class="text">ui-icon-triangle-1-nw</span>
</li>
<li>
<span class="ui-icon ui-icon-triangle-2-n-s"></span>
<span class="text">ui-icon-triangle-2-n-s</span>
</li>
<li>
<span class="ui-icon ui-icon-triangle-2-e-w"></span>
<span class="text">ui-icon-triangle-2-e-w</span>
</li>
<li>
<span class="ui-icon ui-icon-arrow-1-n"></span>
<span class="text">ui-icon-arrow-1-n</span>
</li>
<li>
<span class="ui-icon ui-icon-arrow-1-ne"></span>
<span class="text">ui-icon-arrow-1-ne</span>
</li>
<li>
<span class="ui-icon ui-icon-arrow-1-e"></span>
<span class="text">ui-icon-arrow-1-e</span>
</li>
<li>
<span class="ui-icon ui-icon-arrow-1-se"></span>
<span class="text">ui-icon-arrow-1-se</span>
</li>
<li>
<span class="ui-icon ui-icon-arrow-1-s"></span>
<span class="text">ui-icon-arrow-1-s</span>
</li>
<li>
<span class="ui-icon ui-icon-arrow-1-sw"></span>
<span class="text">ui-icon-arrow-1-sw</span>
</li>
<li>
<span class="ui-icon ui-icon-arrow-1-w"></span>
<span class="text">ui-icon-arrow-1-w</span>
</li>
<li>
<span class="ui-icon ui-icon-arrow-1-nw"></span>
<span class="text">ui-icon-arrow-1-nw</span>
</li>
<li>
<span class="ui-icon ui-icon-arrow-2-n-s"></span>
<span class="text">ui-icon-arrow-2-n-s</span>
</li>
<li>
<span class="ui-icon ui-icon-arrow-2-ne-sw"></span>
<span class="text">ui-icon-arrow-2-ne-sw</span>
</li>
<li>
<span class="ui-icon ui-icon-arrow-2-e-w"></span>
<span class="text">ui-icon-arrow-2-e-w</span>
</li>
<li>
<span class="ui-icon ui-icon-arrow-2-se-nw"></span>
<span class="text">ui-icon-arrow-2-se-nw</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowstop-1-n"></span>
<span class="text">ui-icon-arrowstop-1-n</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowstop-1-e"></span>
<span class="text">ui-icon-arrowstop-1-e</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowstop-1-s"></span>
<span class="text">ui-icon-arrowstop-1-s</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowstop-1-w"></span>
<span class="text">ui-icon-arrowstop-1-w</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthick-1-n"></span>
<span class="text">ui-icon-arrowthick-1-n</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthick-1-ne"></span>
<span class="text">ui-icon-arrowthick-1-ne</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthick-1-e"></span>
<span class="text">ui-icon-arrowthick-1-e</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthick-1-se"></span>
<span class="text">ui-icon-arrowthick-1-se</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthick-1-s"></span>
<span class="text">ui-icon-arrowthick-1-s</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthick-1-sw"></span>
<span class="text">ui-icon-arrowthick-1-sw</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthick-1-w"></span>
<span class="text">ui-icon-arrowthick-1-w</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthick-1-nw"></span>
<span class="text">ui-icon-arrowthick-1-nw</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthick-2-n-s"></span>
<span class="text">ui-icon-arrowthick-2-n-s</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthick-2-ne-sw"></span>
<span class="text">ui-icon-arrowthick-2-ne-sw</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthick-2-e-w"></span>
<span class="text">ui-icon-arrowthick-2-e-w</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthick-2-se-nw"></span>
<span class="text">ui-icon-arrowthick-2-se-nw</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthickstop-1-n"></span>
<span class="text">ui-icon-arrowthickstop-1-n</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthickstop-1-e"></span>
<span class="text">ui-icon-arrowthickstop-1-e</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthickstop-1-s"></span>
<span class="text">ui-icon-arrowthickstop-1-s</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowthickstop-1-w"></span>
<span class="text">ui-icon-arrowthickstop-1-w</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowreturnthick-1-w"></span>
<span class="text">ui-icon-arrowreturnthick-1-w</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowreturnthick-1-n"></span>
<span class="text">ui-icon-arrowreturnthick-1-n</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowreturnthick-1-e"></span>
<span class="text">ui-icon-arrowreturnthick-1-e</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowreturnthick-1-s"></span>
<span class="text">ui-icon-arrowreturnthick-1-s</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowreturn-1-w"></span>
<span class="text">ui-icon-arrowreturn-1-w</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowreturn-1-n"></span>
<span class="text">ui-icon-arrowreturn-1-n</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowreturn-1-e"></span>
<span class="text">ui-icon-arrowreturn-1-e</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowreturn-1-s"></span>
<span class="text">ui-icon-arrowreturn-1-s</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowrefresh-1-w"></span>
<span class="text">ui-icon-arrowrefresh-1-w</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowrefresh-1-n"></span>
<span class="text">ui-icon-arrowrefresh-1-n</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowrefresh-1-e"></span>
<span class="text">ui-icon-arrowrefresh-1-e</span>
</li>
<li>
<span class="ui-icon ui-icon-arrowrefresh-1-s"></span>
<span class="text">ui-icon-arrowrefresh-1-s</span>
</li>
<li>
<span class="ui-icon ui-icon-arrow-4"></span>
<span class="text">ui-icon-arrow-4</span>
</li>
<li>
<span class="ui-icon ui-icon-arrow-4-diag"></span>
<span class="text">ui-icon-arrow-4-diag</span>
</li>
<li>
<span class="ui-icon ui-icon-extlink"></span>
<span class="text">ui-icon-extlink</span>
</li>
<li>
<span class="ui-icon ui-icon-newwin"></span>
<span class="text">ui-icon-newwin</span>
</li>
<li>
<span class="ui-icon ui-icon-refresh"></span>
<span class="text">ui-icon-refresh</span>
</li>
<li>
<span class="ui-icon ui-icon-shuffle"></span>
<span class="text">ui-icon-shuffle</span>
</li>
<li>
<span class="ui-icon ui-icon-transfer-e-w"></span>
<span class="text">ui-icon-transfer-e-w</span>
</li>
<li>
<span class="ui-icon ui-icon-transferthick-e-w"></span>
<span class="text">ui-icon-transferthick-e-w</span>
</li>
<li>
<span class="ui-icon ui-icon-folder-collapsed"></span>
<span class="text">ui-icon-folder-collapsed</span>
</li>
<li>
<span class="ui-icon ui-icon-folder-open"></span>
<span class="text">ui-icon-folder-open</span>
</li>
<li>
<span class="ui-icon ui-icon-document"></span>
<span class="text">ui-icon-document</span>
</li>
<li>
<span class="ui-icon ui-icon-document-b"></span>
<span class="text">ui-icon-document-b</span>
</li>
<li>
<span class="ui-icon ui-icon-note"></span>
<span class="text">ui-icon-note</span>
</li>
<li>
<span class="ui-icon ui-icon-mail-closed"></span>
<span class="text">ui-icon-mail-closed</span>
</li>
<li>
<span class="ui-icon ui-icon-mail-open"></span>
<span class="text">ui-icon-mail-open</span>
</li>
<li>
<span class="ui-icon ui-icon-suitcase"></span>
<span class="text">ui-icon-suitcase</span>
</li>
<li>
<span class="ui-icon ui-icon-comment"></span>
<span class="text">ui-icon-comment</span>
</li>
<li>
<span class="ui-icon ui-icon-person"></span>
<span class="text">ui-icon-person</span>
</li>
<li>
<span class="ui-icon ui-icon-print"></span>
<span class="text">ui-icon-print</span>
</li>
<li>
<span class="ui-icon ui-icon-trash"></span>
<span class="text">ui-icon-trash</span>
</li>
<li>
<span class="ui-icon ui-icon-locked"></span>
<span class="text">ui-icon-locked</span>
</li>
<li>
<span class="ui-icon ui-icon-unlocked"></span>
<span class="text">ui-icon-unlocked</span>
</li>
<li>
<span class="ui-icon ui-icon-bookmark"></span>
<span class="text">ui-icon-bookmark</span>
</li>
<li>
<span class="ui-icon ui-icon-tag"></span>
<span class="text">ui-icon-tag</span>
</li>
<li>
<span class="ui-icon ui-icon-home"></span>
<span class="text">ui-icon-home</span>
</li>
<li>
<span class="ui-icon ui-icon-flag"></span>
<span class="text">ui-icon-flag</span>
</li>
<li>
<span class="ui-icon ui-icon-calculator"></span>
<span class="text">ui-icon-calculator</span>
</li>
<li>
<span class="ui-icon ui-icon-cart"></span>
<span class="text">ui-icon-cart</span>
</li>
<li>
<span class="ui-icon ui-icon-pencil"></span>
<span class="text">ui-icon-pencil</span>
</li>
<li>
<span class="ui-icon ui-icon-clock"></span>
<span class="text">ui-icon-clock</span>
</li>
<li>
<span class="ui-icon ui-icon-disk"></span>
<span class="text">ui-icon-disk</span>
</li>
<li>
<span class="ui-icon ui-icon-calendar"></span>
<span class="text">ui-icon-calendar</span>
</li>
<li>
<span class="ui-icon ui-icon-zoomin"></span>
<span class="text">ui-icon-zoomin</span>
</li>
<li>
<span class="ui-icon ui-icon-zoomout"></span>
<span class="text">ui-icon-zoomout</span>
</li>
<li>
<span class="ui-icon ui-icon-search"></span>
<span class="text">ui-icon-search</span>
</li>
<li>
<span class="ui-icon ui-icon-wrench"></span>
<span class="text">ui-icon-wrench</span>
</li>
<li>
<span class="ui-icon ui-icon-gear"></span>
<span class="text">ui-icon-gear</span>
</li>
<li>
<span class="ui-icon ui-icon-heart"></span>
<span class="text">ui-icon-heart</span>
</li>
<li>
<span class="ui-icon ui-icon-star"></span>
<span class="text">ui-icon-star</span>
</li>
<li>
<span class="ui-icon ui-icon-link"></span>
<span class="text">ui-icon-link</span>
</li>
<li>
<span class="ui-icon ui-icon-cancel"></span>
<span class="text">ui-icon-cancel</span>
</li>
<li>
<span class="ui-icon ui-icon-plus"></span>
<span class="text">ui-icon-plus</span>
</li>
<li>
<span class="ui-icon ui-icon-plusthick"></span>
<span class="text">ui-icon-plusthick</span>
</li>
<li>
<span class="ui-icon ui-icon-minus"></span>
<span class="text">ui-icon-minus</span>
</li>
<li>
<span class="ui-icon ui-icon-minusthick"></span>
<span class="text">ui-icon-minusthick</span>
</li>
<li>
<span class="ui-icon ui-icon-close"></span>
<span class="text">ui-icon-close</span>
</li>
<li>
<span class="ui-icon ui-icon-closethick"></span>
<span class="text">ui-icon-closethick</span>
</li>
<li>
<span class="ui-icon ui-icon-key"></span>
<span class="text">ui-icon-key</span>
</li>
<li>
<span class="ui-icon ui-icon-lightbulb"></span>
<span class="text">ui-icon-lightbulb</span>
</li>
<li>
<span class="ui-icon ui-icon-scissors"></span>
<span class="text">ui-icon-scissors</span>
</li>
<li>
<span class="ui-icon ui-icon-clipboard"></span>
<span class="text">ui-icon-clipboard</span>
</li>
<li>
<span class="ui-icon ui-icon-copy"></span>
<span class="text">ui-icon-copy</span>
</li>
<li>
<span class="ui-icon ui-icon-contact"></span>
<span class="text">ui-icon-contact</span>
</li>
<li>
<span class="ui-icon ui-icon-image"></span>
<span class="text">ui-icon-image</span>
</li>
<li>
<span class="ui-icon ui-icon-video"></span>
<span class="text">ui-icon-video</span>
</li>
<li>
<span class="ui-icon ui-icon-script"></span>
<span class="text">ui-icon-script</span>
</li>
<li>
<span class="ui-icon ui-icon-alert"></span>
<span class="text">ui-icon-alert</span>
</li>
<li>
<span class="ui-icon ui-icon-info"></span>
<span class="text">ui-icon-info</span>
</li>
<li>
<span class="ui-icon ui-icon-notice"></span>
<span class="text">ui-icon-notice</span>
</li>
<li>
<span class="ui-icon ui-icon-help"></span>
<span class="text">ui-icon-help</span>
</li>
<li>
<span class="ui-icon ui-icon-check"></span>
<span class="text">ui-icon-check</span>
</li>
<li>
<span class="ui-icon ui-icon-bullet"></span>
<span class="text">ui-icon-bullet</span>
</li>
<li>
<span class="ui-icon ui-icon-radio-off"></span>
<span class="text">ui-icon-radio-off</span>
</li>
<li>
<span class="ui-icon ui-icon-radio-on"></span>
<span class="text">ui-icon-radio-on</span>
</li>
<li>
<span class="ui-icon ui-icon-pin-w"></span>
<span class="text">ui-icon-pin-w</span>
</li>
<li>
<span class="ui-icon ui-icon-pin-s"></span>
<span class="text">ui-icon-pin-s</span>
</li>
<li>
<span class="ui-icon ui-icon-play"></span>
<span class="text">ui-icon-play</span>
</li>
<li>
<span class="ui-icon ui-icon-pause"></span>
<span class="text">ui-icon-pause</span>
</li>
<li>
<span class="ui-icon ui-icon-seek-next"></span>
<span class="text">ui-icon-seek-next</span>
</li>
<li>
<span class="ui-icon ui-icon-seek-prev"></span>
<span class="text">ui-icon-seek-prev</span>
</li>
<li>
<span class="ui-icon ui-icon-seek-end"></span>
<span class="text">ui-icon-seek-end</span>
</li>
<li>
<span class="ui-icon ui-icon-seek-first"></span>
<span class="text">ui-icon-seek-first</span>
</li>
<li>
<span class="ui-icon ui-icon-stop"></span>
<span class="text">ui-icon-stop</span>
</li>
<li>
<span class="ui-icon ui-icon-eject"></span>
<span class="text">ui-icon-eject</span>
</li>
<li>
<span class="ui-icon ui-icon-volume-off"></span>
<span class="text">ui-icon-volume-off</span>
</li>
<li>
<span class="ui-icon ui-icon-volume-on"></span>
<span class="text">ui-icon-volume-on</span>
</li>
<li>
<span class="ui-icon ui-icon-power"></span>
<span class="text">ui-icon-power</span>
</li>
<li>
<span class="ui-icon ui-icon-signal-diag"></span>
<span class="text">ui-icon-signal-diag</span>
</li>
<li>
<span class="ui-icon ui-icon-signal"></span>
<span class="text">ui-icon-signal</span>
</li>
<li>
<span class="ui-icon ui-icon-battery-0"></span>
<span class="text">ui-icon-battery-0</span>
</li>
<li>
<span class="ui-icon ui-icon-battery-1"></span>
<span class="text">ui-icon-battery-1</span>
</li>
<li>
<span class="ui-icon ui-icon-battery-2"></span>
<span class="text">ui-icon-battery-2</span>
</li>
<li>
<span class="ui-icon ui-icon-battery-3"></span>
<span class="text">ui-icon-battery-3</span>
</li>
<li>
<span class="ui-icon ui-icon-circle-plus"></span>
<span class="text">ui-icon-circle-plus</span>
</li>
<li>
<span class="ui-icon ui-icon-circle-minus"></span>
<span class="text">ui-icon-circle-minus</span>
</li>
<li>
<span class="ui-icon ui-icon-circle-close"></span>
<span class="text">ui-icon-circle-close</span>
</li>
<li>
<span class="ui-icon ui-icon-circle-triangle-e"></span>
<span class="text">ui-icon-circle-triangle-e</span>
</li>
<li>
<span class="ui-icon ui-icon-circle-triangle-s"></span>
<span class="text">ui-icon-circle-triangle-s</span>
</li>
<li>
<span class="ui-icon ui-icon-circle-triangle-w"></span>
<span class="text">ui-icon-circle-triangle-w</span>
</li>
<li>
<span class="ui-icon ui-icon-circle-triangle-n"></span>
<span class="text">ui-icon-circle-triangle-n</span>
</li>
<li>
<span class="ui-icon ui-icon-circle-arrow-e"></span>
<span class="text">ui-icon-circle-arrow-e</span>
</li>
<li>
<span class="ui-icon ui-icon-circle-arrow-s"></span>
<span class="text">ui-icon-circle-arrow-s</span>
</li>
<li>
<span class="ui-icon ui-icon-circle-arrow-w"></span>
<span class="text">ui-icon-circle-arrow-w</span>
</li>
<li>
<span class="ui-icon ui-icon-circle-arrow-n"></span>
<span class="text">ui-icon-circle-arrow-n</span>
</li>
<li>
<span class="ui-icon ui-icon-circle-zoomin"></span>
<span class="text">ui-icon-circle-zoomin</span>
</li>
<li>
<span class="ui-icon ui-icon-circle-zoomout"></span>
<span class="text">ui-icon-circle-zoomout</span>
</li>
<li>
<span class="ui-icon ui-icon-circle-check"></span>
<span class="text">ui-icon-circle-check</span>
</li>
<li>
<span class="ui-icon ui-icon-circlesmall-plus"></span>
<span class="text">ui-icon-circlesmall-plus</span>
</li>
<li>
<span class="ui-icon ui-icon-circlesmall-minus"></span>
<span class="text">ui-icon-circlesmall-minus</span>
</li>
<li>
<span class="ui-icon ui-icon-circlesmall-close"></span>
<span class="text">ui-icon-circlesmall-close</span>
</li>
<li>
<span class="ui-icon ui-icon-squaresmall-plus"></span>
<span class="text">ui-icon-squaresmall-plus</span>
</li>
<li>
<span class="ui-icon ui-icon-squaresmall-minus"></span>
<span class="text">ui-icon-squaresmall-minus</span>
</li>
<li>
<span class="ui-icon ui-icon-squaresmall-close"></span>
<span class="text">ui-icon-squaresmall-close</span>
</li>
<li>
<span class="ui-icon ui-icon-grip-dotted-vertical"></span>
<span class="text">ui-icon-grip-dotted-vertical</span>
</li>
<li>
<span class="ui-icon ui-icon-grip-dotted-horizontal"></span>
<span class="text">ui-icon-grip-dotted-horizontal</span>
</li>
<li>
<span class="ui-icon ui-icon-grip-solid-vertical"></span>
<span class="text">ui-icon-grip-solid-vertical</span>
</li>
<li>
<span class="ui-icon ui-icon-grip-solid-horizontal"></span>
<span class="text">ui-icon-grip-solid-horizontal</span>
</li>
<li>
<span class="ui-icon ui-icon-gripsmall-diagonal-se"></span>
<span class="text">ui-icon-gripsmall-diagonal-se</span>
</li>
<li>
<span class="ui-icon ui-icon-grip-diagonal-se"></span>
<span class="text">ui-icon-grip-diagonal-se</span>
</li>
</ul>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 812 KiB

View File

@ -0,0 +1,4 @@
{
"apiKey": "c38903157cbffc30961f50bc29d0991a6cd8af495ab3009b05c5f98e82b2e61b94ba2d5c0a48fc518b1cd74c9e427b01051a228f670f3c5282544dfbec93db87",
"url": "https://neo999.next-hd.net/pleasanter/"
}

View File

@ -0,0 +1,386 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 01_基本スクリプト
@name :
@siteIds : 310406
@siteTitles : Re①基本情報
@disabled: false
*/
let pageLoading = 0;
let apiKey = '6504c8a807677a3a576e10327f3c19876c55736ee45d4a845796b9e7f5e087bfd4bd0d8184863da8cf1733ca635111432ab334aea59102b06a96ee6d2c05190d';
//メッセージデータ
let messageData = JSON.parse($('#messageData').val() || '[]');
//----------------------------------------------------------------------
//初期処理
window.addEventListener('load', function () {
if (pageLoading == 0) {
console.log('Window load Event');
$p.ex.onLoad();
}
});
$p.events.on_editor_load = function () {
if (pageLoading == 0) {
console.log('on Editor Load');
$p.ex.onLoad();
}
}
//----------------------------------------------------------------------
$p.ex.onLoad = function () {
//ロード開始
pageLoading = 1;
//初期処理
$p.ex.init();
}
//初期処理
$p.ex.init = function () {
console.log('initialize...');
//初期化
//一時保存ボタン処理1
$('#UpdateCommand').empty();
$('#UpdateCommand').html(`一時保存`);
$('#UpdateCommand').addClass('new-status-light-lime');
//プロセスボタン調整
$p.ex.processButtonControl();
//依頼票登録処理の場合は何もしない
if ($('#Results_Class199').val() == '1') return;
//新規作成時のみ処理
if ($p.action() == 'new') {
//年度自動保存
let now = new Date();
let year = parseFloat(now.getFullYear()) - 2000;
let month = now.getMonth() + 1;
let code;
//年保存
$p.set($('#Results_ClassF'), year);
//四半期記号
switch (month) {
case 1:
case 2:
case 3:
code = 'A';
break;
case 4:
case 5:
case 6:
code = 'B';
break;
case 7:
case 8:
case 9:
code = 'C';
break;
case 10:
case 11:
case 12:
code = 'D';
break;
}
$p.set($('#Results_ClassG'), code);
$p.set($('#Results_ClassH'), code);
} else {
//スタートアップメッセージ表示
$p.ex.startupMessage();
}
//読取り専用
$('.code-readonly2 input').prop('tabindex', '-1');
$('.code-readonly2 select').prop('tabindex', '-1');
//Re②依頼票 作成ボタンを非表示
$('button[data-from-site-id="' + $p.siteId() + '"]:contains("Re②依頼票")').hide();
$('button[data-from-site-id="' + $p.siteId() + '"]:contains("Re③依頼項目")').hide();
}
//入力チェック後処理
$p.events.before_validate = function (args) {
}
//入力チェック後処理
$p.events.after_validate = function (args) {
//エリア-ブランド結合
$p.ex.areaBrandName();
//施主名 姓名結合
$p.ex.setCustomerName();
//担当者一覧マージ
$p.ex.usersMarge1();
//CC一覧マージ
$p.ex.usersMarge2();
//担当者・CC一覧マージ
$p.ex.usersMarge3();
//変更履歴の保存
$p.ex.saveHistory();
}
//画面更新後
$p.events.after_set_Update = function (args) {
//初期処理
$p.ex.init();
//一時保存ボタン処理2
$('#UpdateCommand').empty();
$('#UpdateCommand').html(`<span class="ui-button-icon ui-icon ui-icon-disk"></span>
<span class="ui-button-icon-space"> </span>
一時保存`);
//一時保存メッセージ
let json8val = JSON.parse(args.json[8].Value);
if (json8val.Id == 'Updated') {
$p.ex.setMyMessage('new-status-light-lime', '基本情報の内容が一時保存されました');
}
//依頼票登録ボタンが押されたら
if ($('#Results_Class199').val() == '1') {
$p.apiUpdate({
'id': $p.id(),
'data': {
'ApiVersion': 1.1,
'ClassHash': {
'Class199': '0'
}
},
'done': function (data) {
//フラグを0に戻してから依頼票ボタンを押す
$('button[data-from-site-id="' + $p.siteId() + '"]:contains("Re②依頼票")').click();
},
'fail': function (data) {
console.log(data);
}
});
}
}
//エリアとブランド名を合体させて格納する
$p.ex.areaBrandName = function () {
let area = $('#Results_Class011 option:selected').text();
let brand = $('#Results_Class012 option:selected').text();
if (area && brand) {
$p.set($('#Results_ClassL'), area + ' ' + brand);
}
}
//施主名 姓名結合
$p.ex.setCustomerName = function () {
let name1 = $('#Results_Class001').val();
let name2 = $('#Results_Class002').val();
let customerName = name1 + ' ' + name2 + ' 様';
$p.set($('#Results_ClassK'), customerName);
let eigyo = $('#Results_Class022').text();
let area = $('#Results_Class011 option:selected').text();
let flagData = name1 + ' ' + name2 + '_' + area + '_' + eigyo;
$p.set($('#Results_Class200'), flagData);
}
//担当者一覧マージ
$p.ex.usersMarge1 = function () {
let users = [];
$('#Results_ClassB').val() && users.push($('#Results_ClassB').val()); //入力者
$('#Results_Class022').val() && users.push($('#Results_Class022').val()); //主担当営業 Class022
$('#Results_Class023').val() && users.push($('#Results_Class023').val()); //副担当営業 Class023
$('#Results_Class024').val() && users.push($('#Results_Class024').val()); //営業設計 Class024
$('#Results_Class025').val() && users.push($('#Results_Class025').val()); //担当監督 Class025
$('#Results_Class026').val() && users.push($('#Results_Class026').val()); //担当IC Class026
$('#Results_Class027').val() && users.push($('#Results_Class027').val()); //管理設計 Class027
$('#Results_Class028').val() && users.push($('#Results_Class028').val()); //所属長 Class028
$p.set($('#Results_Class191'), JSON.stringify(users));
}
//CC一覧マージ
$p.ex.usersMarge2 = function () {
let users = [];
$('#Results_Class031').val() && users.push($('#Results_Class031').val()); //CC1
$('#Results_Class032').val() && users.push($('#Results_Class032').val()); //CC2
$('#Results_Class033').val() && users.push($('#Results_Class033').val()); //CC3
$('#Results_Class034').val() && users.push($('#Results_Class034').val()); //CC4
$p.set($('#Results_Class192'), JSON.stringify(users));
}
//担当者・CC一覧マージ
$p.ex.usersMarge3 = function () {
/*
let users = [];
$('#Results_Class022').val() && users.push($('#Results_Class022').val()); //主担当営業 Class022
$('#Results_Class023').val() && users.push($('#Results_Class023').val()); //副担当営業 Class023
$('#Results_Class024').val() && users.push($('#Results_Class024').val()); //営業設計 Class024
$('#Results_Class025').val() && users.push($('#Results_Class025').val()); //担当監督 Class025
$('#Results_Class026').val() && users.push($('#Results_Class026').val()); //担当IC Class026
$('#Results_Class027').val() && users.push($('#Results_Class027').val()); //管理設計 Class027
$('#Results_Class028').val() && users.push($('#Results_Class028').val()); //所属長 Class028
$('#Results_Class031').val() && users.push($('#Results_Class031').val()); //CC1
$('#Results_Class032').val() && users.push($('#Results_Class032').val()); //CC2
$('#Results_Class033').val() && users.push($('#Results_Class033').val()); //CC3
$('#Results_Class034').val() && users.push($('#Results_Class034').val()); //CC4
*/
//担当者一覧とCC一覧をマージして保管
let mergeAry = [...$('#Results_Class191').val(), ...$('#Results_Class192').val()];
mergeAry.push($('#Results_ClassB').val());
$p.set($('#Results_Class193'), JSON.stringify(mergeAry));
}
//マスターシートの選択を外したら欄を削除する
$p.on('change', 'ClassY', function () {
//マスターシート リンク解除
if (!$("#Results_ClassY").val()) {
$p.ex.clearMSSData();
//100ms待機後にメッセージ表示
setTimeout(() => {
$p.ex.setMyMessage('new-status-yellow', 'マスターシートの情報を削除しました');
}, 100);
} else {
$p.ex.getMSSData();
}
});
$p.ex.getMSSData = function () {
let resultId = $("#Results_ClassY").val();
$p.apiGet({
'id': resultId,
'done': function (data) {
console.log(data);
if (data.Response.TotalCount == '1') {
let mssData = data.Response.Data[0];
//既存データクリア
console.log('Clear MSS Data before Set');
$p.ex.clearMSSData();
console.log('Set MSS Data');
$p.set($('#Results_ClassZ'), mssData.ClassHash.ClassA); //契約コード
$p.set($('#Results_Class001'), mssData.ClassHash.Class001); //施主・姓
$p.set($('#Results_Class002'), mssData.ClassHash.Class002); //施主・名
$p.set($('#Results_Class003'), mssData.ClassHash.Class003); //施主・姓(カナ)
$p.set($('#Results_Class004'), mssData.ClassHash.Class004); //施主・名(カナ)
$p.set($('#Results_Class005'), mssData.ClassHash.ClassQ); //工事名
$p.set($('#Results_Class006'), mssData.ClassHash.ClassR); //工事名_カナ
$p.set($('#Results_Class010'), mssData.ClassHash.Class029); //建上地
$p.set($('#Results_Class011'), mssData.ClassHash.ClassW); //エリア
$p.set($('#Results_Class012'), mssData.ClassHash.Class033); //契約ブランド
$p.set($('#Results_Class013'), mssData.ClassHash.Class040); //防火指定
$p.set($('#Results_Class014'), mssData.ClassHash.Class043); //建物種類
$p.set($('#Results_Class021'), mssData.ClassHash.ClassF); //契約営業所
$p.set($('#Results_Class022'), mssData.ClassHash.ClassG); //主担当営業
$p.set($('#Results_Class023'), mssData.ClassHash.ClassH); //副担当営業
$p.set($('#Results_Class024'), mssData.ClassHash.ClassI); //営業設計
$p.set($('#Results_Class025'), mssData.ClassHash.ClassJ); //担当監督
$p.set($('#Results_Class026'), mssData.ClassHash.ClassK); //担当IC
$p.set($('#Results_Class027'), mssData.ClassHash.ClassL); //管理設計
$p.set($('#Results_Class028'), mssData.ClassHash.ClassY); //所属長
if (mssData.DateHash.DateH != '1899-12-30T00:00:00') {
let dateH = new Date(mssData.DateHash.DateH);
let dateHStr = dateH.getFullYear() + '/' + (dateH.getMonth() + 1).toString().padStart(2, '0') + '/' + dateH.getDate().toString().padStart(2, '0');
$p.set($('#Results_Date001'), dateHStr);
}
if (mssData.DateHash.Date063 != '1899-12-30T00:00:00') {
let date063 = new Date(mssData.DateHash.Date063);
let date063Str = date063.getFullYear() + '/' + (date063.getMonth() + 1).toString().padStart(2, '0') + '/' + date063.getDate().toString().padStart(2, '0');
$p.set($('#Results_Date002'), date063Str);
}
$p.set($('#Results_ClassS'), '1'); //案件状況
$p.clearMessage();
$p.ex.setMyMessage('new-status-lime', 'マスターシートの情報を取得しました');
} else {
//既存データクリア
$p.ex.clearMSSData();
}
},
'fail': function (data) {
console.log(data);
//既存データクリア
$p.ex.clearMSSData();
}
});
}
//MSSからの引用データをクリア
$p.ex.clearMSSData = function () {
console.log('Clear MSS Data');
$p.set($('#Results_ClassS'), '0'); //案件状況
$p.set($('#Results_ClassZ'), ''); //契約コード
$p.set($('#Results_Class001'), ''); //施主・姓
$p.set($('#Results_Class002'), ''); //施主・名
$p.set($('#Results_Class003'), ''); //施主・姓(カナ)
$p.set($('#Results_Class004'), ''); //施主・名(カナ)
$p.set($('#Results_Class005'), ''); //連名
$p.set($('#Results_Class006'), ''); //連名(カナ)
$p.set($('#Results_Class010'), ''); //建上地
$p.set($('#Results_Class011'), ''); //エリア
$p.set($('#Results_Class012'), ''); //契約ブランド
$p.set($('#Results_Class013'), ''); //防火指定
$p.set($('#Results_Class014'), ''); //建物種類
$p.set($('#Results_ClassK'), ''); //施主名
$p.set($('#Results_ClassL'), ''); //エリアブランド
$p.set($('#Results_ClassM'), ''); //エリア記号
$p.set($('#Results_ClassN'), ''); //ブランド記号
$p.set($('#Results_Class021'), ''); //契約営業所
$p.set($('#Results_Class022'), ''); //主担当営業
$p.set($('#Results_Class023'), ''); //副担当営業
$p.set($('#Results_Class024'), ''); //営業設計
$p.set($('#Results_Class025'), ''); //担当監督
$p.set($('#Results_Class026'), ''); //担当IC
$p.set($('#Results_Class027'), ''); //管理設計
$p.set($('#Results_Class028'), ''); //所属長
$p.set($('#Results_Date001'), ''); //承認図予定日
$p.set($('#Results_Date002'), ''); //着工予定日
}
/**
* 指定したIDの<select>タグにプレースホルダー的な<option>を挿入する関数
* @param {string} selectId - <select>タグのID
*/
function addPlaceholderOption(selectId) {
//値が空の場合、プレースホルダー的なoptionを追加
const val = $(`#${selectId}`).val();
if (!val) {
//つ目のoptionのテキストを変更
$(`#${selectId} option:first`).text('次から選択してください');
}
//console.log($(`#${selectId}`));
}

View File

@ -0,0 +1,122 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 02_プロセス処理
@name :
@siteIds : 310406
@siteTitles : Re①基本情報
@disabled: false
*/
//プロセスごとに実行スクリプト
$p.ex.processScript = function (procNum) {
//プロセス共通処理 ------------------------------------------------------------------
//確認メッセージの取得
let confirmMessage = $('#Process_' + procNum).attr('data-confirm');
//実行確認
if (!confirm(confirmMessage)) {
//キャンセルなら終了
console.log('Process_' + procNum + ' はキャンセルされました');
return false;
} else {
//オリジナルの確認メッセージの削除
$('#Process_' + procNum).removeAttr('data-confirm');
}
//プロセス名の取得
let procName = $('#Process_' + procNum).text().replace(/^\s+/, '');
console.log(`▷Process_${procNum} : ${procName} 処理開始`);
//--------------------------------------------------------------------------------
//プロセスごとの個別処理
switch (procNum) {
case '1': //登録完了
break
case '2': //依頼終了
break
case '3': //保留
break;
case '4': //取消
break;
case '5': //依頼票登録
break;
case '6': //案件復帰
break;
case '7': //保留(営業積算)
break;
case '8': //取消(営業積算)
break;
case '9': //案件復帰(営業積算)
break;
case '10': //テスト
break;
}
//プロセスの実行
console.log(`▶Process_${procNum} : ${procName} 処理終了`);
$p.execProcess($('#Process_' + procNum));
}
//プロセスボタン調整
$p.ex.processButtonControl = function () {
$("button[id^='Process']").each(function () {
//close アイコンのボタンは非表示
if ($(this).attr('data-icon') == 'ui-icon-close') {
$(this).hide();
}
//ui-icon-cancel アイコンのボタンはグレーアウト
if ($(this).attr('data-icon') == 'ui-icon-cancel') {
//グレーアウト
$(this).addClass('new-status-grey');
} else {
//その他のボタンはサイズ拡大
$(this).addClass('processButtonSize');
}
//個別設定
switch (this.id) {
case 'Process_1': //登録完了
$(this).addClass('new-status-yellow');
break;
case 'Process_2': //依頼終了
$(this).addClass('new-status-red');
break;
case 'Process_3': //保留
//$(this).addClass('new-status-orange');
break;
case 'Process_4': //取消
//$(this).addClass('new-status-purple');
break;
case 'Process_5': //依頼票登録
$(this).addClass('new-status-blue');
break;
case 'Process_6': //案件復帰
$(this).addClass('new-status-orange');
break;
case 'Process_7': //保留(営業積算)
//$(this).addClass('new-status-orange');
break;
case 'Process_8': //取消(営業積算)
//$(this).addClass('new-status-purple');
break;
case 'Process_9': //案件復帰(営業積算)
$(this).addClass('new-status-orange');
break;
}
});
}

View File

@ -0,0 +1,35 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 90.スタートメッセージ表示
@name :
@siteIds : 310406
@siteTitles : Re①基本情報
@disabled: false
*/
//スタートアップメッセージ表示
$p.ex.startupMessage = function () {
let count = 0;
for (message of messageData) {
//2つ目以降のメッセージの際にクリアフラグを0に設定。
let clearFlag = 0;//count > 0 ? 0 : 1;
$p.ex.setMyMessage(message.colorCode, message.message, clearFlag);
count++;
}
//開いたときにステータスごとに処理
switch ($('#Results_Status').val()) {
case '100': //新規登録
break;
case '200': //登録完了
break;
case '900': //依頼終了
break;
case '910': //保留
break;
case '920': //取消
break;
}
}

View File

@ -0,0 +1,69 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 99_更新履歴保存スクリプト
@name :
@siteIds : 310406
@siteTitles : Re①基本情報
@disabled: false
*/
//変更内容を保存
$p.ex.saveHistory = function () {
let history = '';
let count = 0;
//履歴に表示しない項目リスト
let excludeList = [
'Results_Timestamp',
'Results_ClassK',
'Results_ClassL',
'Results_ClassM',
'Results_ClassN',
'Results_Class191',
'Results_Class192',
'Results_Class193',
'Results_Class199',
'Results_Class200',
'Results_Description200'
];
if ($p.data.MainForm) {
$p.set($('#Results_Description200'), '');
history = '◆ 変更内容 ◆\n';
$.each($p.data.MainForm, function (index, val) {
if (index.startsWith('Results')) {
if (!excludeList.includes(index)) {
//項目名の取得
let colName = $('label[for="' + index + '"]').text();
let text;
//セレクトボックス判定
if ($('#' + index + '.control-dropdown').length) {
//セレクトボックス処理
if ($('#' + index).prop("multiple")) {
text = $('#' + index + '_ms span').eq(-1).text();
} else {
text = $('#' + index + ' option:selected').text();
}
} else if ($('#' + index + '.radio-value').length) {
//ラジオボタン処理
text = val != '' ? $('label[for="' + index + val + '"').text() : '';
} else {
//その他
text = val;
}
history += '▷ ' + colName + ' : ' + text + '\n';
count++;
}
}
});
if (count) {
//console.log(history);
$p.set($('#Results_Description200'), history);
$p.set($('#Comments'), history);
}
}
}

View File

@ -0,0 +1,37 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : メッセージ管理
@name :
@siteIds : 326371
@siteTitles : メッセージ管理
@disabled: false
*/
let pageLoading = 0; //ページロード中フラグ
//初期処理
window.addEventListener('load', function () {
if (pageLoading == 0) {
console.log('Window load Event');
$p.ex.onLoad();
}
});
$p.events.on_editor_load = function () {
if (pageLoading == 0) {
console.log('on Editor Load');
$p.ex.onLoad();
}
}
//----------------------------------------------------------------------
$p.ex.onLoad = function () {
//ロード開始
pageLoading = 1;
//初期処理
const colorCode = $('#Results_ClassC').val();
const message = $('#Results_ClassD').val();
$p.ex.setMyMessage(colorCode, message);
}

View File

@ -0,0 +1,60 @@
/*
@config :next999.json
@filename : ${psFileBasename}
@title :01_メッセージデータ取得
@name :01_メッセージデータ取得
@siteIds : 310406
@siteTitles : Re①基本情報
@disabled: false
*/
try {
//メッセージデータ取得
getMessageData();
} catch (error) {
context.Log(error);
}
//メッセージデータ取得
function getMessageData() {
//メッセージデータを取得
let data = {
"View": {
"ColumnFilterHash": {
"ClassA": "[\"" + model.SiteId + "\"]",
"ClassB": model.Status
},
"ColumnSorterHash": {
"ClassA": "asc",
"ClassB": "asc",
"NumA": "asc"
}
}
}
let results = items.Get(326371, JSON.stringify(data));
if (results.length === 0) {
context.Log('メッセージデータが見つかりませんでした。');
return;
}
let messageData = []
for (let item of results) {
const status = item.ClassB;
const colorCode = item.ClassC;
const message = item.ClassD;
messageData.push({
"status": status,
"colorCode": colorCode,
"message": message,
});
}
//取得したメッセージデータをhiddenに格納
if (messageData.length > 0) {
hidden.Add('messageData', JSON.stringify(messageData));
} else {
context.Log('メッセージデータが見つかりませんでした。');
}
}

View File

@ -0,0 +1,134 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 01_読み取り専用スタイル
@name :
@siteIds : 310406
@siteTitles : Re基本情報
@disabled: false
*/
label.error {
pointer-events: none;
z-index: 100;
border-top: none !important;
}
.code-readonly {
pointer-events: none;
background-color: lightgrey;
font-weight: bold;
}
.code-readonly2,
.code-readonly2+button,
.code-readonly2+div.ui-icon,
.code-readonly3,
.code-readonly3+button,
.code-readonly3+div.ui-icon {
font-weight: bold;
&:active {
pointer-events: none;
}
a:not(.ui-spinner-button) {
pointer-events: auto;
}
}
.code-readonly2 select,
.code-readonly2 input,
.code-readonly2 button.ui-multiselect,
.code-readonly2 .control-markup,
.code-readonly2 .ui-spinner,
span[data-readonly="1"] {
pointer-events: none;
border: dashed 1px black;
background-color: lightgray !important;
color: black !important;
.ui-spinner-input {
border: none;
}
}
.code-readonly3 select,
.code-readonly3 input,
.code-readonly3 button.ui-multiselect,
.code-readonly3 .control-markup,
.code-readonly3 .ui-spinner {
pointer-events: none;
border: dashed 1px black;
.ui-spinner-input {
border: none;
}
}
.code-readonly2,
.code-readonly3,
.field-normal:has(span[data-readonly="1"]),
.field-wide:has(span[data-readonly="1"]) {
position: relative;
&:hover::after {
content: "読取り専用です";
position: absolute;
left: 120px;
top: calc(100% - 9px);
margin-top: 4px;
background: #00000080;
color: #fff;
padding: 4px 10px;
border-radius: 4px;
font-size: 12px;
font-weight: normal !important;
pointer-events: none;
z-index: 9999;
white-space: nowrap;
}
}
.code-required,
select[data-validate-required="1"],
input[data-validate-required="1"] {
border: double 3px red !important;
&+button.ui-multiselect {
border: double 3px red !important;
}
}
.field-normal:has(.code-required),
.field-wide:has(.code-required),
.field-normal:has(select[data-validate-required="1"]),
.field-wide:has(select[data-validate-required="1"]),
.field-normal:has(input[data-validate-required="1"]),
.field-wide:has(input[data-validate-required="1"]) {
position: relative;
&:hover::after {
content: "入力必須です";
position: absolute;
left: 120px;
top: calc(100% - 9px);
margin-top: 4px;
background: #ff000080;
color: #fff;
padding: 4px 10px;
border-radius: 4px;
font-size: 12px;
font-weight: normal !important;
pointer-events: none;
z-index: 9999;
white-space: nowrap;
}
}
.error {
border: double 3px red !important;
}

View File

@ -0,0 +1,30 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 02_共通スタイル
@name :
@siteIds : 310406
@siteTitles : Re基本情報
@disabled: false
*/
/*見出しサイズ*/
.field-section {
font-size: 1.5em !important;
font-weight: bold !important;
height: auto;
}
/*項目の後ろの行間を少し狭める*/
.field-normal {
height: 35px;
}
.field-wide {
min-height: 35px;
padding: 0 10px 5px 0;
}
/*コメントのある項目の高さだけ少し広げる*/
div:has(.commentAdd).field-normal {
height: 50px;
}

View File

@ -0,0 +1,51 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 03_プロセスボタンの変更
@name :
@siteIds : 310406
@siteTitles : Re基本情報
@disabled: false
*/
.processButtonSize {
font-size: 1.2em !important;
font-weight: bold !important;
}
/*
#Process_1,
#Process_2,
#Process_5 {
font-size: 1.5em;
font-weight: bold;
}
#Process_1 {
background: yellow;
color: black;
}
#Process_2 {
background: red;
color: white;
}
#Process_3,
#Process_4,
#Process_6 {
background: grey;
color: black;
}
#Process_5 {
background: blue;
color: white;
}
#UpdateCommand {
background: lightgreen;
color: black !important;
}
*/

View File

@ -0,0 +1,15 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 04_特定項目のサイズ変更
@name :
@siteIds : 310406
@siteTitles : Re基本情報
@disabled: false
*/
#Results_ClassA,
label[for="Results_ClassA"] {
font-size: 1.5em !important;
font-weight: bold !important;
height: 2.2em !important;
}

View File

@ -0,0 +1,4 @@
{
"apiKey": "c38903157cbffc30961f50bc29d0991a6cd8af495ab3009b05c5f98e82b2e61b94ba2d5c0a48fc518b1cd74c9e427b01051a228f670f3c5282544dfbec93db87",
"url": "https://neo999.next-hd.net/pleasanter/"
}

View File

@ -0,0 +1,686 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 01_基本スクリプト
@name :
@siteIds : 310407
@siteTitles : Re②依頼票
@disabled: false
*/
let pageLoading = 0;
let apiKey = '6504c8a807677a3a576e10327f3c19876c55736ee45d4a845796b9e7f5e087bfd4bd0d8184863da8cf1733ca635111432ab334aea59102b06a96ee6d2c05190d';
//依頼上限表示
let countLimit = [10, 3, 3, 10, 5, 5, 5, 10, 5, 5, 3];
let userList = JSON.parse($('#userList').val() || '[]'); //全従業員のユーザーデータ
let sekisanMemberList = JSON.parse($('#sekisanMemberList').val() || '[]');
let sekisanDeptList = JSON.parse($('#sekisanDeptList').val() || '[]');
//メッセージデータ
let messageData = JSON.parse($('#messageData').val() || '[]');
//----------------------------------------------------------------------
//初期処理
window.addEventListener('load', function () {
if (pageLoading == 0) {
console.log('Window load Event');
$p.ex.onLoad();
}
});
$p.events.on_editor_load = function () {
if (pageLoading == 0) {
console.log('on Editor Load');
$p.ex.onLoad();
}
}
//----------------------------------------------------------------------
$p.ex.onLoad = function () {
//ロード開始
pageLoading = 1;
//初期処理
$p.ex.init();
}
//初期処理
$p.ex.init = function () {
console.log('initialize...');
//依頼項目登録処理の場合は何もしない
if ($('#Results_Class198').val() == '1') return;
//一時保存ボタン処理1
$('#UpdateCommand').empty();
$('#UpdateCommand').html(`一時保存`);
$('#UpdateCommand').addClass('new-status-light-lime');
//コメント追加
$('label[for="SectionFields5"]').append('<span class="commentAdd2">※1つの依頼票で登録できる依頼項目の上限は10個までです</span>');
//ブランドの横ににコメントを追加
let commentDiv = document.createElement('div');
commentDiv.className = 'brandComment';
let commentBody = document.createElement('pre');
commentBody.innerText =
`複数ブランド提案の場合はここでブランド変更し依頼をしてください。
金額の取り違えには気を付けてください`;
commentDiv.appendChild(commentBody);
$('#Results_Class012Field').after(commentDiv);
//プロセスボタン調整
$p.ex.processButtonControl();
//依頼項目ラベル
$p.ex.createLabelText();
//新規作成時のみ処理
if ($p.action() == 'new') {
//直接新規作成したらエラー表示
if (!$('#Results_ClassX').val()) {
$p.ex.setMyMessage('new-status-red', '【Re①基本情報】から【依頼票の登録】ボタンを押して作成してください');
} else {
//祝日計算
$p.ex.getHolidayTable();
}
} else {
//スタートアップメッセージ表示
$p.ex.startupMessage();
}
//担当者一覧マージイベント
$('#Results_Class022,#Results_Class023,#Results_Class024,#Results_Class025,#Results_Class026,#Results_Class027,#Results_Class028').on('change', function () {
$p.ex.usersMarge1();
});
//CC一覧変更マージイベント
$('#Results_Class031,#Results_Class032,#Results_Class033,#Results_Class034').on('change', function () {
$p.ex.usersMarge2();
});
//事前相談を無しにしたら、事前相談者を消す
$p.on('change', 'CheckA', function () {
if ($('#Results_CheckA').prop('checked')) {
$p.set($('#Results_ClassJ'), 1);//事前相談あり
} else {
$p.set($('#Results_ClassJ'), 0);//事前相談なし
$p.set($('#Results_ClassK'), '');
}
});
//アップ希望日
$p.on('change', 'DateI', function () {
$p.clearMessage();
$p.ex.upDateCheck();
});
//Re③依頼項目ボタンは非表示
$('button[data-from-site-id="' + $p.siteId() + '"]:contains("Re③依頼項目")').hide();
//現在の進捗の値によって項目を表示を切り替える
$p.ex.changeColor($('#Results_ClassO').val());
$('input[name="Results_ClassO"]').on('change', function () {
$p.ex.changeColor($(this).val());
if ($(this).val() == '0') {
$p.set($('#Results_ClassP'), ''); //現場の進捗状況
$p.set($('#Results_ClassQ'), ''); //必要な見積金額
$p.set($('#Results_DescriptionO'), ''); //問合せ経緯
}
});
//読取り専用
$('.code-readonly2 input').prop('tabindex', '-1');
$('.code-readonly2 select').prop('tabindex', '-1');
//UP希望日
$p.ex.upDateCheck();
//「依頼履歴」テーブルの読み込み完了後にボタン生成
waitForElement('table[data-id="310405"]', function () {
console.log('依頼履歴テーブルが読み込まれました。');
$p.ex.createReportButton();
});
//セレクトボックスにプレースホルダーを追加
addPlaceholderOption('Results_ClassK');
}
//入力チェック前処理
$p.events.before_validate_Create = function (args) {
if (!$('#Results_ClassX').val()) {
$p.ex.setMyMessage('new-status-red', '【Re①基本情報】から【依頼票の登録】ボタンを押して作成してください');
return false;
}
}
//入力チェック後処理
$p.events.after_validate = function (args) {
if (!$('#Results_ClassT').val().length) {
$p.ex.setMyMessage('new-status-red', '通知先が入力されていません');
focusOnColumn('ClassT', 'General');
return false;
}
//入力チェックエラーがある場合は処理を中止
if ($('#Results_DateI').val()) {
if (!$p.ex.upDateCheck()) {
return false;
}
} else {
$p.ex.setMyMessage('new-status-red', 'アップ希望日を期限日より後ろに設定してください');
focusOnColumn('ClassB', 'General');
return false;
}
if ($('#Results_ClassJ').val() == 1 && $('#Results_ClassK').val() == '') {
$p.ex.setMyMessage('new-status-red', '営業積算課事前相談済みの場合、【事前相談者】を選択してください');
focusOnColumn('ClassK', 'General');
return false;
}
//承認図後・着工中 の場合
if ($('#Results_ClassO').val() == 1) {
if ($('#Results_ClassP').val() == '') {
$p.ex.setMyMessage('new-status-red', '【承認図後・着工中】物件の場合、【現在の進捗状況】を選択してください');
focusOnColumn('ClassP', 'General');
return false;
}
if ($('#Results_ClassQ').val() == '') {
$p.ex.setMyMessage('new-status-red', '【承認図後・着工中】物件の場合、【必要な見積金額】を選択してください');
focusOnColumn('ClassQ', 'General');
return false;
}
if ($('#Results_DescriptionO').val() == '') {
$p.ex.setMyMessage('new-status-red', '【承認図後・着工中】物件の場合、【問合せ経緯】を入力してください');
focusOnColumn('DescriptionO', 'General');
return false;
}
}
//エリア-ブランド結合
$p.ex.areaBrandName();
//担当者一覧マージ
$p.ex.usersMarge1();
//CC一覧マージ
$p.ex.usersMarge2();
//変更履歴の保存
$p.ex.saveHistory();
//事前相談無しの場合、事前相談者を消す
if ($('#Results_ClassJ').val() == '0') {
$p.set($('#Results_ClassK'), '');
}
}
//親から子を作成した際に親への遷移を回避するスクリプト
$p.events.after_set_Create = function (args) {
//baseUrlを使ってitemsのidを含めたURLを取得
itemsUrl = function (id) {
return $('#ApplicationPath').val() + 'items/' + id;
}
let response = args.json.filter(function (item, index) {
if (item.Method == 'Response') return true;
});
//子テーブルに留まる
location.href = itemsUrl(response[0].Value);
//初期処理
$p.ex.init();
}
$p.events.after_set_Update = function (args) {
//初期処理
$p.ex.init();
//一時保存ボタン処理2
$('#UpdateCommand').empty();
$('#UpdateCommand').html(`<span class="ui-button-icon ui-icon ui-icon-disk"></span>
<span class="ui-button-icon-space"> </span>
一時保存`);
//一時保存メッセージ
let json8val = JSON.parse(args.json[8].Value);
if (json8val.Id == 'Updated') {
$p.ex.setMyMessage('new-status-light-lime', '依頼票の内容が一時保存されました');
}
//依頼項目登録ボタンが押されたら
if ($('#Results_Class198').val() == '1') {
$p.clearMessage();
// ウインドウ全体にモーダルを表示
if ($('#global-modal').length === 0) {
const modalHtml = `
<div id="global-modal" style="
position: fixed;
z-index: 9999;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.5);
display: flex;
align-items: center;
justify-content: center;
">
<div style="
background: #fff;
padding: 40px 60px;
border-radius: 8px;
font-size: 1.2em;
box-shadow: 0 2px 16px rgba(0,0,0,0.2);
text-align: center;
">
処理中ですしばらくお待ちください...
</div>
</div>
`;
$('body').append(modalHtml);
}
$p.apiUpdate({
'id': $p.id(),
'data': {
'ApiVersion': 1.1,
'ClassHash': {
'Class198': '0'
}
},
'done': function (data) {
//フラグを0に戻してから依頼票ボタンを押す
$('button[data-from-site-id="' + $p.siteId() + '"]:contains("Re③依頼項目")').click();
},
'fail': function (data) {
console.log(data);
}
});
}
}
//エリアとブランド名を合体させて格納する
$p.ex.areaBrandName = function () {
let area = $('#Results_Class011 option:selected').text();
let brand = $('#Results_Class012 option:selected').text();
if (area && brand) {
$p.set($('#Results_ClassL'), area + ' ' + brand);
}
}
//担当者一覧マージ
$p.ex.usersMarge1 = function () {
let users = [];
$('#Results_ClassE').val() && users.push($('#Results_ClassE').val()); //依頼者
$('#Results_Class022').val() && users.push($('#Results_Class022').val()); //主担当営業 Class022
$('#Results_Class023').val() && users.push($('#Results_Class023').val()); //副担当営業 Class023
$('#Results_Class024').val() && users.push($('#Results_Class024').val()); //営業設計 Class024
$('#Results_Class025').val() && users.push($('#Results_Class025').val()); //担当監督 Class025
$('#Results_Class026').val() && users.push($('#Results_Class026').val()); //担当IC Class026
$('#Results_Class027').val() && users.push($('#Results_Class027').val()); //管理設計 Class027
$('#Results_Class028').val() && users.push($('#Results_Class028').val()); //所属長 Class028
$p.set($('#Results_Class191'), JSON.stringify(users));
$p.ex.usersMarge3();
}
//CC一覧マージ
$p.ex.usersMarge2 = function () {
let users = [];
$('#Results_Class031').val() && users.push($('#Results_Class031').val()); //CC1
$('#Results_Class032').val() && users.push($('#Results_Class032').val()); //CC2
$('#Results_Class033').val() && users.push($('#Results_Class033').val()); //CC3
$('#Results_Class034').val() && users.push($('#Results_Class034').val()); //CC4
$p.set($('#Results_Class192'), JSON.stringify(users));
$p.ex.usersMarge3();
}
//担当者・CC一覧マージ
$p.ex.usersMarge3 = function () {
//担当者一覧とCC一覧をマージして保管
let mergeAry = [...$('#Results_Class191').val(), ...$('#Results_Class192').val()];
mergeAry.push($('#Results_ClassE').val());
$p.set($('#Results_Class193'), JSON.stringify(mergeAry));
}
$p.ex.upDateCheck = function () {
if ($('#Results_DateI').val() != '') {
let dateI = new Date($('#Results_DateI').val());
let dateJ = new Date($('#Results_DateJ').val());
//アップ希望日が期限日より手前の場合
if (dateI.getTime() < dateJ.getTime()) {
$('#Results_DateI').addClass('dateI_alert');
$p.ex.setMyMessage('new-status-red', 'アップ希望日は期限日より後ろに設定してください');
focusOnColumn('ClassB', 'General');
return false;
} else {
$('#Results_DateI').removeClass('dateI_alert');
return true;
}
}
}
//祝日判定テーブルの取得
$p.ex.getHolidayTable = function () {
let holidays = [];
let today = new Date();
let startDate = new Date();
let endDate = new Date();
//30日前の日付を計算
startDate.setDate(today.getDate() - 30);
//60日後の日付を計算
endDate.setDate(today.getDate() + 60);
//範囲指定
let startDateStr = startDate.getFullYear() + '/' +
(startDate.getMonth() + 1).toString().padStart(2, '0') + '/' +
startDate.getDate().toString().padStart(2, '0') + ' 00:00:00';
let endDateStr = endDate.getFullYear() + '/' +
(endDate.getMonth() + 1).toString().padStart(2, '0') + '/' +
endDate.getDate().toString().padStart(2, '0') + ' 23:59:59';
let filterDate = '["' + startDateStr + ',' + endDateStr + '"]';
//祝日テーブルからデータを取得
$p.apiGet({
'id': 192267,
'data': {
'ApiVersion': 1.1,
'ApiKey': apiKey,
'View': {
'ColumnFilterHash': {
'DateA': filterDate,
},
'ColumnSorterHash': {
'DateA': "asc",
}
}
},
'done': function (data) {
console.log(data);
$.each(data.Response.Data, function (index, value) {
let dateA = new Date(value.DateHash.DateA);
let holiday = dateA.getFullYear() + '/' + (dateA.getMonth() + 1).toString().padStart(2, '0') + '/' + dateA.getDate();
holidays.push(holiday);
});
let limitDate = new Date();
limitDate.setHours(0);
limitDate.setMinutes(0);
limitDate.setSeconds(0);
//土日祝日を除く5日後をカウント
let count = 0;
while (count < 5) {
limitDate.setDate(limitDate.getDate() + 1);
let limitDateStr = limitDate.getFullYear() + '/' + (limitDate.getMonth() + 1).toString().padStart(2, '0') + '/' + limitDate.getDate().toString().padStart(2, '0');
if (!(limitDate.getDay() == 0) && !(limitDate.getDay() == 6) && !(holidays.includes(limitDateStr))) {
count++;
}
}
//let limitDateStr = limitDate.getFullYear() + "年" + (limitDate.getMonth() + 1) + "月" + limitDate.getDate() + "日以降";
let limitDateStr = limitDate.getFullYear() + '/' + (limitDate.getMonth() + 1).toString().padStart(2, '0') + '/' + limitDate.getDate().toString().padStart(2, '0');
$p.set($('#Results_DateJ'), limitDateStr);
}
});
}
//進捗、見積、経緯の欄のクラス変更
$p.ex.changeColor = function (flag) {
if (flag == 1) {
$('label[for="Results_ClassO1').addClass('fontColor_Red');
$('#Results_ClassPField').removeClass('display_none');
$('#Results_ClassQField').removeClass('display_none');
$('#Results_DescriptionOField').removeClass('display_none');
$('#Results_ClassPField').addClass('bgColor_Pink');
$('#Results_ClassQField').addClass('bgColor_Pink');
$('#Results_DescriptionOField').addClass('bgColor_Pink');
} else {
$('label[for="Results_ClassO1').removeClass('fontColor_Red');
$('#Results_ClassPField').addClass('display_none');
$('#Results_ClassQField').addClass('display_none');
$('#Results_DescriptionOField').addClass('display_none');
$('#Results_ClassPField').removeClass('bgColor_Pink');
$('#Results_ClassQField').removeClass('bgColor_Pink');
$('#Results_DescriptionOField').removeClass('bgColor_Pink');
}
}
//要素が読み込まれるまで待機し、返す
function waitForElement(selector, callback, interval = 100, timeout = 5000) {
const startTime = Date.now();
const checkExist = setInterval(function () {
if ($(selector).length) {
clearInterval(checkExist); //要素が見つかったら停止
callback();
} else if (Date.now() - startTime > timeout) {
clearInterval(checkExist); //タイムアウト処理
console.warn(`指定した要素 '${selector}' が ${timeout / 1000} 秒以内に見つかりませんでした。`);
}
}, interval);
}
/*
[
{
"TableName": "Users",
"View": {
"ColumnFilterExpressions": {
"UserId": "[Class193]",
}
}
}
]
[
{
"SiteId": "333888",
"View": {
"ColumnSorterHash": {
"ClassA": "asc"
}
},
"Lookups": [
{//管理番号
"From": "ClassA",
"To": "ClassA",
"Type": 0,
"OverwriteForm": true
}, {//マスターシート
"From": "ClassY",
"To": "ClassY",
"Type": 0,
"OverwriteForm": true
}, {//契約コード
"From": "ClassZ",
"To": "ClassZ",
"Type": 0,
"OverwriteForm": true
}, {//施主名
"From": "ClassK",
"To": "Class001",
"Type": 0,
"OverwriteForm": true
}, {//建上地
"From": "Class010",
"To": "Class010",
"Type": 0,
"OverwriteForm": true
}, {//エリア
"From": "Class011",
"To": "Class011",
"Type": 0,
"OverwriteForm": true
}, {//契約ブランド
"From": "Class012",
"To": "Class012",
"Type": 0,
"OverwriteForm": true
}, {//防火指定
"From": "Class013",
"To": "Class013",
"Type": 0,
"OverwriteForm": true
}, {//建物種類
"From": "Class014",
"To": "Class014",
"Type": 0,
"OverwriteForm": true
}, {//承認図予定日
"From": "Date001",
"To": "Date001",
"Type": 0,
"OverwriteForm": true
}, {//着工予定日
"From": "Date002",
"To": "Date002",
"Type": 0,
"OverwriteForm": true
}, {//契約営業所
"From": "Class021",
"To": "Class021",
"Type": 0,
"OverwriteForm": true
}, {//主担当営業
"From": "Class022",
"To": "Class022",
"Type": 0,
"OverwriteForm": true
}, {//副担当営業
"From": "Class023",
"To": "Class023",
"Type": 0,
"OverwriteForm": true
}, {//営業設計
"From": "Class024",
"To": "Class024",
"Type": 0,
"OverwriteForm": true
}, {//担当監督
"From": "Class025",
"To": "Class025",
"Type": 0,
"OverwriteForm": true
}, {//担当IC
"From": "Class026",
"To": "Class026",
"Type": 0,
"OverwriteForm": true
}, {//管理設計
"From": "Class027",
"To": "Class027",
"Type": 0,
"OverwriteForm": true
}, {//所属長
"From": "Class028",
"To": "Class028",
"Type": 0,
"OverwriteForm": true
}, {//CC1
"From": "Class031",
"To": "Class031",
"Type": 0,
"OverwriteForm": true
}, {//CC2
"From": "Class032",
"To": "Class032",
"Type": 0,
"OverwriteForm": true
}, {//CC3
"From": "Class033",
"To": "Class033",
"Type": 0,
"OverwriteForm": true
}, {//CC4
"From": "Class034",
"To": "Class034",
"Type": 0,
"OverwriteForm": true
}, {//その他の宛先
"From": "ClassL",
"To": "ClassL",
"Type": 0,
"OverwriteForm": true
}, {//エリアブランド
"From": "Description001",
"To": "Description001",
"Type": 0,
"OverwriteForm": true
}, {//エリア記号
"From": "ClassM",
"To": "ClassM",
"Type": 0,
"OverwriteForm": true
}, {//ブランド記号
"From": "ClassN",
"To": "ClassN",
"Type": 0,
"OverwriteForm": true
}, {//担当者一覧
"From": "Class191",
"To": "Class191",
"Type": 0,
"OverwriteForm": true
}, {//CC一覧
"From": "Class192",
"To": "Class192",
"Type": 0,
"OverwriteForm": true
}, {//担当者・CC一覧
"From": "Class193",
"To": "Class193",
"Type": 0,
"OverwriteForm": true
}
]
}
]
*/
/**
* 指定したIDの<select>タグにプレースホルダー的な<option>を挿入する関数
* @param {string} selectId - <select>タグのID
*/
function addPlaceholderOption(selectId) {
//値が空の場合、プレースホルダー的なoptionを追加
const val = $(`#${selectId}`).val();
if (!val) {
//つ目のoptionのテキストを変更
$(`#${selectId} option:first`).text('次から選択してください');
}
//console.log($(`#${selectId}`));
}
function focusOnColumn(columnName, fieldSet = 'General') {
$(`a[href="#FieldSet${fieldSet}"]`).click();
$("html, body").animate({ scrollTop: $(`#Results_${columnName}Field`).offset().top }, 100);
}

View File

@ -0,0 +1,89 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 02_プロセス処理
@name :
@siteIds : 310407
@siteTitles : Re②依頼票
@disabled: false
*/
//プロセスごとに実行スクリプト
$p.ex.processScript = function (procNum) {
//プロセス共通処理 ------------------------------------------------------------------
//確認メッセージの取得
let confirmMessage = $('#Process_' + procNum).attr('data-confirm');
//実行確認
if (!confirm(confirmMessage)) {
//キャンセルなら終了
console.log('Process_' + procNum + ' はキャンセルされました');
return false;
} else {
//オリジナルの確認メッセージの削除
$('#Process_' + procNum).removeAttr('data-confirm');
}
//プロセス名の取得
let procName = $('#Process_' + procNum).text().replace(/^\s+/, '');
console.log(`▷Process_${procNum} : ${procName} 処理開始`);
//--------------------------------------------------------------------------------
//プロセスごとの個別処理
switch (procNum) {
case '1': //登録完了
break;
case '2': //積算依頼
break;
case '3': //積算受付
break;
case '4': //保留
break;
case '5': //取消
break;
case '6': //保留(営業積算)
break;
case '7': //取消(営業積算)
break;
}
//プロセスの実行
console.log(`▶Process_${procNum} : ${procName} 処理終了`);
$p.execProcess($('#Process_' + procNum));
}
//プロセスボタン調整
$p.ex.processButtonControl = function () {
$("button[id^='Process']").each(function () {
//hideで始まるボタンの非表示
if ($(this).attr('data-icon') == 'ui-icon-close') {
$(this).hide();
}
//hideで始まるボタンの非表示
if ($(this).attr('data-icon') == 'ui-icon-cancel') {
//グレーアウト
$(this).addClass('new-status-grey');
} else {
//ボタンサイズ拡大
$(this).addClass('processButtonSize');
}
//個別設定
switch (this.id) {
case 'Process_1':
$(this).addClass('new-status-yellow');
break;
}
});
}

View File

@ -0,0 +1,436 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 03_依頼項目タブ
@name :
@siteIds : 310407
@siteTitles : Re②依頼票
@disabled: false
*/
//依頼項目数ラベル追加
$p.ex.createLabelText = function () {
//依頼パターンにコメントを追加
let commentDiv = document.createElement('div');
commentDiv.className = 'patternComment';
const patternTableHtml = `<table border="1" class="patternTable">
<thead>
<tr>
<th>依頼パターン</th>
<th>備考</th>
<th>上限<br>件数</th>
</tr>
</thead>
<tbody>
<tr>
<td>1.基本</td>
<td>29に当てはまらない場合</td>
<td>10</td>
</tr>
<tr>
<td>2.工法</td>
<td>SE工法など</td>
<td>3</td>
</tr>
<tr>
<td>3.基礎</td>
<td>スラブ下げなど</td>
<td>3</td>
</tr>
<tr>
<td>4.床材</td>
<td>フローリングフロアタイルCFシートなど</td>
<td>10</td>
</tr>
<tr>
<td>5.断熱材バルコニー</td>
<td>断熱材は遮界壁など含む</td>
<td>5</td>
</tr>
<tr>
<td>6.外壁軒天タイル</td>
<td>タイルは室内外の壁床いずれも含む</td>
<td>5</td>
</tr>
<tr>
<td>7.内部建材</td>
<td>階段建具造作材点検など</td>
<td>10</td>
</tr>
<tr>
<td>8.マトリックス</td>
<td></td>
<td>5</td>
</tr>
<tr>
<td>9.造作家具造作建具造作洗</td>
<td>ミラー(姿)造作ガラス(造作窓)など含む</td>
<td>5</td>
</tr>
</tbody>
</table>`;
commentDiv.innerHTML = patternTableHtml;
$('#SectionFields5Container').append(commentDiv);
//「件」表示
let countNumStr1 = document.createElement('span');
countNumStr1.innerText = '件';
countNumStr1.classList = 'koumokuStr';
$('.numArea .container-normal').append(countNumStr1);
//「件」表示
let countNumStr2 = document.createElement('span');
countNumStr2.innerText = '件';
countNumStr2.classList = 'koumokuStr';
$('.numArea2 .container-normal').append(countNumStr2);
//「項目数」表示
let koumokuStr1 = document.createElement('span');
koumokuStr1.innerText = '項目数';
koumokuStr1.classList = 'koumokuStr';
$('.numArea .container-normal').prepend(koumokuStr1);
//「項目数」表示
let koumokuStr2 = document.createElement('span');
koumokuStr2.innerText = '完了数';
koumokuStr2.classList = 'koumokuStr';
$('.numArea2 .container-normal').prepend(koumokuStr2);
}
//依頼項目追加ボタン
$p.ex.createIraiButton = function () {
//各項目の依頼リミット数
let allCount = $('#Results_Num051').val(); //合計項目数
const arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'];
//依頼項目追加ボタン
for (i = 0; i < 9; i++) {
let j = (i + 1).toString().padStart(3, '0');
let k = i + 21;
let limit = countLimit[i];
let countData = $('#Results_Num' + j).val();
let div1 = document.createElement('div');
let button1 = document.createElement('button');
button1.type = 'button';
button1.id = 'addButton0' + k;
button1.innerHTML = '依頼項目追加';
button1.setAttribute('onclick', '$p.ex.selectIraiPattern("' + arr[i] + '")'); //ボタンを押したときの処理
button1.classList = 'koumokuAddButton';
div1.append(button1);
$('#Results_Num0' + k + 'Field').after(div1);
//全依頼数が10個以上の場合はボタン不可
if (allCount >= 10) {
$('#addButton0' + k).button({
icon: 'ui-icon-closethick',
disabled: true
});
} else {
if (countData < limit) {
$('#addButton0' + k).button({
icon: 'ui-icon-radio-on',
});
} else {
//各項目ごとの依頼数
$('#addButton0' + k).button({
icon: 'ui-icon-closethick',
disabled: true
});
}
}
}
}
$p.ex.changeIraiCountColor = function () {
//各項目の依頼リミット数
let allCount = $('#Results_Num051').val(); //合計項目数
let clearCount = $('#Results_Num052').val(); //完了合計数
//合計数が1以上かつ完了数がそれ以下の場合
if (allCount > 0) {
if (allCount > clearCount) {
$('#Results_Num051').addClass('iraiAri');
//完了している場合
} else {
$('#Results_Num051').addClass('iraiComplete');
$('#Results_Num052').addClass('iraiComplete');
}
}
for (i = 1; i <= 9; i++) {
let countStr = i.toString().padStart(3, '0');
let clearStr = (i + 20).toString().padStart(3, '0');
let iraiCount = parseFloat($('#Results_Num' + countStr).val());
let clearCount = parseFloat($('#Results_Num' + clearStr).val());
if (iraiCount > 0) {
if (iraiCount > clearCount) {
$('#Results_Num' + countStr).addClass('iraiAri');
} else {
$('#Results_Num' + countStr).addClass('iraiComplete');
$('#Results_Num' + clearStr).addClass('iraiComplete');
}
}
}
}
//依頼パターン切り替え
$p.ex.selectIraiPattern = function (patternNum) {
//パターン保存
$p.set($('#Results_Class199'), patternNum);
//依頼項目登録フラグ
$p.set($('#Results_Class198'), '1');
//更新ボタン
$('#UpdateCommand').click();
}
$p.ex.createReportButton = function () {
//解析対象テーブル
const $table = $('table[data-id="310405"]');
if ($table.length === 0) return;
//ヘッダ行処理
const $thead = $table.find('thead');
if ($thead.length) {
const $headerRow = $thead.find('tr').first();
//先頭にth追加
const $th = $('<th style="text-align:center;"><input type="checkbox" name="no3_report_all"></th>');
$headerRow.prepend($th);
//ヘッダチェックボックス連動
$th.find('input[type="checkbox"]').on('change', function () {
const checked = $(this).prop('checked');
$table.find('tbody input[name="no3_report"]').prop('checked', checked);
});
}
//tbody行処理
$table.find('tbody tr').each(function () {
const $row = $(this);
const $firstTd = $row.find('td').first();
const value = $firstTd.text().trim();
//チェックボックス生成
const $cbTd = $('<td style="text-align:center; vertical-align:middle;"></td>');
const $cb = $('<input type="checkbox" name="no3_report">').val(value);
//tdクリックでチェックボックス連動
$cbTd.on('click', function (e) {
if (e.target === $cb[0]) return; //チェックボックス自身は除外
$cb.prop('checked', !$cb.prop('checked'));
});
$cbTd.append($cb);
$row.prepend($cbTd);
//行クリック時の画面遷移無効化
$row.on('click', function (e) {
//aタグと追加チェックボックス以外なら遷移無効
if ($(e.target).is('a') || $(e.target).is('input[name="no3_report"]')) return;
e.preventDefault();
e.stopPropagation();
});
//チェックボックスクリック時のイベントを無効化
$cb.on('click', function (e) {
e.stopPropagation();
});
});
//ヘッダセルクリックで全選択/解除
$table.find('thead th').first().on('click', function (e) {
if ($(e.target).is('input[type="checkbox"]')) return;
const $headerCb = $(this).find('input[type="checkbox"]');
$headerCb.prop('checked', !$headerCb.prop('checked')).trigger('change');
});
//帳票出力ボタンを追加
const $reportBtn = $('<button id="no3-report-btn" style="padding:5px !important; font-size:1.5em;">帳票出力</button>');
$reportBtn.button();
$table.after($('<div style="margin-top:5px; text-align:right;"></div>').append($reportBtn));
//帳票出力ボタンのクリックイベントに関数を紐付け
$('#no3-report-btn').on('click', function () {
//ここで取得した値を利用してレポート出力処理を実行
if (confirm('依頼項目の帳票を出力しますか?')) {
$p.ex.getCheckedReportValues();
}
});
const $reportMesssage = $('<div id="no3-report-message" style="color: red; font-weight: bold;"> ▲チェックした依頼項目がまとめて帳票に出力されます▼</div>');
$table.after($reportMesssage);
}
$p.ex.getCheckedReportValues = async function () {
//共通キー項目
const keys = [
'ResultId',
'SiteId',
'ItemTitle',
'Title',
'Body',
'Status',
'Manager',
'Owner',
'Locked',
'Comments',
'Creator',
'CreatedTime',
'Updator',
'UpdatedTime',
'Ver'
]
//チェックが入っているチェックボックスの値を取得
const checkedValues = [];
$('input[name="no3_report"]:checked').each(function () {
checkedValues.push($(this).val());
});
//取得した値をコンソールに表示(必要に応じて他の処理に利用)
//console.log('チェックされた値:', checkedValues);
let recordData = [];
for (let recordId of checkedValues) {
const record = await $p.ex.getRecordData(recordId);
let param = {}
if (!record) {
console.error('Record data not found for ID:', recordId);
continue;
}
//共通キー項目のデータをセット
for (let key of keys) {
param[key] = record[key];
}
//ClassHashの値をセット
Object.keys(record.ClassHash).forEach(function (key) {
param[key] = record.ClassHash[key];
});
//Numhashの値をセット
Object.keys(record.NumHash).forEach(function (key) {
param[key] = record.NumHash[key];
});
//DateHashの値をセット
Object.keys(record.DateHash).forEach(function (key) {
if (record.DateHash[key] != '1899-12-30T00:00:00') {
param[key] = dateFormatChange(record.DateHash[key]);
}
});
//DescriptionHashの値をセット
Object.keys(record.DescriptionHash).forEach(function (key) {
param[key] = record.DescriptionHash[key];
});
//CheckHashの値をセット
Object.keys(record.CheckHash).forEach(function (key) {
param[key] = record.CheckHash[key];
});
//日付変換
param.CreatedTime = dateFormatChange(param.CreatedTime);
param.UpdatedTime = dateFormatChange(param.UpdatedTime);
//UserList変換
param.Manager = checkUserList(param.Manager);
param.Owner = checkUserList(param.Owner);
param.Creator = checkUserList(param.Creator);
param.Updator = checkUserList(param.Updator);
//UserListの値をチェック
param.ClassE = checkUserList(param.ClassE);
param.ClassF = checkUserList(param.ClassF);
param.ClassK = checkUserList(param.ClassK);
param.ClassT = checkUserList(param.ClassT);
param.Class111 = checkUserList(param.Class111);
param.Class113 = checkUserList(param.Class113);
param.Class116 = checkUserList(param.Class116);
param.Class132 = checkUserList(param.Class132);
param.Class134 = checkUserList(param.Class134);
param.Class136 = checkUserList(param.Class136);
param.Class141 = checkUserList(param.Class141);
param.Class151 = checkUserList(param.Class151);
param.Class153 = checkUserList(param.Class153);
param.Class191 = checkUserList(param.Class191);
param.Class192 = checkUserList(param.Class192);
param.Class193 = checkUserList(param.Class193);
param.Class031 = checkUserList(param.Class031);
param.Class032 = checkUserList(param.Class032);
param.Class033 = checkUserList(param.Class033);
param.Class034 = checkUserList(param.Class034);
param.Class022 = checkUserList(param.Class022);
param.Class023 = checkUserList(param.Class023);
param.Class024 = checkUserList(param.Class024);
param.Class025 = checkUserList(param.Class025);
param.Class026 = checkUserList(param.Class026);
param.Class027 = checkUserList(param.Class027);
param.Class028 = checkUserList(param.Class028);
recordData.push(param);
}
//console.log('取得したレコードデータ:', recordData);
//return checkedValues; //必要に応じて値を返す
createReport('326335', recordData);
};
//ユーザーリストからユーザー名を返す
function checkUserList(value) {
try {
let users = JSON.parse(value);
let userNames = [];
for (let user of users) {
if (userList[user]) {
userNames.push(userList[user].name);
} else {
userNames.push(user); //ユーザーが見つからない場合はそのまま値を使用
}
}
return JSON.stringify(userNames); //値が文字列でない場合はそのまま返す
} catch (error) {
let userName = userList[value] ? userList[value].name : value; //ユーザーが見つからない場合はそのまま値を使用
return userName; //値が文字列でない場合はそのまま返す
}
}
//日付フォーマット変換関数
function dateFormatChange(dateStr) {
let dateObj = new Date(dateStr);
//時分秒が00:00:00の場合は日付のみを返す
if (dateObj.getHours() === 0 && dateObj.getMinutes() === 0 && dateObj.getSeconds() === 0) {
//YYYY/MM/DD形式で返す
return dateObj.toLocaleDateString('ja-JP'); //日本語のロケールで日付をフォーマット
} else {
//YYYY/MM/DD HH:mm:ss形式で返す
return dateObj.toLocaleString('ja-JP', { timeZone: 'Asia/Tokyo' }); //日本語のロケールで日付と時間をフォーマット
}
}

View File

@ -0,0 +1,70 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 90_スタートメッセージ表示
@name :
@siteIds : 310407
@siteTitles : Re②依頼票
@disabled: false
*/
//スタートアップメッセージ表示
$p.ex.startupMessage = function () {
let count = 0;
for (message of messageData) {
//2つ目以降のメッセージの際にクリアフラグを0に設定。
let clearFlag = 0;//count > 0 ? 0 : 1;
$p.ex.setMyMessage(message.colorCode, message.message, clearFlag);
count++;
}
//開いたときに表示するメッセージ一覧
switch ($('#Results_Status').val()) {
case '100': //新規登録
//Re③依頼項目タブ色変更
$('a[href="#FieldSetTab1"]').addClass('status-grey');
break;
case '200': //登録完了
//Re③依頼項目タブ色変更
$('a[href="#FieldSetTab1"]').addClass('status-yellow');
//依頼項目ボタン
$p.ex.createIraiButton();
break;
case '300': //積算依頼
//Re③依頼項目タブ色変更
$('a[href="#FieldSetTab1"]').addClass('status-orange');
break;
case '400': //積算受付
//Re③依頼項目タブ色変更
$('a[href="#FieldSetTab1"]').addClass('status-purple');
break;
case '500': //積算対応中
//Re③依頼項目タブ色変更
$('a[href="#FieldSetTab1"]').addClass('status-green');
break;
case '800': //一部完了
//Re③依頼項目タブ色変更
$('a[href="#FieldSetTab1"]').addClass('status-black');
break;
case '900': //完了
//Re③依頼項目タブ色変更
$('a[href="#FieldSetTab1"]').addClass('status-blue');
break;
case '910': //保留
//Re③依頼項目タブ色変更
$('a[href="#FieldSetTab1"]').addClass('status-grey');
break;
case '920': //取消
//Re③依頼項目タブ色変更
$('a[href="#FieldSetTab1"]').addClass('status-grey');
break;
}
}

View File

@ -0,0 +1,149 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 999_汎用帳票出力スクリプト
@name :
@siteIds : 310407
@siteTitles : Re②依頼票
@disabled: false
*/
//999_汎用帳票出力スクリプト
async function createReport(templateId, recordData = [], templateType = 'xlsx') {
//templateIdで帳票データを取得
const templateData = await $p.ex.getRecordData(templateId);
if (!templateData) {
console.error('Report data not found for ID:', templateId);
return;
} else if (templateData.AttachmentsHash.AttachmentsA.length === 0) {
console.error('No attachments found for template ID:', templateId);
return;
}
const templateName = templateData.ClassHash.ClassA;
const templateGuid = templateData.AttachmentsHash.AttachmentsA[0].Guid;
//Guidを使ってバイナリデータを取得
const templateFile = await $p.ex.getTemplateFile(templateGuid);
const templateBinary = await base64ToArrayBuffer(templateFile.Base64);
//XlsPopulate Workbookを作成
let workbook = await XlsxPopulate.fromDataAsync(templateBinary);
//paramシート取得
let param = workbook.sheet('param');
if (!param) {
console.error('paramシートが見つかりません');
return;
}
//レコードデータを取得
let col = 2;
for (let record of recordData) {
Object.keys(record).forEach(function (key) {
param = setValueToSheet(param, col, key, record[key]);
});
col++;
}
const blob = await workbook.outputAsync();
//return blob;
//年月日時分秒の文字列を生成
const now = new Date();
const dateStr = now.getFullYear() + ('0' + (now.getMonth() + 1)).slice(-2) + ('0' + now.getDate()).slice(-2) +
'_' + ('0' + now.getHours()).slice(-2) + ('0' + now.getMinutes()).slice(-2) + ('0' + now.getSeconds()).slice(-2);
if (templateType === 'xlsx') {
//Blobをダウンロード
saveAs(blob, templateName + '_' + dateStr + '.' + templateFile.Extension);
} else if (templateType === 'pdf') {
//PDF出力
//const pdfBlob = await workbook.outputAsync('application/pdf');
//saveAs(pdfBlob, templateName + '_' + dateStr + '.pdf');
}
}
//A列からキーを検索し、該当する行の指定した列に値をセットする関数
function setValueToSheet(sheet, col, key, value) {
//左端の列を下まで走査する
const lastRow = sheet.usedRange().endCell('down').rowNumber();
for (let row = 1; row <= lastRow; row++) {
const keyCell = sheet.cell(row, 1);
const keyValue = keyCell.value();
if (!keyValue) continue;
if (keyValue === key) {
sheet.cell(row, col).value(value);
break;
}
}
return sheet;
}
//base64エンコードされたバイナリデータをArrayBufferに変換
async function base64ToArrayBuffer(base64) {
const binaryString = atob(base64);
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
//プリザンターから1件のレコードデータを取得する関数
$p.ex.getRecordData = async function (id) {
//もしidが空鳴らんなら、空のオブジェクトを返す
if (!id) {
return {};
}
//プリザンターへゲット処理
const url = 'https://' + location.hostname + '/pleasanter/api/items/' + id + '/get'
const json = {
'ApiVersion': 1.1,
'ApiKey': apiKey,
}
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(json)
});
const resData = await res.json();
//console.log(resData);
return resData.Response.Data[0];
}
//プリザンターから1件の添付ファイルのbase64データを取得する関数
$p.ex.getTemplateFile = async function (guid) {
//もしidが空鳴らんなら、空のオブジェクトを返す
if (!guid) {
return {};
}
//プリザンターへゲット処理
const url = 'https://' + location.hostname + '/pleasanter/api/binaries/' + guid + '/get'
const json = {
'ApiVersion': 1.1,
'ApiKey': apiKey,
}
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(json)
});
const resData = await res.json();
//console.log(resData);
return resData.Response;
}

View File

@ -0,0 +1,70 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 99_更新履歴保存スクリプト
@name :
@siteIds : 310407
@siteTitles : Re②依頼票
@disabled: false
*/
//変更内容を保存
$p.ex.saveHistory = function () {
let history = '';
let count = 0;
//履歴に表示しない項目リスト
let excludeList = [
'Results_Timestamp',
'Results_ClassL',
'Results_ClassM',
'Results_ClassN',
'Results_Class191',
'Results_Class192',
'Results_Class193',
'Results_Class198',
'Results_Class199',
'Results_Class200',
'Results_NumZ',
'Results_Description200'
];
if ($p.data.MainForm) {
$p.set($('#Results_Description200'), '');
history = '◆ 変更内容 ◆\n';
$.each($p.data.MainForm, function (index, val) {
if (index.startsWith('Results')) {
if (!excludeList.includes(index)) {
//項目名の取得
let colName = $('label[for="' + index + '"]').text();
let text;
//セレクトボックス判定
if ($('#' + index + '.control-dropdown').length) {
//セレクトボックス処理
if ($('#' + index).prop("multiple")) {
text = $('#' + index + '_ms span').eq(-1).text();
} else {
text = $('#' + index + ' option:selected').text();
}
} else if ($('#' + index + '.radio-value').length) {
//ラジオボタン処理
text = val != '' ? $('label[for="' + index + val + '"').text() : '';
} else {
//その他
text = val;
}
history += '▷ ' + colName + ' : ' + text + '\n';
count++;
}
}
});
if (count) {
//console.log(history);
$p.set($('#Results_Description200'), history);
$p.set($('#Comments'), history);
}
}
}

View File

@ -0,0 +1,160 @@
/*
@config :next999.json
@filename : ${psFileBasename}
@title :01.原価閲覧メンバー照会
@name :01.原価閲覧メンバー照会
@siteIds : 310407
@siteTitles : Re②依頼票
@disabled: false
*/
//原価閲覧メンバーを紹介し、リストを返すサーバースクリプト
try {
//【営業積算】原価閲覧グループ 63 のメンバーを取得
getSekisanMenberList();
//全従業員グループ 27 のメンバーを取得
getUserList();
//マスターシートからデータを取得し、一部を格納する
getMSSdata();
//メッセージデータを取得
getMessageData();
} catch (error) {
context.Log(error);
}
function getMSSdata() {
try {
let mssDataId = model.ClassY;
if (!mssDataId) {
context.Log('マスターシートのデータIDが設定されていません。');
return;
} else {
context.Log(`マスターシートのデータID: ${mssDataId}`);
let records = items.Get(mssDataId);
hidden.Add('mssData_Brand', records[0].Class033);
hidden.Add('mssData_Series', records[0].Class035);
}
} catch (error) {
context.Log(error);
}
}
function getSekisanMenberList() {
try {
//【営業積算】原価閲覧グループ 63 のメンバーを取得
let group = groups.Get(63);
let memberIds = []
let deptIds = []
for (let member of group.GetMembers()) {
if (member.UserId == 0) {
deptIds.push(member.DeptId);
} else {
memberIds.push(member.UserId);
}
//context.Log(`${member.DeptId},${member.UserId}`);
}
//【営業積算】原価閲覧グループの組織とメンバーをHTML隠し要素に出力
hidden.Add('sekisanMemberList', JSON.stringify(memberIds));
hidden.Add('sekisanDeptList', JSON.stringify(deptIds));
} catch (error) {
context.Log(error);
}
}
//ユーザー情報をHTML内に格納する関数
function getUserList() {
try {
//---------------------------------------------------------------------
group = groups.Get(27); //全従業員グループ27
let userList = {};
//ユーザー情報を取得してリストを作成
for (let member of group.GetMembers()) {
//ユーザー情報情報取得
let user = users.Get(member.UserId);
let rows = extendedSql.ExecuteTable('GetUserMailAddresses', '{"OwnerId": ' + user.UserId + '}');
let mailAddrs = [];
for (let row of rows) {
mailAddrs.push(row.MailAddress);
}
let dept = depts.Get(user.DeptId);
let deptName = dept ? dept.DeptName : '';
userList[user.UserId] = {
userId: user.UserId,
name: user.Name,
deptId: user.DeptId,
deptName: deptName,
mailAddresses: mailAddrs.join(','),
//deptName: dept.Name
}
}
//context.Log(`ユーザーリスト: ${JSON.stringify(userList)}`);
// ユーザーリストをHTML隠し要素に出力
hidden.Add('userList', JSON.stringify(userList));
} catch (error) {
context.Log(error);
}
}
//メッセージデータ取得
function getMessageData() {
//メッセージデータを取得
let data = {
"View": {
"ColumnFilterHash": {
"ClassA": "[\"" + model.SiteId + "\"]",
"ClassB": model.Status
},
"ColumnSorterHash": {
"ClassA": "asc",
"ClassB": "asc",
"NumA": "asc"
}
}
}
let results = items.Get(326371, JSON.stringify(data));
if (results.length === 0) {
context.Log('メッセージデータが見つかりませんでした。');
return;
}
let messageData = []
for (let item of results) {
const status = item.ClassB;
const colorCode = item.ClassC;
const message = item.ClassD;
messageData.push({
"status": status,
"colorCode": colorCode,
"message": message,
});
}
//取得したメッセージデータをhiddenに格納
if (messageData.length > 0) {
hidden.Add('messageData', JSON.stringify(messageData));
} else {
context.Log('メッセージデータが見つかりませんでした。');
}
}

View File

@ -0,0 +1,134 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 01_読み取り専用スタイル
@name
@siteIds : 310407
@siteTitles : Re依頼票
@disabled: false
*/
label.error {
pointer-events: none;
z-index: 100;
border-top: none !important;
}
.code-readonly {
pointer-events: none;
background-color: lightgrey;
font-weight: bold;
}
.code-readonly2,
.code-readonly2+button,
.code-readonly2+div.ui-icon,
.code-readonly3,
.code-readonly3+button,
.code-readonly3+div.ui-icon {
font-weight: bold;
&:active {
pointer-events: none;
}
a:not(.ui-spinner-button) {
pointer-events: auto;
}
}
.code-readonly2 select,
.code-readonly2 input,
.code-readonly2 button.ui-multiselect,
.code-readonly2 .control-markup,
.code-readonly2 .ui-spinner,
span[data-readonly="1"] {
pointer-events: none;
border: dashed 1px black;
background-color: lightgray !important;
color: black !important;
.ui-spinner-input {
border: none;
}
}
.code-readonly3 select,
.code-readonly3 input,
.code-readonly3 button.ui-multiselect,
.code-readonly3 .control-markup,
.code-readonly3 .ui-spinner {
pointer-events: none;
border: dashed 1px black;
.ui-spinner-input {
border: none;
}
}
.code-readonly2,
.code-readonly3,
.field-normal:has(span[data-readonly="1"]),
.field-wide:has(span[data-readonly="1"]) {
position: relative;
&:hover::after {
content: "読取り専用です";
position: absolute;
left: 120px;
top: calc(100% - 9px);
margin-top: 4px;
background: #00000080;
color: #fff;
padding: 4px 10px;
border-radius: 4px;
font-size: 12px;
font-weight: normal !important;
pointer-events: none;
z-index: 9999;
white-space: nowrap;
}
}
.code-required,
select[data-validate-required="1"],
input[data-validate-required="1"] {
border: double 3px red !important;
&+button.ui-multiselect {
border: double 3px red !important;
}
}
.field-normal:has(.code-required),
.field-wide:has(.code-required),
.field-normal:has(select[data-validate-required="1"]),
.field-wide:has(select[data-validate-required="1"]),
.field-normal:has(input[data-validate-required="1"]),
.field-wide:has(input[data-validate-required="1"]) {
position: relative;
&:hover::after {
content: "入力必須です";
position: absolute;
left: 120px;
top: calc(100% - 9px);
margin-top: 4px;
background: #ff000080;
color: #fff;
padding: 4px 10px;
border-radius: 4px;
font-size: 12px;
font-weight: normal !important;
pointer-events: none;
z-index: 9999;
white-space: nowrap;
}
}
.error {
border: double 3px red !important;
}

View File

@ -0,0 +1,30 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 02_共通スタイル
@name
@siteIds : 310407
@siteTitles : Re依頼票
@disabled: false
*/
/*見出しサイズ*/
.field-section {
font-size: 1.5em !important;
font-weight: bold !important;
height: auto;
}
/*項目の後ろの行間を少し狭める*/
.field-normal {
height: 35px;
}
.field-wide {
min-height: 35px;
padding: 0 10px 5px 0;
}
/*コメントのある項目の高さだけ少し広げる*/
div:has(.commentAdd).field-normal {
height: 50px;
}

View File

@ -0,0 +1,14 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 03_プロセスボタンの変更
@name
@siteIds : 310407
@siteTitles : Re依頼票
@disabled: false
*/
.processButtonSize {
font-size: 1.2em !important;
font-weight: bold !important;
}

View File

@ -0,0 +1,69 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 04_項目のサイズ変更
@name
@siteIds : 310407
@siteTitles : Re依頼票
@disabled: false
*/
#Results_ClassB,
label[for="Results_ClassB"] {
font-size: 1.5em !important;
font-weight: bold !important;
height: 2.2em !important;
}
label[for="Results_ClassO"],
label[for="Results_ClassP"],
label[for="Results_ClassQ"],
label[for="Results_DescriptionO"] {
font-size: 1.2em !important;
font-weight: bold !important;
color: red;
}
.container-radio label {
font-size: 1.2em !important;
font-weight: bold !important;
}
label[for="Results_DateJ"] {
font-weight: bold;
color: red;
}
#Results_DateI {
font-weight: bold;
font-size: 1.2em;
background-color: lightblue;
}
#Results_DateJ {
font-weight: bold;
font-size: 1.2em;
background-color: red !important;
color: white !important;
}
.dateI_alert {
background-color: red !important;
color: white !important;
}
#Results_DescriptionOField {
margin-bottom: 10px;
}
.brandComment {
font-size: 0.9em !important;
font-weight: bold !important;
color: white !important;
background-color: black !important;
width: 30%;
display: inline-block;
float: left;
padding: 10px;
border-radius: 10px;
}

View File

@ -0,0 +1,22 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 05_背景変更処理
@name
@siteIds : 310407
@siteTitles : Re依頼票
@disabled: false
*/
.bgColor_Pink {
background-color: #ffe5e5;
display: block;
}
.display_none {
display: none;
}
.fontColor_Red {
color: red;
}

View File

@ -0,0 +1,177 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 06_依頼項目数表示調整
@name
@siteIds : 310407
@siteTitles : Re依頼票
@disabled: false
*/
#SectionFields5 {
width: 70%;
}
.patternComment {
font-weight: bold !important;
width: 30%;
display: inline-block;
padding: 10px;
margin-left: 20px;
border-radius: 10px;
}
.patternTable {
border: 1px solid grey;
border-collapse: collapse;
width: 100%;
td {
border: 1px solid grey;
background-color: whitesmoke;
color: black;
font-size: 1.2em;
padding: 2px 5px;
white-space: nowrap;
}
th {
border: 1px solid grey;
background-color: darkblue;
color: white;
font-weight: bold;
white-space: nowrap;
text-align: center;
vertical-align: middle;
padding: 5px 5px;
}
td:first-child {
background-color: lightcyan;
font-weight: bold;
color: black;
}
td:last-child {
background-color: lightyellow;
color: red;
text-align: center;
font-size: 1.2em;
font-weight: bold;
}
}
.numArea {
width: 350px;
margin-left: 20px;
padding-right: 0px;
.field-label {
width: 200px;
margin-right: -200px;
text-align-last: left;
padding-top: 4px;
padding-left: 10px;
label {
font-size: 1.1em;
font-weight: bold;
}
}
.field-control {
border-bottom: 1px dashed darkgray;
.container-normal {
margin-left: 180px;
}
}
}
.size130 {
label {
font-size: 1.3em;
font-weight: bold !important;
}
input {
font-size: 1.3em;
font-weight: bold !important;
width: 85px !important;
height: 27px !important;
}
span {
height: 35px;
width: 120px;
}
}
.numArea2 {
width: 170px;
padding-right: 0px;
.field-label {
display: none;
}
.field-control {
border-bottom: 1px dashed darkgray;
.container-normal {
margin-left: 0px;
}
}
}
.koumokuStr {
font-size: 0.9em;
float: left;
margin: 7px;
}
.limitStr {
font-size: 0.9em;
float: left;
margin: 7px;
font-weight: bold;
color: red;
}
.parent:has(.iraiAri) {
background-color: yellow;
}
.parent:has(.iraiComplete) {
background-color: lightblue;
}
.iraiAri,
.iraiComplete {
font-weight: bold;
}
.koumokuAddButton {
margin: 1px 1px 1px 5px;
float: left;
pointer-events: auto;
font-weight: bold;
color: white;
background: blue !important;
&:hover {
color: yellow !important;
}
}
.commentAdd2 {
font-size: 0.7em;
font-weight: bold;
color: red;
margin-left: 10px;
}

View File

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>色見本をExcelに出力背景色・文字色適用</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.4/xlsx.full.min.js"></script>
</head>
<body>
<button id="export">色見本をExcelに出力</button>
<script>
document.getElementById("export").addEventListener("click", function () {
const colorSamples = [
["スタイル名", "背景色", "文字色"],
["new-status-red", "#FF0000", "#FFFFFF"],
["new-status-green", "#008000", "#FFFFFF"],
["new-status-blue", "#0000FF", "#FFFFFF"],
["new-status-yellow", "#FFFF00", "#000000"],
["new-status-orange", "#FFA500", "#000000"],
["new-status-purple", "#800080", "#FFFFFF"],
["new-status-pink", "#FFC0CB", "#000000"],
["new-status-brown", "#A52A2A", "#FFFFFF"],
["new-status-cyan", "#00FFFF", "#000000"],
["new-status-magenta", "#FF00FF", "#FFFFFF"],
["new-status-teal", "#008080", "#FFFFFF"],
["new-status-lime", "#00FF00", "#000000"],
["new-status-violet", "#EE82EE", "#000000"],
["new-status-grey", "#808080", "#FFFFFF"],
["new-status-black", "#000000", "#FFFFFF"],
["new-status-white", "#FFFFFF", "#000000"],
["new-status-gold", "#FFD700", "#000000"],
["new-status-silver", "#C0C0C0", "#000000"],
["new-status-navy", "#000080", "#FFFFFF"],
["new-status-maroon", "#800000", "#FFFFFF"],
["new-status-olive", "#808000", "#000000"],
["new-status-aqua", "#00FFFF", "#000000"],
["new-status-beige", "#F5F5DC", "#000000"],
["new-status-chocolate", "#D2691E", "#FFFFFF"],
["new-status-coral", "#FF7F50", "#000000"],
["new-status-crimson", "#DC143C", "#FFFFFF"],
["new-status-indigo", "#4B0082", "#FFFFFF"],
["new-status-ivory", "#FFFFF0", "#000000"],
["new-status-khaki", "#F0E68C", "#000000"],
["new-status-plum", "#DDA0DD", "#000000"],
["new-status-light-red", "#F08080", "#000000"],
["new-status-light-green", "#90EE90", "#000000"],
["new-status-light-blue", "#ADD8E6", "#000000"],
["new-status-light-yellow", "#FFFFE0", "#000000"],
["new-status-light-orange", "#FFDAB9", "#000000"],
["new-status-light-purple", "#E6E6FA", "#000000"],
["new-status-light-pink", "#FFB6C1", "#000000"],
["new-status-light-brown", "#DEB887", "#000000"],
["new-status-light-cyan", "#E0FFFF", "#000000"],
["new-status-light-magenta", "#DA70D6", "#000000"],
["new-status-light-teal", "#20B2AA", "#000000"],
["new-status-light-lime", "#32CD32", "#000000"],
["new-status-light-violet", "#D8BFD8", "#000000"],
["new-status-light-grey", "#D3D3D3", "#000000"],
["new-status-light-black", "#A9A9A9", "#FFFFFF"],
["new-status-light-white", "#F5F5F5", "#000000"],
["new-status-light-gold", "#EEE8AA", "#000000"],
["new-status-light-silver", "#DCDCDC", "#000000"],
["new-status-light-navy", "#708090", "#FFFFFF"],
["new-status-light-maroon", "#BC8F8F", "#000000"],
["new-status-light-olive", "#BDB76B", "#000000"],
["new-status-light-aqua", "#7FFFD4", "#000000"],
["new-status-light-beige", "#FFE4C4", "#000000"],
["new-status-light-chocolate", "#CD853F", "#000000"],
["new-status-light-coral", "#FFE4E1", "#000000"],
["new-status-light-crimson", "#FA8072", "#000000"],
["new-status-light-indigo", "#9370DB", "#000000"],
["new-status-light-ivory", "#FAFAD2", "#000000"],
["new-status-light-khaki", "#F5DEB3", "#000000"],
["new-status-light-plum", "#E6BEAE", "#000000"]
];
const ws = XLSX.utils.aoa_to_sheet(colorSamples);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "色見本");
// セルの背景色と文字色を適用
for (let i = 1; i < colorSamples.length; i++) {
const bgColor = colorSamples[i][1].replace("#", ""); // 背景色HEX
const fontColor = colorSamples[i][2].replace("#", ""); // 文字色HEX
const cell = ws[XLSX.utils.encode_cell({ r: i, c: 0 })]; // スタイル名のセル
const bgCell = ws[XLSX.utils.encode_cell({ r: i, c: 1 })]; // 背景色のセル
if (cell && bgCell) {
cell.s = { fill: { fgColor: { rgb: bgColor } }, font: { color: { rgb: fontColor } } };
bgCell.s = { fill: { fgColor: { rgb: bgColor } }, font: { color: { rgb: fontColor } } };
}
}
// Excelファイルをダウンロード
XLSX.writeFile(wb, "color_samples_styled.xlsx");
});
</script>
</body>
</html>

View File

@ -0,0 +1,4 @@
{
"apiKey": "c38903157cbffc30961f50bc29d0991a6cd8af495ab3009b05c5f98e82b2e61b94ba2d5c0a48fc518b1cd74c9e427b01051a228f670f3c5282544dfbec93db87",
"url": "https://neo999.next-hd.net/pleasanter/"
}

View File

@ -0,0 +1,960 @@
/*
@config :next999.json
@filename : ${psFileBasename}
@title : 01_基本スクリプト
@name :
@siteIds : 310405
@siteTitles : Re③依頼項目
@disabled: false
*/
let pageLoading = 0;
let apiKey = '6504c8a807677a3a576e10327f3c19876c55736ee45d4a845796b9e7f5e087bfd4bd0d8184863da8cf1733ca635111432ab334aea59102b06a96ee6d2c05190d';
let userList = JSON.parse($('#userList').val() || '[]'); //全従業員のユーザーデータ
//メッセージデータ
let messageData = JSON.parse($('#messageData').val() || '[]');
//組織、ユーザによって処理を分岐するフラグ
let eSekisanFlag = false;
let jSekisanFlag = false;
//特権部署のID
let eSekisanDeptId = '25';
let jSekisanDeptId = '26';
//部材リストのデータ
let partsData;
//mssData
let mssData_Brand = $('#mssData_Brand').val() || '';
let mssData_Series = $('#mssData_Series').val() || '';
//----------------------------------------------------------------------
//初期処理
window.addEventListener('load', function () {
if (pageLoading == 0) {
console.log('Window load Event');
$p.ex.onLoad();
}
});
$p.events.on_editor_load = function () {
if (pageLoading == 0) {
console.log('on Editor Load');
$p.ex.onLoad();
}
}
//----------------------------------------------------------------------
$p.ex.onLoad = function () {
//ロード開始
pageLoading = 1;
//初期処理
$p.ex.init();
}
//初期処理
$p.ex.init = function () {
console.log('initialize...');
//一時保存ボタン処理1
$('#UpdateCommand').empty();
$('#UpdateCommand').html(`一時保存`);
$('#UpdateCommand').addClass('new-status-light-lime');
//部材リスト検索欄にコメントを追加
$('#SectionFields18').css('width', '70%');
let commentDiv = document.createElement('div');
commentDiv.className = 'buzaiComment';
let commentBody = document.createElement('pre');
commentBody.innerText =
`左から部材リストを検索してください。
選択した部材の詳細を確認してください
問合せ不要となっている部材については問合せは不要となります算出法を確認し金額をご確認ください
使用不可となっている部材は使用できません
メーカーや部材リストに表示されない部材は下記の依頼項目に詳細を入力しお問い合わせください
`;
commentDiv.appendChild(commentBody);
$('#SectionFields18Container').append(commentDiv);
//コメント追加
$('label[for="SectionFields5"]').append('<span class="commentAdd2">※変更不可</span>');
$('label[for="SectionFields6"]').append('<span class="commentAdd2">※変更不可</span>');
$('label[for="SectionFields8"]').append('<span class="commentAdd3">※編集可能</span>');
//ブランドの横ににコメントを追加
let commentDiv2 = document.createElement('div');
commentDiv2.className = 'brandComment';
let commentBody2 = document.createElement('pre');
commentBody2.innerText =
`複数ブランド提案の場合はここでブランド変更し依頼をしてください。
金額の取り違えには気を付けてください`;
commentDiv2.appendChild(commentBody2);
$('#Results_Class012Field').after(commentDiv2);
//依頼パターン設定(11,12のときは部材リストリンク非表示)
switch ($('#Results_Class041').val()) {
case 'B': //工法
case 'C': //基礎
case 'H': //マトリックス
//部材マスタと大中小リンクの非表示
$('#Results_Class042Field').hide();
$('#Results_Class045Field').hide();
$('#Results_Class046Field').hide();
$('#Results_Class047Field').hide();
$('#Results_Class048Field').hide();
//部材データコンテナ非表示
$('#SectionFields17Container').hide();
$('#SectionFields18Container').hide();
$('#SectionFields19Container').hide();
break;
}
let changeFlag = '';
//大分類の変更イベント
$p.on('change', 'Class035', function () {
console.log('Change Class045');
changeFlag = 'Class045';
//大分類が選択されたら、中分類をクリア
$p.ex.clearRadioChecked('Class046');
$p.ex.clearAllRadioItems('Class047');
$p.ex.clearAllRadioItems('Class048');
});
//中分類の変更イベント
$p.on('change', 'Class036', function () {
console.log('Change Class046');
changeFlag = 'Class046';
//中分類が選択されたら、小分類をクリア
$p.ex.clearRadioChecked('Class047');
$p.ex.clearAllRadioItems('Class048');
});
//小分類の変更イベント
$p.on('change', 'Class037', function () {
console.log('Change Class047');
changeFlag = 'Class047';
//小分類が選択されたら、メーカーをクリア
$p.ex.clearRadioChecked('Class048');
});
//メーカーの変更イベント
$p.on('change', 'Class038', function () {
console.log('Change Class048');
changeFlag = 'Class048';
//メーカーが選択されたら、部材リストリンクをクリア
$p.set($('#Results_Class042'), '');
});
//部材マスタリンクの変更イベント
$p.on('change', 'Class042', function () {
console.log('Change Class042');
let class042 = $('#Results_Class042').val();
if (class042) {
//選択されたら
console.log($('#Results_Class042').val());
$p.ex.getPartsData(class042);
//$('#SectionFields17Container').show();
} else {
//選択を解除されたら
console.log('Results_Class042 is cleared');
//部材リストのデータをクリア
$p.ex.clearPartsData();
let buzaiListCount = $('#Results_Class043 option').length;
switch (changeFlag) {
case 'Class045':
case 'Class046':
case 'Class047':
$('#Results_Class042 option:first').text('分類~メーカーを選択してください');
$p.set($('#Results_CheckA'), 0); //部材リストあり?
$p.ex.changeIraiPage();
break
case 'Class048':
if (buzaiListCount === 1) {
$('#Results_Class042 option:first').text('該当する部材がありません。下記の依頼項目に入力してください。');
$('#Results_Class042Field').css('pointer-events', 'none');
$p.set($('#Results_CheckA'), 1); //部材リスト無し
$p.ex.changeIraiPage();
} else {
$('#Results_Class042 option:first').text('部材リストを選択してください');
$('#Results_Class042Field').css('pointer-events', 'auto');
$p.set($('#Results_CheckA'), 0); //部材リストあり?
$p.ex.changeIraiPage();
}
break
}
}
});
//部材リストの初期表示調整
if (!$('#Results_Class042').val()) {
let buzaiListCount = $('#Results_Class043 option').length;
if (buzaiListCount === 1) {
$('#Results_Class042 option:first').text('分類~メーカーを選択してください');
$('#Results_Class042Field').css('pointer-events', 'none');
//$p.ex.changeIraiPage();
} else {
$('#Results_Class042 option:first').text('部材リストを選択してください');
$('#Results_Class042Field').css('pointer-events', 'auto');
//$p.ex.changeIraiPage();
}
}
//プロセスボタン調整
$p.ex.processButtonControl();
//ラジオボタン調整
$p.ex.radioButtonReadOnly('ClassO');
$p.ex.radioButtonReadOnly('ClassP');
$p.ex.radioButtonReadOnly('ClassQ');
//現在の進捗 が 商談~承認図 の場合
if ($('#Results_ClassO').val() == '0') {
$('#Results_ClassPField').hide();
$('#Results_ClassQField').hide();
$('#Results_DescriptionOField').hide();
}
//所属部署判定
$p.ex.eSekisanCheck();
$p.ex.jSekisanCheck();
//担当者一覧マージイベント
$('#Results_Class022,#Results_Class023,#Results_Class024,#Results_Class025,#Results_Class026,#Results_Class027,#Results_Class028').on('change', function () {
console.log('Change UsersMarge1');
$p.ex.usersMarge1();
});
//CC一覧変更マージイベント
$('#Results_Class031,#Results_Class032,#Results_Class033,#Results_Class034').on('change', function () {
console.log('Change UsersMarge2');
$p.ex.usersMarge2();
});
//新規作成時のみ処理
if ($p.action() == 'new') {
switch ($('#Results_Class041').val()) {
case 'B': //工法
case 'C': //基礎
case 'H': //マトリックス
//部材マスタと大中小リンクの非表示
$('#Results_Class042Field').hide();
$('#Results_Class045Field').hide();
$('#Results_Class046Field').hide();
$('#Results_Class047Field').hide();
$('#Results_Class048Field').hide();
//部材データコンテナ非表示
$('#SectionFields17Container').hide();
$('#SectionFields18Container').hide();
$('#SectionFields19Container').hide();
break;
default:
$('#SectionFields2Container').hide(); //依頼項目の非表示
$('#SectionFields4Container').hide(); //不備追加資料の非表示
break;
}
//マスターシートからシリーズを反映させる
if (mssData_Brand && mssData_Series) {
//mssData_Brandの値が109101のとき、mssData_Seriesの値をResults_Class056に設定する
if (mssData_Brand == '109101') {
$p.set($('#Results_Class056'), mssData_Series);
}
}
} else {
//スタートアップメッセージ表示
$p.ex.startupMessage();
//質疑応答送信ボタン生成
$p.ex.messageSaveButton();
//見積関連ボタン
$p.ex.mitsumoriButton();
//依頼パターンによって表示項目を切り替える処理
//$p.ex.changeColumnList();
//対象エリアと対象ブランドのチェック
waitForElement('#Results_Class074_ms span', function () {
$p.ex.checkAreaAndBrand()
});
//部材リストの内容によって表示内容を修正する
waitForElement('li[aria-controls="FieldSetTab5"]', function () {
$p.ex.changeIraiPage();
});
//補完済みの部材データを読込む
partsData = $('#Results_DescriptionX').val() && JSON.parse($('#Results_DescriptionX').val());
//質疑応答メッセージテーブル作成
$p.ex.messageHistory();
//部材リストの内容によって表示内容を修正する
waitForElement('#SectionFields4Container', function () {
if ($('#Results_Class062').val() == '1') {
$('#SectionFields4Container').show();
} else {
$('#SectionFields4Container').hide();
}
});
}
if (!eSekisanFlag) {
$('#Results_Class132Field').hide();
$('#Results_Description131Field').hide();
//$('#Results_Attachments131Field').hide();
}
//担当者・CC一覧に含まれる場合、営業積算からの質疑は非表示
if (!$('#Results_Class193').val().includes($p.userId().toString())) {
$('#Results_Class132Field').hide();
$('#Results_Description132Field').hide();
//$('#Results_Attachments132Field').hide();
}
let num131 = parseFloat($('#Results_Num131').val());
let num132 = parseFloat($('#Results_Num132').val());
//1つ以上の質疑または回答がある場合は閉じる
/*
if (num131 > 0 || num132 > 0) {
waitForElement('#SectionFields11', function () {
$('label[for="SectionFields11"]').click();
});
}*/
//セレクトボックスにプレースホルダーを追加
addPlaceholderOption('Results_Class059');
addPlaceholderOption('Results_Class063');
//添付ファイルのダウンロードチェックボックスを生成
let attachColumns = $('.control-attachments');
$.each(attachColumns, function (index, value) {
let attach = value.dataset.name;
$p.ex.createDownloadCheckBox(attach);
})
//不備追加資料
$p.on('change', 'Class062', function () {
if ($('#Results_Class062').val() == '1') {
$('#SectionFields4Container').show();
} else {
$('#SectionFields4Container').hide();
}
});
}
$p.ex.modalWindow = function () {
//Results_Class045Field
//Results_Class046Field
//Results_Class047Field
//Results_Class048Field
//Results_Class042Field
// 対象フィールドのjQuery要素を取得
const fields = [
'#Results_Class045Field',
'#Results_Class046Field',
'#Results_Class047Field',
'#Results_Class048Field',
'#Results_Class042Field'
];
// フィールドの位置とサイズを計算
let top = Infinity, left = Infinity, right = -Infinity, bottom = -Infinity;
fields.forEach(selector => {
const $el = $(selector);
if ($el.length) {
const offset = $el.offset();
const width = $el.outerWidth();
const height = $el.outerHeight();
top = Math.min(top, offset.top);
left = Math.min(left, offset.left);
right = Math.max(right, offset.left + width);
bottom = Math.max(bottom, offset.top + height);
}
});
// モーダルが既に存在していれば削除
$('#custom-modal-overlay').remove();
// モーダル用のdivを作成
const $modal = $(`
<div id="custom-modal-overlay" style="
position: absolute;
z-index: 9999;
top: ${top - 8}px;
left: ${left - 8}px;
width: ${right - left + 16}px;
height: ${bottom - top + 16}px;
background: rgba(0,0,0,0.4);
display: flex;
align-items: center;
justify-content: center;
pointer-events: auto;
">
<div style="
background: #fff;
padding: 32px 48px;
border-radius: 8px;
box-shadow: 0 4px 24px rgba(0,0,0,0.2);
min-width: 300px;
min-height: 100px;
text-align: center;
position: relative;
">
<button id="custom-modal-close" style="
position: absolute;
top: 8px;
right: 8px;
background: transparent;
border: none;
font-size: 20px;
cursor: pointer;
">&times;</button>
<div style="margin-top: 16px;">
<b>部材リストを読み込んでいます</b>
</div>
</div>
</div>
`);
// モーダルをbodyに追加
$('body').append($modal);
}
//入力チェック後処理
$p.events.after_validate = function (args) {
//エリア-ブランド結合
$p.ex.areaBrandName();
//施主名 姓名結合
//$p.ex.setCustomerName();
//担当者一覧マージ
$p.ex.usersMarge1();
//CC一覧マージ
$p.ex.usersMarge2();
//担当者・CC一覧マージ
$p.ex.usersMarge3();
//変更履歴の保存
$p.ex.saveHistory();
//依頼項目のマージ
$p.ex.mergeIraiItems();
}
$p.ex.mergeIraiItems = function () {
const IraiColumns = [
'Results_Class051', //メーカー
'Results_Class052', //シリーズ・商品名
'Results_Class053', //品番
'Results_Class054', //施工範囲・箇所
'Results_Class055', //サイズ
'Results_Class056', //nextシリーズ
'Results_Class057', //iPadVer
'Results_Class058', //マトリックスサイズ
'Results_Class059', //階数(設置階)
'Results_Description051', //副資材
'Results_Class060', //標準仕様
'Results_Description052' //その他
];
let IraiItemList = [];
for (let column of IraiColumns) {
let columnName = $('#' + column + 'Field label').text();
let columnValue = $('#' + column).val();
if (columnValue) {
//値がある場合、項目名と値を配列に追加
IraiItemList.push('■' + columnName + ' : ' + columnValue);
}
}
let IraiItemStr = IraiItemList.join('\n');
$p.set($('#Results_Description055'), IraiItemStr);
}
$p.ex.clearIraiItems = function () {
const IraiColumns = [
'Results_Class051', //メーカー
'Results_Class052', //シリーズ・商品名
'Results_Class053', //品番
'Results_Class054', //施工範囲・箇所
'Results_Class055', //サイズ
'Results_Class056', //nextシリーズ
'Results_Class057', //iPadVer
'Results_Class058', //マトリックスサイズ
'Results_Class059', //階数(設置階)
'Results_Description051', //副資材
'Results_Class060', //標準仕様
'Results_Description052' //その他
];
for (let column of IraiColumns) {
//該当の項目をクリア
$p.set($('#' + column).val(), '');
}
$p.set($('#Results_Description055'), '');
}
// 親から子を作成した際に、親への遷移を回避するスクリプト
$p.events.after_set_Create = function (args) {
//baseUrlを使ってitemsのidを含めたURLを取得
itemsUrl = function (id) {
return $('#ApplicationPath').val() + 'items/' + id;
}
let response = args.json.filter(function (item, index) {
if (item.Method == 'Response') return true;
});
//子テーブルに留まる
location.href = itemsUrl(response[0].Value);
//初期処理
$p.ex.init();
}
$p.events.after_set_Update = function (args) {
//初期処理
$p.ex.init();
//一時保存ボタン処理2
$('#UpdateCommand').empty();
$('#UpdateCommand').html(`<span class="ui-button-icon ui-icon ui-icon-disk"></span>
<span class="ui-button-icon-space"> </span>
一時保存`);
//一時保存メッセージ
let json8val = JSON.parse(args.json[8].Value);
if (json8val.Id == 'Updated') {
$p.ex.setMyMessage('new-status-light-lime', '依頼項目の内容が一時保存されました');
}
}
//エリアとブランド名を合体させて格納する
$p.ex.areaBrandName = function () {
let area = $('#Results_Class011 option:selected').text();
let brand = $('#Results_Class012 option:selected').text();
if (area && brand) {
$p.set($('#Results_ClassL'), area + ' ' + brand);
}
}
//担当者一覧マージ
$p.ex.usersMarge1 = function () {
let users = [];
$('#Results_ClassE').val() && users.push($('#Results_ClassE').val()); //依頼者
$('#Results_Class022').val() && users.push($('#Results_Class022').val()); //主担当営業 Class022
$('#Results_Class023').val() && users.push($('#Results_Class023').val()); //副担当営業 Class023
$('#Results_Class024').val() && users.push($('#Results_Class024').val()); //営業設計 Class024
$('#Results_Class025').val() && users.push($('#Results_Class025').val()); //担当監督 Class025
$('#Results_Class026').val() && users.push($('#Results_Class026').val()); //担当IC Class026
$('#Results_Class027').val() && users.push($('#Results_Class027').val()); //管理設計 Class027
$('#Results_Class028').val() && users.push($('#Results_Class028').val()); //所属長 Class028
$p.set($('#Results_Class191'), JSON.stringify(users));
$p.ex.usersMarge3();
}
//CC一覧マージ
$p.ex.usersMarge2 = function () {
let users = [];
$('#Results_Class031').val() && users.push($('#Results_Class031').val()); //CC1
$('#Results_Class032').val() && users.push($('#Results_Class032').val()); //CC2
$('#Results_Class033').val() && users.push($('#Results_Class033').val()); //CC3
$('#Results_Class034').val() && users.push($('#Results_Class034').val()); //CC4
$p.set($('#Results_Class192'), JSON.stringify(users));
$p.ex.usersMarge3();
}
//担当者・CC一覧マージ
$p.ex.usersMarge3 = function () {
//担当者一覧とCC一覧をマージして保管
let mergeAry = [...$('#Results_Class191').val(), ...$('#Results_Class192').val()];
mergeAry.push($('#Results_ClassE').val());
$p.set($('#Results_Class193'), JSON.stringify(mergeAry));
}
//アクセスと権限チェック
//営業積算メンバーチェック
$p.ex.eSekisanCheck = function () {
console.log('Check e-sekisan Depts Code');
if ($p.userId() == '460') {
eSekisanFlag = true;
} else if ($p.deptId() == eSekisanDeptId) {
eSekisanFlag = true;
} else {
//タブ4非表示
waitForElement('li[aria-controls="FieldSetTab4"]', function () {
$('li[aria-controls="FieldSetTab4"]').hide();
});
}
}
//アクセスと権限チェック
//【営業積算】閲覧権限 グループメンバーチェック
$p.ex.jSekisanCheck = function () {
console.log('Check j-sekisan Depts Code');
let sekisanMemberList = JSON.parse($('#sekisanMemberList').val());
let sekisanDeptList = JSON.parse($('#sekisanDeptList').val());
//console.log(sekisanMemberList);
//console.log(sekisanDeptList);
if (sekisanMemberList.includes($p.userId())) {
jSekisanFlag = true;
} else if (sekisanDeptList.includes($p.deptId())) {
jSekisanFlag = true;
} else {
//タブ5非表示
waitForElement('li[aria-controls="FieldSetTab5"]', function () {
$('li[aria-controls="FieldSetTab5"]').hide();
});
}
}
//要素が読み込まれるまで待機し、返す
function waitForElement(selector, callback, interval = 100, timeout = 5000) {
const startTime = Date.now();
const checkExist = setInterval(function () {
if ($(selector).length) {
clearInterval(checkExist); // 要素が見つかったら停止
callback();
} else if (Date.now() - startTime > timeout) {
clearInterval(checkExist); // タイムアウト処理
console.warn(`指定した要素 '${selector}' が ${timeout / 1000} 秒以内に見つかりませんでした。`);
}
}, interval);
}
//ラジオボタンを無効化する
$p.ex.radioButtonReadOnly = function (column) {
//console.log($('input[name="Results_' + column + '"][type="radio"]'))
$('input[name="Results_' + column + '"][type="radio"]').each(function (index, value) {
if ($(this)[0].checked) {
$(this).parent().css('color', 'blue');
} else {
$(this).prop('disabled', true);
}
})
}
//プリザンターから1件のレコードデータを取得する関数
$p.ex.getRecordData = async function (id) {
//もしidが空鳴らんば、空のオブジェクトを返す
if (!id) {
return {};
}
//プリザンターへゲット処理
const url = 'https://' + location.hostname + '/pleasanter/api/items/' + id + '/get'
const json = {
'ApiVersion': 1.1,
'ApiKey': apiKey,
}
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(json)
});
const resData = await res.json();
//console.log(resData);
return resData.Response.Data[0];
}
/*
//マトリックスサイズ入力欄について
$('#Results_Num052Field span.ui-widget-content').prependTo('#Results_Class051Field .container-normal');
$('<div>✕</div>').prependTo('#Results_Class051Field .container-normal');
$('#Results_Num051Field span.ui-widget-content').prependTo('#Results_Class051Field .container-normal');
[
{
"SiteId": 310407,
"View": {
"ColumnSorterHash": {
"ClassA": "asc"
}
},
"Lookups": [
{
"From": "ClassA",
"To": "ClassA",
"OverwriteForm": true
}, {
"From": "ClassB",
"To": "ClassB",
"OverwriteForm": true
}, {
"From": "ClassE",
"To": "ClassE",
"OverwriteForm": true
}, {
"From": "Class199",
"To": "Class041",
"OverwriteForm": true
}, {
"From": "DateI",
"To": "DateI",
"OverwriteForm": true
}, {
"From": "ClassI",
"To": "ClassI",
"OverwriteForm": true
}, {
"From": "ClassJ",
"To": "ClassJ",
"OverwriteForm": true
}, {
"From": "ClassK",
"To": "ClassK",
"OverwriteForm": true
}, {
"From": "ClassL",
"To": "ClassL",
"OverwriteForm": true
}, {
"From": "ClassM",
"To": "ClassM",
"OverwriteForm": true
}, {
"From": "ClassN",
"To": "ClassN",
"OverwriteForm": true
}, {
"From": "ClassO",
"To": "ClassO",
"OverwriteForm": true
}, {
"From": "ClassP",
"To": "ClassP",
"OverwriteForm": true
}, {
"From": "ClassQ",
"To": "ClassQ",
"OverwriteForm": true
}, {
"From": "DescriptionO",
"To": "DescriptionO",
"OverwriteForm": true
}, {
"From": "ClassX",
"To": "ClassX",
"OverwriteForm": true
}, {
"From": "ClassY",
"To": "ClassY",
"OverwriteForm": true
}, {
"From": "ClassZ",
"To": "ClassZ",
"OverwriteForm": true
}, {
"From": "Class001",
"To": "Class001",
"OverwriteForm": true
}, {
"From": "Class010",
"To": "Class010",
"OverwriteForm": true
}, {
"From": "Class011",
"To": "Class011",
"OverwriteForm": true
}, {
"From": "Class012",
"To": "Class012",
"OverwriteForm": true
}, {
"From": "Class013",
"To": "Class013",
"OverwriteForm": true
}, {
"From": "Class014",
"To": "Class014",
"OverwriteForm": true
}, {
"From": "Date001",
"To": "Date001",
"OverwriteForm": true
}, {
"From": "Date002",
"To": "Date002",
"OverwriteForm": true
}, {
"From": "Class021",
"To": "Class021",
"OverwriteForm": true
}, {
"From": "Class022",
"To": "Class022",
"OverwriteForm": true
}, {
"From": "Class023",
"To": "Class023",
"OverwriteForm": true
}, {
"From": "Class024",
"To": "Class024",
"OverwriteForm": true
}, {
"From": "Class025",
"To": "Class025",
"OverwriteForm": true
}, {
"From": "Class026",
"To": "Class026",
"OverwriteForm": true
}, {
"From": "Class027",
"To": "Class027",
"OverwriteForm": true
}, {
"From": "Class028",
"To": "Class028",
"OverwriteForm": true
}, {
"From": "Class031",
"To": "Class031",
"OverwriteForm": true
}, {
"From": "Class032",
"To": "Class032",
"OverwriteForm": true
}, {
"From": "Class033",
"To": "Class033",
"OverwriteForm": true
}, {
"From": "Class034",
"To": "Class034",
"OverwriteForm": true
}, {
"From": "Description001",
"To": "Description001",
"OverwriteForm": true
}, {
"From": "ClassT",
"To": "ClassT",
"OverwriteForm": true
}, {
"From": "DescriptionT",
"To": "DescriptionT",
"OverwriteForm": true
}, {
"From": "Class191",
"To": "Class191",
"OverwriteForm": true
}, {
"From": "Class192",
"To": "Class192",
"OverwriteForm": true
}, {
"From": "Class193",
"To": "Class193",
"OverwriteForm": true
}, {
"From": "Class193",
"To": "Class111",
"OverwriteForm": true
}, {
"From": "Class193",
"To": "Class132",
"OverwriteForm": true
}
]
}
]
*/
/*
[
{
"SiteId": 68782,
"SearchFormat": "[Title] - [ClassA] - [Owner]",
"View": {
"ColumnSorterHash": {
"ResultId": "desc"
},
"ColumnFilterHash": {
"Status": "[\"100\",\"110\",\"150\",\"200\",\"210\",\"500\"]"
}
},
}
]
[
{
"SiteId": 109112,
"SearchFormat": "[Title] - [ClassA] - [Owner]",
"View": {
"ColumnSorterHash": {
"ClassB": "asc"
},
"ColumnFilterHash": {
"ClassA": "[\"109101\"]"
}
},
}
]
*/
/*
[
{
"SiteId": "320587",
"SearchFormat": "[ClassD]■[ClassI]-[ClassJ]-[ClassK]■[ClassV]■[ClassW]",
"View": {
"ColumnSorterHash": {
"ClassA": "asc",
"ClassB": "asc",
"ClassC": "asc",
"ClassD": "asc",
}
}
}
]
*/

View File

@ -0,0 +1,140 @@
/*
@config :next999.json
@filename : ${psFileBasename}
@title : 02_プロセス
@name :
@siteIds : 310405
@siteTitles : Re③依頼項目
@disabled: false
*/
// プロセスごとに実行スクリプト
$p.ex.processScript = function (procNum) {
//プロセス共通処理 ------------------------------------------------------------------
//確認メッセージの取得
let confirmMessage = $('#Process_' + procNum).attr('data-confirm');
//実行確認
if (!confirm(confirmMessage)) {
//キャンセルなら終了
console.log('Process_' + procNum + ' はキャンセルされました');
return false;
} else {
//オリジナルの確認メッセージの削除
$('#Process_' + procNum).removeAttr('data-confirm');
}
//プロセス名の取得
let procName = $('#Process_' + procNum).text().replace(/^\s+/, '');
console.log(`▷Process_${procNum} : ${procName} 処理開始`);
//--------------------------------------------------------------------------------
//プロセスごとの個別処理
switch (procNum) {
case '1': //質疑送信
let questionMessage = $('#Results_Description131').val();
if (questionMessage) {
$p.ex.saveQuestionMessage();
} else {
//質疑本文が空欄
$p.ex.setMyMessage('new-status-red', '質疑本文を入力してください');
return false;
}
break;
case '2': //回答送信
let answerMessage = $('#Results_Description132').val();
if (answerMessage) {
$p.ex.saveAnswerMessage();
} else {
//回答本文が空欄
$p.ex.setMyMessage('new-status-red', '回答本文を入力してください');
return false;
}
break;
case '3': //回答確認
break;
case '4': //見積回答削除
if ($('input[name="messageDeleteCheck"]:checked').length) {
$p.ex.messageDelete();
} else {
$p.ex.setMyMessage('new-status-red', '回答本文を入力削除したい質疑回答メッセージ選択してくださいしてください');
}
break;
case '5': //登録完了
break;
case '6': //積算依頼
break;
case '7': //積算受付
break;
case '8': //積算対応
break;
case '9': //外部見積
break;
case '10': //社内確認
break;
case '11': //チェック
break;
case '12': //差戻し
break;
case '13': //積算回答
break;
case '14': //完了
break;
case '15': //保留
break;
case '16': //取消
break;
case '17': //e保留
break;
case '18': //e取消
break;
case '19': //依頼不要
break;
case '20': //再依頼
break;
}
//プロセスの実行
console.log(`▶Process_${procNum} : ${procName} 処理終了`);
$p.execProcess($('#Process_' + procNum));
}
//プロセスボタン調整
$p.ex.processButtonControl = function () {
$("button[id^='Process']").each(function () {
//hideで始まるボタンの非表示
if ($(this).attr('data-icon') == 'ui-icon-close') {
$(this).hide();
}
//hideで始まるボタンの非表示
if ($(this).attr('data-icon') == 'ui-icon-cancel') {
//グレーアウト
$(this).addClass('new-status-grey');
} else {
//ボタンサイズ拡大
$(this).addClass('processButtonSize');
}
//個別設定
switch (this.id) {
case 'Process_1':
$(this).addClass('new-status-yellow');
break;
case 'Process_2':
$(this).addClass('new-status-red');
break;
case 'Process_5':
$(this).addClass('new-status-blue');
break;
}
});
}

View File

@ -0,0 +1,304 @@
/*
@config :next999.json
@filename : ${psFileBasename}
@title : 03_質疑応答スクリプト
@name :
@siteIds : 310405
@siteTitles : Re③依頼項目
@disabled: false
*/
//営業積算からの質疑を保存
$p.ex.saveQuestionMessage = function () {
let message = $('#Results_Description131').val();
let userName = $p.userName();
let now = new Date();
let nowStr = now.getFullYear() + '/' + (now.getMonth() + 1).toString().padStart(2, '0') + '/' + now.getDate().toString().padStart(2, '0') + ' ' +
now.getHours().toString().padStart(2, '0') + ':' + now.getMinutes().toString().padStart(2, '0') + ':' + now.getSeconds().toString().padStart(2, '0');
let messageID = 'a' + now.getFullYear() + '' + (now.getMonth() + 1).toString().padStart(2, '0') + '' + now.getDate().toString().padStart(2, '0') + '' +
now.getHours().toString().padStart(2, '0') + '' + now.getMinutes().toString().padStart(2, '0') + '' + now.getSeconds().toString().padStart(2, '0') + '-' + $p.userId();
let num = parseFloat($('#Results_Num131').val()) + 1;
let data = {
'messageID': messageID,
'type': 'Question',
'num': toCircledNumber(num),
'typeStr': '営業積算からの質疑',
'userName': userName,
'messageTime': nowStr,
'messageBody': message,
'enabled': true,
};
//質疑回答 保管用項目に保存する
let saveData = $('#Results_Description135').val();
let shitsugiData;
if (saveData == '') {
shitsugiData = [];
shitsugiData.push(data);
} else {
shitsugiData = JSON.parse(saveData);
shitsugiData.push(data);
}
$p.set($('#Results_Description135'), JSON.stringify(shitsugiData));
//保管したら入力欄は削除する
$p.set($('#Results_Description136'), $('#Results_Description131').val());
$p.set($('#Results_Description131'), '');
}
//依頼者からの回答を保存
$p.ex.saveAnswerMessage = function () {
let message = $('#Results_Description132').val();
let userName = $p.userName();
let now = new Date();
let nowStr = now.getFullYear() + '/' + (now.getMonth() + 1).toString().padStart(2, '0') + '/' + now.getDate().toString().padStart(2, '0') + ' ' +
now.getHours().toString().padStart(2, '0') + ':' + now.getMinutes().toString().padStart(2, '0') + ':' + now.getSeconds().toString().padStart(2, '0');
let messageID = 'b' + now.getFullYear() + '' + (now.getMonth() + 1).toString().padStart(2, '0') + '' + now.getDate().toString().padStart(2, '0') + '' +
now.getHours().toString().padStart(2, '0') + '' + now.getMinutes().toString().padStart(2, '0') + '' + now.getSeconds().toString().padStart(2, '0') + '-' + $p.userId();
let num = parseFloat($('#Results_Num132').val()) + 1;
let data = {
'messageID': messageID,
'type': 'Answer',
'num': toCircledNumber(num),
'typeStr': '依頼者からの回答',
'userName': userName,
'messageTime': nowStr,
'messageBody': message,
'enabled': true,
};
//質疑回答 保管用項目に保存する
let saveData = $('#Results_Description135').val();
let shitsugiData;
if (saveData == '') {
shitsugiData = [];
shitsugiData.push(data);
} else {
shitsugiData = JSON.parse(saveData);
shitsugiData.push(data);
}
$p.set($('#Results_Description135'), JSON.stringify(shitsugiData));
//保管したら入力欄は削除する
$p.set($('#Results_Description136'), $('#Results_Description132').val());
$p.set($('#Results_Description132'), '');
}
$p.ex.messageHistory = function () {
//質疑開通と回答回数の参照
let num131 = parseFloat($('#Results_Num131').val());
let num132 = parseFloat($('#Results_Num132').val());
if (num131 > 0 || num132 > 0) {
//タブの色の変更
let shitsugi_Status = $('#Results_Class131').val();
//console.log('質疑回答ステータス: ' + shitsugi_Status);
switch (shitsugi_Status) {
case '': //質疑なし
case '0': //質疑なし
$('a[href="#FieldSetTab3"] label').text('質疑なし');
$('a[href="#FieldSetTab3"]').css('background-color', 'blue');
$('a[href="#FieldSetTab3"]').css('color', 'white');
break;
case '1'://質疑あり
$('a[href="#FieldSetTab3"] label').text('質疑あり');
$('a[href="#FieldSetTab3"]').css('background-color', 'red');
$('a[href="#FieldSetTab3"]').css('color', 'white');
break;
case '2'://回答あり
$('a[href="#FieldSetTab3"] label').text('回答あり');
$('a[href="#FieldSetTab3"]').css('background-color', 'yellow');
$('a[href="#FieldSetTab3"]').css('color', 'black');
break;
case '3'://回答確認済み
$('a[href="#FieldSetTab3"] label').text('回答確認済み');
$('a[href="#FieldSetTab3"]').css('background-color', 'green');
$('a[href="#FieldSetTab3"]').css('color', 'white');
break;
}
//メッセージテーブルがすでに存在したら削除
if ($('#messageTable').length) {
$('#messageTable').remove();
}
//削除ボタン削除
if ($('#messageDelete').length) {
$('#messageDelete').remove();
}
let saveData = $('#Results_Description135').val();
if (saveData) {
//メッセージデータの取得
let messageData = [];
messageData = JSON.parse(saveData);
//messageData.reverse();
//console.log('質疑回答メッセージデータ: ' + JSON.stringify(messageData));
let templateHtml;
templateHtml =
`<table id="messageTable" class="radius-table">
<tbody>
{{#messageData}}
<tr class="{{type}}">
<td class="shitsugi_type">{{typeStr}} {{num}}</td>
<td class="shitsugi_userName">{{userName}}</td>
<td class="shitsugi_messageTime">{{messageTime}}</td>
</tr>
<tr class="{{type}}">
<td colspan="2" class="shitsugi_messageBody">
<pre class="shitsugi_preWrap">{{{messageBody}}}</pre>
</td>
<td class="shitsugi_deleteCheck"><input type="checkbox" name="messageDeleteCheck" value="{{messageID}}"></input></td>
</tr>
{{/messageData}}
</tbody>
</table>`;
let template = Hogan.compile(templateHtml);
let outputHtml = template.render({
"messageData": messageData
});
//console.log(outputHtml);
setTimeout(function () {
$('#SectionFields12').prepend(outputHtml);
}, 300);
}
//営業積算のみ表示
if (eSekisanFlag) {
//質疑回答削除ボタンを作成
let div3 = document.createElement('div');
let button3 = document.createElement('button');
button3.type = 'button';
button3.id = 'messageDelete';
button3.innerHTML = '質疑回答削除';
button3.setAttribute('onclick', '$("#Process_4").click()');
button3.style.margin = '5px';
button3.style.float = 'right';
button3.style.fontSize = '1.3em';
div3.append(button3);
$('#SectionFields12').prepend(div3);
$('#messageDelete').button({
icon: 'ui-icon-document'
});
}
} else {
$('#SectionFields12Container').hide();
}
}
//質疑回答送信ボタン作成
$p.ex.messageSaveButton = function () {
//営業積算のみ表示
if (eSekisanFlag) {
//質疑送信ボタン
let div1 = document.createElement('div');
div1.style.textAlign = 'right';
let button1 = document.createElement('button');
button1.type = 'button';
button1.id = 'saveQuestion';
button1.innerHTML = '質疑送信';
button1.setAttribute('onclick', '$("#Process_1").click()');
button1.style.margin = '5px';
button1.style.fontSize = '1.3em';
div1.append(button1);
$('#Results_Attachments131Field').after(div1);
$('#saveQuestion').button({
icon: 'ui-icon-document'
});
}
//回答送信ボタン
let div2 = document.createElement('div');
div2.style.textAlign = 'right';
let button2 = document.createElement('button');
button2.type = 'button';
button2.id = 'saveAnswer';
button2.innerHTML = '回答送信';
button2.setAttribute('onclick', '$("#Process_2").click()');
button2.style.margin = '5px';
button2.style.fontSize = '1.3em';
div2.append(button2);
$('#Results_Attachments132Field').after(div2);
$('#saveAnswer').button({
icon: 'ui-icon-document'
});
}
$p.ex.messageDelete = function () {
//チェックが入っていたら実行
let messageData = JSON.parse($('#Results_Description135').val());
//チェックのあるメッセージを配列から除去する
$('input[name="messageDeleteCheck"]:checked').each(function (index) {
let messageID = $(this).val();
// messageIDが一致するデータのenabledをfalseに変更
messageData = messageData.map(item => {
if (item.messageID === messageID) {
return {
...item,
enabled: false,
type: item.type + '.Disabled'
};
}
return item;
});
//質疑 回答判定
/*
if (messageID.charAt(0) == 'a') {
//質疑回数の数を1つ減らす
let num131 = parseFloat($('#Results_Num131').val());
$p.set($('#Results_Num131'), num131 - 1);
} else if (messageID.charAt(0) == 'b') {
//回答回数の数を1つ減らす
let num132 = parseFloat($('#Results_Num132').val());
$p.set($('#Results_Num131'), num132 - 1);
}
*/
//console.log(messageId);
//messageData = messageData.filter(item => item.messageID !== messageID);
});
$p.set($('#Results_Description135'), JSON.stringify(messageData));
$p.ex.setMyMessage('new-status-green', '選択した質疑回答メッセージを削除しました');
}
// numを丸数字に変換して表示
function toCircledNumber(n) {
n = Math.floor(Number(n));
if (isNaN(n) || n < 0 || n > 100) return n;
if (n === 0) return '⓪';
if (n <= 20) return String.fromCharCode(9311 + n); // 9312 = ①
if (n <= 35) return String.fromCharCode(12881 + n - 21); // 12881 = ㉑
if (n <= 50) return String.fromCharCode(12977 + n - 36); // 12977 = ㊱
if (n <= 100) return n; // fallback for 51-100
}

View File

@ -0,0 +1,134 @@
/*
@config :next999.json
@filename : ${psFileBasename}
@title : 04_見積遅延連絡スクリプト
@name :
@siteIds : 310405
@siteTitles : Re③依頼項目
@disabled: false
*/
$p.on('change', 'Class152', function () {
$p.ex.createChienMail();
});
$p.on('change', 'Date151', function () {
$p.ex.createChienMail();
});
//遅延メール作成
$p.ex.createChienMail = function () {
let riyu = $('#Results_Class152').val();
let riyuStr = $('#Results_Class152 option[value="' + riyu + '"').text();
let dateStr = $('#Results_Date151').val();
let henshinDate = new Date(dateStr);
if (riyu && dateStr) {
let dayOfWeek = henshinDate.getDay(); // 曜日(数値)
let dayOfWeekStr = ["日", "月", "火", "水", "木", "金", "土"][dayOfWeek]; // 曜日(日本語表記)
let body1 = `${riyuStr} につき、見積返信が遅延する予定です。
見積返信予定日${dateStr} (${dayOfWeekStr})
お待たせしており申し訳ございません
いましばらくお待ちください
宜しくお願い致します`;
let bodyA = `現在、積算問い合わせが集中しているため
見積り返信までに通常よりも時間を要する見込みです
見積アップ希望日が近い順から対応しておりますので
いましばらくお待ちください
急を要する場合はお電話ください`;
let bodyB = `問い合わせ内容について依頼者からの質疑回答待ちのため
回答が届き次第見積り対応を進めます
営業積算からの質疑をご確認いただき
依頼者からの回答欄に入力をお願いいたします
急を要する場合はお電話ください`;
let messageBody = body1;
//理由3,4の場合メッセージを変更する
switch (riyu) {
case '3':
messageBody = bodyA;
break;
case '4':
messageBody = bodyB;
break;
}
$p.set($('#Results_Description151'), messageBody);
}
}
//遅延メールを保存する
$p.ex.saveChienMail = function () {
//あて先
let addr = $('#Results_Class151_ms span').text();
let riyu = $('#Results_Class152').val();
let riyuStr = $('#Results_Class152 option[value="' + riyu + '"').text();
let message = $('#Results_Description151').val();
let sendUser = $('#Results_Class153 option:selected').text();
let lateDate = $('#Results_Date151').val();
let sendDate = $('#Results_Date152').val();
let saveLog = `--------------------------------------------------------------------------
あて先${addr}
遅延理由${riyuStr}
返信予定日${lateDate}
遅延通知メール
${message}
送信者${sendUser}
送信日時${sendDate}
`;
let log = $('#Results_Description155').val();
log = log + saveLog;
$p.set($('#Results_Description155'), log);
}
$p.ex.mitsumoriButton = function () {
//見積依頼ボタン
let div1 = document.createElement('div');
let button1 = document.createElement('button');
button1.type = 'button';
button1.id = 'mitsumoriIrai';
button1.innerHTML = '見積依頼';
//button1.setAttribute('onclick', '$("#Process_5").click()');
button1.style.margin = '5px';
button1.style.float = 'right';
button1.style.fontSize = '1.3em';
div1.append(button1);
$('#Results_Class142').after(div1);
$('#mitsumoriIrai').button({
icon: 'ui-icon-search'
});
//見積遅延連絡ボタン
let div2 = document.createElement('div');
let button2 = document.createElement('button');
button2.type = 'button';
button2.id = 'mitsumoriChien';
button2.innerHTML = '見積遅延連絡';
//button2.setAttribute('onclick', '$("#Process_6").click()');
button2.style.margin = '5px';
button2.style.float = 'right';
button2.style.fontSize = '1.3em';
div2.append(button2);
$('#Results_Description151').after(div2);
$('#mitsumoriChien').button({
icon: 'ui-icon-alert'
});
}

View File

@ -0,0 +1,624 @@
/*
@config :next999.json
@filename : ${psFileBasename}
@title : 05_依頼項目操作スクリプト
@name :
@siteIds : 310405
@siteTitles : Re③依頼項目
@disabled: false
*/
//依頼パターンごとの表示項目リスト
$p.ex.changeColumnList = function () {
let viewList = {
'A': ['col1', 'col2', 'col3', 'col4', 'col9', 'col11', 'col12'],
'B': ['col1', 'col8', 'col11'],
'C': ['col4', 'col11', 'col12'],
'D': ['col1', 'col2', 'col3', 'col4', 'col9', 'col11'],
'E': ['col1', 'col2', 'col3', 'col4', 'col5'],
'F': ['col1', 'col2', 'col3', 'col4', 'col10', 'col11'],
'G': ['col1', 'col2', 'col3', 'col4', 'col10'],
'H': ['col6', 'col7', 'col8', 'col9'],
'I': ['col1', 'col2', 'col3', 'col4', 'col5', 'col10', 'col12']
}
//表示項目の定義名
let columnList = {
'col1': { "Name": "メーカー", "ColumnName": "Class051" },
'col2': { "Name": "シリーズ・商品名", "ColumnName": "Class052" },
'col3': { "Name": "品番", "ColumnName": "Class053" },
'col4': { "Name": "施工範囲・箇所", "ColumnName": "Class054" },
'col5': { "Name": "サイズ", "ColumnName": "Class055" },
'col6': { "Name": "nextシリーズ", "ColumnName": "Class056" },
'col7': { "Name": "iPadVer", "ColumnName": "Class057" },
'col8': { "Name": "マトリックスサイズ", "ColumnName": "Class058" },
'col9': { "Name": "階数(設置階)", "ColumnName": "Class059" },
'col10': { "Name": "副資材", "ColumnName": "Description051" },
'col11': { "Name": "標準仕様", "ColumnName": "Class060" },
'col12': { "Name": "その他", "ColumnName": "Description052" }
}
//パターンの取得
let pattern = $('#Results_Class041').val();
let idList = viewList[pattern];
//idListに含まれるColumnName表示対象
let matchColumnNames = idList.map(id => columnList[id].ColumnName);
//idListに含まれないColumnName非表示対象
let allColumnNames = Object.values(columnList).map(item => item.ColumnName);
let unmatchColumnNames = allColumnNames.filter(name => !matchColumnNames.includes(name));
//ここで表示・非表示処理を追加可能
unmatchColumnNames.map(id => {
//非表示
$('#Results_' + id + 'Field').hide();
});
//nextシリーズの調整
let brand = $('#Results_Class012').val();
if (brand === '109101') {
} else {
//nextシリーズではない場合、欄を空欄にして非表示
$('#Results_Class056Field').addClass('code-readonly2');
$p.set($('#Results_Class056'), ''); //nextシリーズの値を空にする
$('#Results_Class056 option:first').text('非nexthouseです');
$('#Results_Class056').css('background-color', 'grey');
}
}
//ラジオボタンの選択を変更
$p.ex.clearRadioChecked = function (id) {
//ラジオボタンの選択の解除
$('input[name="Results_' + id + '"].control-radio:checked').each(function () {
$(this).prop('checked', false);
$(this).parent().remove();
});
//値の削除
$p.set($('#Results_' + id + ''), '');
}
$p.ex.clearAllRadioItems = function (id) {
//ラジオボタンの選択の解除
$('input[name="Results_' + id + '"].control-radio:checked').each(function () {
$(this).prop('checked', false);
});
//ラジオボタンのアイテムをすべて削除
$('input[name="Results_' + id + '"].control-radio').each(function () {
$(this).parent().remove();
});
//値の削除
$p.set($('#Results_' + id + ''), '');
}
//部材リストからデータを取得する関数
$p.ex.getPartsData = async function (id) {
//部材リストのデータの初期化
partsData = {
"Status": { "Label": "問合せ有無", "Data": "" },
"Comments": { "Label": "改訂履歴", "Data": "" },
"ClassA": { "Label": "大分類", "Data": "" },
"ClassB": { "Label": "中分類", "Data": "" },
"ClassC": { "Label": "小分類", "Data": "" },
"ClassD": { "Label": "メーカー", "Data": "" },
"ClassE": { "Label": "算出方法", "Data": "" },
"ClassI": { "Label": "品名/シリーズ", "Data": "" },
"ClassJ": { "Label": "品番/コード", "Data": "" },
"ClassK": { "Label": "タイプ/クラス/パターン", "Data": "" },
"ClassL": { "Label": "サイズ", "Data": "" },
"ClassM": { "Label": "追加・差額", "Data": "" },
"ClassP": { "Label": "販売単位", "Data": "" },
"ClassQ": { "Label": "単位", "Data": "" },
"ClassV": { "Label": "対象エリア", "Data": "" }, //*
"ClassW": { "Label": "対象ブランド", "Data": "" }, //*
"Class001": { "Label": "単価表", "Data": "" }, //*
"Class002": { "Label": "販売算出表", "Data": "" }, //*
"Class003": { "Label": "カタログ1", "Data": "" }, //*
"Class004": { "Label": "カタログ2", "Data": "" }, //*
"Class005": { "Label": "NotePM1", "Data": "" }, //*
"Class006": { "Label": "NotePM2", "Data": "" }, //*
"Class007": { "Label": "NotePM3", "Data": "" }, //*
"NumA": { "Label": "販売価格", "Data": "" },
"NumB": { "Label": "送料", "Data": "" },
"DescriptionA": { "Label": "注記", "Data": "" }, //*
"DescriptionB": { "Label": "URL", "Data": "" },
"Description001": { "Label": "検索キーワード", "Data": "" },
"CheckA": { "Label": "注記有", "Data": "" },
"CheckI": { "Label": "全エリア", "Data": "" },
"CheckJ": { "Label": "全ブランド", "Data": "" },
"Check001": { "Label": "東京", "Data": "" },
"Check002": { "Label": "愛知", "Data": "" },
"Check003": { "Label": "千葉", "Data": "" },
"Check004": { "Label": "静岡", "Data": "" },
"Check005": { "Label": "熊本", "Data": "" },
"Check011": { "Label": "actie", "Data": "" },
"Check012": { "Label": "nexthouse", "Data": "" },
"Check013": { "Label": "ACTIVEHOUSE", "Data": "" },
"Check014": { "Label": "Bluezia", "Data": "" },
"Check015": { "Label": "CLEVERLYHOME", "Data": "" },
"Check016": { "Label": "WELLHOMES", "Data": "" },
"Check017": { "Label": "はちみつハウス", "Data": "" },
"Check018": { "Label": "GRAPH", "Data": "" },
}
//部材リストの値を取得
//プリザンターへゲット処理
const recordData = await $p.ex.getRecordData(id);
//取得データを格納
partsData.Status.Data = recordData.Status;
partsData.Comments.Data = recordData.Comments;
Object.keys(recordData.ClassHash).forEach(function (key) {
const value = recordData.ClassHash[key];
if (partsData[key]) {
partsData[key].Data = value;
}
});
Object.keys(recordData.CheckHash).forEach(function (key) {
const value = recordData.CheckHash[key];
if (partsData[key]) {
partsData[key].Data = value;
}
});
Object.keys(recordData.DescriptionHash).forEach(function (key) {
const value = recordData.DescriptionHash[key];
if (partsData[key]) {
partsData[key].Data = value;
}
});
Object.keys(recordData.NumHash).forEach(function (key) {
const value = recordData.NumHash[key];
if (partsData[key]) {
partsData[key].Data = value;
}
});
console.log('部材リストのデータ:', partsData);
$p.set($('#Results_DescriptionX'), JSON.stringify(partsData));
//部材リストの値を設定
$p.set($('#Results_Class071'), recordData.Status || ''); //問合せ有無
$p.set($('#Results_Class072'), recordData.ClassHash.ClassE || ''); //算出方法
$p.set($('#Results_Class073'), recordData.ClassHash.ClassV || ''); //対象エリア
$p.set($('#Results_Class074'), recordData.ClassHash.ClassW || ''); //対象ブランド
$p.set($('#Results_Description071'), recordData.DescriptionHash.DescriptionA || ''); //注記
$p.set($('#Results_Description072'), ''); //単価表と販売算出表のデータは後で取得するので空にしておく
$p.set($('#Results_Description073'), ''); //カタログ1,2とNotePM1,2,3のデータは後で取得するので空にしておく
$p.set($('#Results_Description074'), ''); //販売価格
$p.set($('#Results_Description075'), ''); //送料
const tankaData = await $p.ex.getRecordData(recordData.ClassHash.Class001);
const hanbaiData = await $p.ex.getRecordData(recordData.ClassHash.Class002);
const catalog1Data = await $p.ex.getRecordData(recordData.ClassHash.Class003);
const catalog2Data = await $p.ex.getRecordData(recordData.ClassHash.Class004);
const notePM1Data = await $p.ex.getRecordData(recordData.ClassHash.Class005);
const notePM2Data = await $p.ex.getRecordData(recordData.ClassHash.Class006);
const notePM3Data = await $p.ex.getRecordData(recordData.ClassHash.Class007);
//取得した各データをconsoleに出力
let desc072data = [];
console.log('単価表のデータ:', Object.keys(tankaData).length === 0 ? 'データなし' : tankaData);
if (Object.keys(tankaData).length > 0) {
let attachmentsHash = tankaData.AttachmentsHash;
let fileList = attachmentsHash.AttachmentsA;
fileList.length > 0 && desc072data.push('▶単価表');
for (let i = 0; i < fileList.length; i++) {
let file = fileList[i];
let fileName = file.Name;
let guid = file.Guid;
let url = 'https://' + location.hostname + '/pleasanter/binaries/' + guid + '/download';
let link = `[${fileName}](${url})`;
desc072data.push(link);
}
}
console.log('販売算出表のデータ:', Object.keys(hanbaiData).length === 0 ? 'データなし' : hanbaiData);
if (Object.keys(hanbaiData).length > 0) {
let attachmentsHash = hanbaiData.AttachmentsHash;
let fileList = attachmentsHash.AttachmentsA;
fileList.length > 0 && desc072data.push('▶販売算出表');
for (let i = 0; i < fileList.length; i++) {
let file = fileList[i];
let fileName = file.Name;
let guid = file.Guid;
let url = 'https://' + location.hostname + '/pleasanter/binaries/' + guid + '/download';
let link = `[${fileName}](${url})`;
desc072data.push(link);
}
}
let desc072 = desc072data.join('\n');
$p.set($('#Results_Description072'), desc072);
//カタログ1,2, NotePM1,2,3のデータを取得
let desc073data = [];
console.log('カタログ1のデータ:', Object.keys(catalog1Data).length === 0 ? 'データなし' : catalog1Data);
if (Object.keys(catalog1Data).length > 0) {
if (catalog1Data.Body) {
desc073data.push('▶カタログ1');
desc073data.push(catalog1Data.Body);
}
}
console.log('カタログ2のデータ:', Object.keys(catalog2Data).length === 0 ? 'データなし' : catalog2Data);
if (Object.keys(catalog2Data).length > 0) {
if (catalog2Data.Body) {
desc073data.push('▶カタログ2');
desc073data.push(catalog2Data.Body);
}
}
console.log('NotePM1のデータ:', Object.keys(notePM1Data).length === 0 ? 'データなし' : notePM1Data);
if (Object.keys(notePM1Data).length > 0) {
if (notePM1Data.Body) {
desc073data.push('▶NotePM1');
desc073data.push(notePM1Data.Body);
}
}
console.log('NotePM2のデータ:', Object.keys(notePM2Data).length === 0 ? 'データなし' : notePM2Data);
if (Object.keys(notePM2Data).length > 0) {
if (notePM2Data.Body) {
desc073data.push('▶NotePM2');
desc073data.push(notePM2Data.Body);
}
}
console.log('NotePM3のデータ:', Object.keys(notePM3Data).length === 0 ? 'データなし' : notePM3Data);
if (Object.keys(notePM3Data).length > 0) {
if (notePM3Data.Body) {
desc073data.push('▶NotePM3');
desc073data.push(notePM3Data.Body);
}
}
let desc073 = desc073data.join('\n');
$p.set($('#Results_Description073'), desc073);
//販売価格と送料のデータを取得
if (partsData.NumA.Data) {
//販売価格と販売単位を結合して表示
let price = partsData.NumA.Data ? partsData.NumA.Data.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') : '';
let unit = partsData.ClassP.Data ? partsData.ClassP.Data : '';
let priceUnit = '¥ ' + price + ' ' + unit;
$p.set($('#Results_Description074'), priceUnit);
}
if (partsData.NumB.Data) {
//送料と単位を結合して表示
let shipping = partsData.NumB.Data ? partsData.NumB.Data.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') : '';
let shippingUnit = partsData.ClassQ.Data ? partsData.ClassQ.Data : '';
let shippingUnitStr = '¥ ' + shipping + ' ' + shippingUnit;
$p.set($('#Results_Description075'), shippingUnitStr);
}
$p.ex.checkAreaAndBrand();
//部材リストの内容によって表示内容を修正する
$p.ex.changeIraiPage();
}
$p.ex.clearPartsData = function () {
//部材リストのデータの初期化
//部材リストのデータの初期化
partsData = {
"Status": { "Label": "問合せ有無", "Data": "" },
"Comments": { "Label": "改訂履歴", "Data": "" },
"ClassA": { "Label": "大分類", "Data": "" },
"ClassB": { "Label": "中分類", "Data": "" },
"ClassC": { "Label": "小分類", "Data": "" },
"ClassD": { "Label": "メーカー", "Data": "" },
"ClassE": { "Label": "算出方法", "Data": "" },
"ClassI": { "Label": "品名/シリーズ", "Data": "" },
"ClassJ": { "Label": "品番/コード", "Data": "" },
"ClassK": { "Label": "タイプ/クラス/パターン", "Data": "" },
"ClassL": { "Label": "サイズ", "Data": "" },
"ClassM": { "Label": "追加・差額", "Data": "" },
"ClassP": { "Label": "販売単位", "Data": "" },
"ClassQ": { "Label": "単位", "Data": "" },
"ClassV": { "Label": "対象エリア", "Data": "" }, //*
"ClassW": { "Label": "対象ブランド", "Data": "" }, //*
"Class001": { "Label": "単価表", "Data": "" }, //*
"Class002": { "Label": "販売算出表", "Data": "" }, //*
"Class003": { "Label": "カタログ1", "Data": "" }, //*
"Class004": { "Label": "カタログ2", "Data": "" }, //*
"Class005": { "Label": "NotePM1", "Data": "" }, //*
"Class006": { "Label": "NotePM2", "Data": "" }, //*
"Class007": { "Label": "NotePM3", "Data": "" }, //*
"NumA": { "Label": "販売価格", "Data": "" },
"NumB": { "Label": "送料", "Data": "" },
"DescriptionA": { "Label": "注記", "Data": "" }, //*
"DescriptionB": { "Label": "URL", "Data": "" },
"Description001": { "Label": "検索キーワード", "Data": "" },
"CheckA": { "Label": "注記有", "Data": "" },
"CheckI": { "Label": "全エリア", "Data": "" },
"CheckJ": { "Label": "全ブランド", "Data": "" },
"Check001": { "Label": "東京", "Data": "" },
"Check002": { "Label": "愛知", "Data": "" },
"Check003": { "Label": "千葉", "Data": "" },
"Check004": { "Label": "静岡", "Data": "" },
"Check005": { "Label": "熊本", "Data": "" },
"Check011": { "Label": "actie", "Data": "" },
"Check012": { "Label": "nexthouse", "Data": "" },
"Check013": { "Label": "ACTIVEHOUSE", "Data": "" },
"Check014": { "Label": "Bluezia", "Data": "" },
"Check015": { "Label": "CLEVERLYHOME", "Data": "" },
"Check016": { "Label": "WELLHOMES", "Data": "" },
"Check017": { "Label": "はちみつハウス", "Data": "" },
"Check018": { "Label": "GRAPH", "Data": "" },
}
$p.set($('#Results_DescriptionX'), JSON.stringify(partsData));
//部材リストの値を空にする
$p.set($('#Results_Class071'), '');
$p.set($('#Results_Class072'), '');
$p.set($('#Results_Class073'), '');
$p.set($('#Results_Class074'), '');
$p.set($('#Results_Description071'), '');
$p.set($('#Results_Description072'), '');
$p.set($('#Results_Description073'), '');
$p.set($('#Results_Description074'), '');
$p.set($('#Results_Description075'), '');
}
//Class011とClass012に表示されているテキスト情報を取得し、Class0073のなかの配列とClass074の中の配列にそれぞれ値が含まれているか確認する関数
$p.ex.checkAreaAndBrand = function () {
//Class011とClass012の値を取得
let areaData = $('#Results_Class011 option:selected').text();
let brandData = $('#Results_Class012 option:selected').text();
//Class073とClass074の値を取得
let areaList = $('#Results_Class073').val();
let brandList = $('#Results_Class074').val();
let brandDataConvert = convertAreaData(brandData);
//$p.clearMessage();
//一致するエリアがある場合は青文字で表示し、一致しない場合はエリア不一致と赤文字で表示
let areaListStr = $('#Results_Class073_ms span').eq(2).html();
if (areaList.includes(areaData)) {
//$p.ex.setMyMessage('alert-success', 'エリア一致', 0);
areaListStr = areaListStr.replaceAll(areaData, `<span style="font-size:1.2em; font-weight:bold; color:blue; ">${areaData}</span>`);
} else {
//$p.ex.setMyMessage('alert-danger', 'エリア不一致', 0);
areaListStr = '<span style="font-size:1.2em; font-weight:bold; color:red; ">一致エリア無し</span>, ' + areaListStr;
}
$('#Results_Class073_ms span').eq(2).html(areaListStr);
//一致するブランドがある場合は青文字で表示し、一致しない場合はブランド不一致と赤文字で表示
let brandListStr = $('#Results_Class074_ms span').eq(2).html();
if (brandList.includes(brandDataConvert)) {
//$p.ex.setMyMessage('alert-success', 'ブランド一致', 0);
brandListStr = brandListStr.replaceAll(brandDataConvert, `<span style="font-size:1.2em; font-weight:bold; color:blue; ">${brandDataConvert}</span>`);
} else {
//$p.ex.setMyMessage('alert-danger', 'ブランド不一致', 0);
brandListStr = '<span style="font-size:1.2em; font-weight:bold; color:red; ">一致ブランド無し</span>, ' + brandListStr;
}
$('#Results_Class074_ms span').eq(2).html(brandListStr);
}
//MSSと積算のエリアデータの整合性
function convertAreaData(areaData) {
const areaMap = {
'actie': 'actie',
'nexthouse': 'nexthouse',
'アクティブハウス': 'ACTIVE HOUSE',
'ブルージア': 'Bluezia',
'クレバリーホーム': 'CLEVERLY HOME',
'WELLHOMES': 'WELLHOMES',
'Graph': 'GRAPH',
'nexthouse VALUE': 'nexthouse',
'one-happy': 'nexthouse',
'niko and ... EDIT HOUSE': 'none',
'RCnext': 'none',
'リフォームラボ': 'none',
'君津住宅': 'none',
'特建事業部': 'none',
'不動産・建売・モデルハウス': 'none'
};
return areaMap[areaData] !== undefined ? areaMap[areaData] : 'none';
}
$p.ex.changeIraiPage = function () {
console.log('依頼項目の表示内容を変更します');
//部材リストが選択されていたら部材データの欄は表示しておく
let class042 = $('#Results_Class042').val();
if (class042) {
$('#SectionFields17Container').show();
//$('#SectionFields2Container').hide(); //依頼項目の非表示
//$('#SectionFields4Container').hide(); //不備追加資料の非表示
} else {
$('#SectionFields17Container').hide();
//$('#SectionFields2Container').show(); //依頼項目の表示
//$('#SectionFields4Container').show(); //不備追加資料の表示
}
//部材リストから取得したデータを分析 Class071 Class072 のデータ
let class071 = $('#Results_Class071').val(); //問合せ有無
let class072 = $('#Results_Class072').val(); //算出方法
let status = $('#Results_Status').val();
// Results_CheckA のチェック状態を取得
if ($('#Results_CheckA').prop('checked')) {
class071 = '150'; //問合せ有無を「必要」に設定
}
switch (class071) {//問合せ有無 必要,不要,保留,使用不可
/*
case '': //未選択
$('#SectionFields19Container').show();
$p.ex.clearIraiItems();
$('#SectionFields2Container').hide(); //依頼項目の非表示
$('#SectionFields4Container').hide(); //不備追加資料の非表示
break;
*/
case '150': //必要
$('li[aria-controls="FieldSetTab2"]').show(); //算出回答タブの表示
$('li[aria-controls="FieldSetTab3"]').show(); //質疑応答タブの表示
$('li[aria-controls="FieldSetTab4"]').show(); //営業積算課タブの表示
$('li[aria-controls="FieldSetTab5"]').show(); //積算発注かタブの表示
$('#SectionFields17Container').hide(); //部材リストのデータを非表示
$('#SectionFields19Container').hide();
$('#SectionFields2Container').show(); //依頼項目の表示
$('#SectionFields4Container').show(); //不備追加資料の表示
break;
case '900': //不要
case '910': //保留
case '920': //使用不可
//積算見積もり依頼は不要なので、営業積算項目以降のタブを非表示にする
$('li[aria-controls="FieldSetTab2"]').hide(); //算出回答タブの非表示
$('li[aria-controls="FieldSetTab3"]').hide(); //質疑応答タブの非表示
$('li[aria-controls="FieldSetTab4"]').hide(); //営業積算課タブの非表示
$('li[aria-controls="FieldSetTab5"]').hide(); //積算発注かタブの非表示
$('#SectionFields19Container').hide();
$('#SectionFields17Container').show(); //部材リストのデータを表示
$p.ex.clearIraiItems();
$('#SectionFields2Container').hide(); //依頼項目の非表示
$('#SectionFields4Container').hide(); //不備追加資料の非表示
//ステータスを「依頼済み」に変更
status != '902' && $p.set($('#Results_Status'), '902');
break;
}
}
/**
* #Results_Class058Field をクリックすると2つの0.5単位入力欄とマーク付きモーダルを表示し
* モーダル外クリックで2つの値をで連結して #Results_Class058 に保存する
*/
function showMatrixSizeModal() {
// 既存モーダルがあれば削除
$('#matrixSizeModal').remove();
// スクロール抑制
$('body').css('overflow', 'hidden');
// #Results_Class058Field の位置取得
const offset = $('#Results_Class058').offset();
const width = $('#Results_Class058').outerWidth();
// モーダルHTML
const modalHtml = `
<div id="matrixSizeModal" style="
position: absolute;
top: ${offset.top}px;
left: ${offset.left}px;
width: ${width}px;
background: #fff;
border: 2px solid #888;
border-radius: 8px;
box-shadow: 0 4px 4px rgba(0,0,0,0.2);
padding: 4px;
z-index: 9999;
text-align: center;
align-items: center;
gap: 8px;
">
<input type="number" id="matrixInput1" step="0.5" min="0" class="matrix-input" autocomplete="off">
<span style="font-size:1em; font-weight:bold;"></span>
<input type="number" id="matrixInput2" step="0.5" min="0" class="matrix-input" autocomplete="off">
</div>
`;
$('body').append(modalHtml);
// 既存値があれば分割してセット
const current = $('#Results_Class058').val();
if (current && current.includes('✕')) {
const [v1, v2] = current.split('✕').map(s => s.trim());
$('#matrixInput1').val(v1);
$('#matrixInput2').val(v2);
}
// モーダルを開いたら #matrixInput1 にフォーカス
$('#matrixInput1').focus();
// モーダル外クリックで保存&モーダル削除
setTimeout(() => {
$(document).on('mousedown.matrixModal', function (e) {
if (!$(e.target).closest('#matrixSizeModal, #Results_Class058Field').length) {
const val1 = $('#matrixInput1').val();
const val2 = $('#matrixInput2').val();
let result = '';
if (val1 && val2) {
result = `${val1}${val2}`;
} else if (val1) {
result = val1;
} else if (val2) {
result = val2;
}
$p.set($('#Results_Class058'), result);
$('#matrixSizeModal').remove();
// スクロール抑制解除
$('body').css('overflow', '');
$(document).off('mousedown.matrixModal');
}
});
}, 10);
}
//Results_Class058 onfocusイベント
$('#Results_Class058').on('focus', function () {
showMatrixSizeModal();
});
/**
* 指定したIDの<select>タグにプレースホルダー的な<option>を挿入する関数
* @param {string} selectId - <select>タグのID
*/
function addPlaceholderOption(selectId) {
//値が空の場合、プレースホルダー的なoptionを追加
const val = $(`#${selectId}`).val();
if (!val) {
//つ目のoptionのテキストを変更
$(`#${selectId} option:first`).text('次から選択してください');
}
//console.log($(`#${selectId}`));
}

View File

@ -0,0 +1,18 @@
/*
@config :next999.json
@filename : ${psFileBasename}
@title : 06_算出回答処理スクリプト
@name :
@siteIds : 310405
@siteTitles : Re③依頼項目
@disabled: true
*/
$p.ex.resultAnswer = function () {
//算出・回答 Results_Description111
//別途費用・伝達事項 Results_Description112
//算出者 Results_Class113
//算出bi Results_Date110
//
}

View File

@ -0,0 +1,36 @@
// LINE WORKSのBot APIを使って特定ユーザーにメッセージを送信するサンプルブラウザJS
// ※実際の運用ではアクセストークンの安全な管理やCORS制約のため、サーバー経由での実装が推奨されます
async function sendLineworksMessage(userId, messageText) {
const accessToken = 'OZ/7AjHT1H7B1zInX5nQEsssQ+0OZF';
//const apiUrl = 'https://apis.worksmobile.com/r/{API_ID}/message/v1/bot/{BOT_NO}/message/push'; // {API_ID}と{BOT_NO}は自身の値に置換
const botId = '10130468';
//const userId = 'k.nogi@works-nextgroup2';
const apiUrl = `https://www.worksapis.com/v1.0/bots/${botId}/users/${userId}/messages`;
const body = {
content: {
type: 'text',
text: messageText
}
};
const response = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'Authorization': `Bearer ${accessToken}`
},
body: JSON.stringify(body)
});
if (response.ok) {
console.log('送信成功', await response.json());
} else {
console.error('送信失敗', await response.text());
}
}
// 使用例
// sendLineworksMessage('user@example.com', 'こんにちはLINE WORKS Botからのメッセージです。');

View File

@ -0,0 +1,153 @@
/*
@config :next999.json
@filename : ${psFileBasename}
@title : 200.添付ファイル一括取得スクリプト
@name :
@siteIds : 310405
@siteTitles : Re③依頼項目
@disabled: false
*/
$p.ex.createDownloadCheckBox = function (attachId) {
let attachName = $('#Results_' + attachId + 'Field label')[0].innerHTML;
let items = JSON.parse($('#Results_' + attachId).val());
if (items.length > 0) {
//保存されているアイテムにチェックボックスを追加
for (let item of items) {
let checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.style.margin = '2px';
checkbox.style.float = 'left';
checkbox.name = attachId + '_checkbox';
checkbox.id = item.Guid + '_checkbox';
checkbox.value = item.Guid;
$('#' + item.Guid).prepend(checkbox);
}
let zipFilename = attachName;
//ダウンロードボタンを追加
//ダウンロードボタン
let div = document.createElement('div');
div.style.margin = '0px 5px 10px 120px';
div.style.clear = 'both';
let dlButton1 = document.createElement('button');
dlButton1.id = attachId + '_dlButton1';
dlButton1.style.marginRight = '5px';
dlButton1.innerHTML = '全ファイルDL';
dlButton1.setAttribute('attach', attachId);
dlButton1.setAttribute('onclick', '$p.ex.dlAllFiles("' + attachId + '","' + zipFilename + '■全ファイルDL' + '")');
div.append(dlButton1);
if (items.length > 1) {
let dlButton2 = document.createElement('button');
dlButton2.id = attachId + '_dlButton2';
dlButton2.style.marginRight = '5px';
dlButton2.innerHTML = '選択DL';
dlButton2.setAttribute('attach', attachId);
dlButton2.setAttribute('onclick', '$p.ex.dlSelectedFiles("' + attachId + '","' + zipFilename + '■選択DL' + '")');
div.append(dlButton2);
}
//設置
$('#Results_' + attachId + 'Field').after(div);
//jQuery UIボタン化
$('#' + attachId + '_dlButton1').button({
icon: 'ui-icon-document'
});
if (items.length > 1) {
$('#' + attachId + '_dlButton2').button({
icon: 'ui-icon-document'
});
}
}
}
$p.ex.dlSelectedFiles = function (attachId, zipFilename) {
//チェックがついているもののみ
const fileList = $('input[name="' + attachId + '_checkbox"]:checked');
let guidList = new Array();
for (item of fileList) {
console.log(item);
guidList.push(item.value);
}
if (guidList.length > 0) {
dlZipAttachements(guidList, zipFilename);
}
}
$p.ex.dlAllFiles = function (attachId, zipFilename) {
let guidList = new Array();
//全部
const fileList = JSON.parse($p.getControl(attachId).val());
for (item of fileList) {
guidList.push(item.Guid);
}
if (guidList.length > 0) {
dlZipAttachements(guidList, zipFilename);
}
}
/**
* 複数ファイルを1ファイルにzip圧縮してDLする
* @param guidList DLする添付ファイルのGUIDのリスト
* @param zipFilename zipファイル名
* @return なし
*/
async function dlZipAttachements(guidList, zipFilename) {
const zip = new JSZip();
const jsonReq = {
'ApiVersion': 1.1,
'ApiKey': apiKey,
};
for (const guid of guidList) {
try {
const response = await fetch(`/pleasanter/api/binaries/${guid}/get`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(jsonReq),
});
if (!response.ok) {
throw new Error(`Failed to fetch file with GUID: ${guid}`);
}
const data = await response.json();
const binary = decodeBase64(data.Response.Base64);
const filename = data.Response.FileName;
zip.folder(zipFilename).file(filename, binary, { binary: true });
} catch (error) {
console.error(`Error fetching file with GUID: ${guid}`, error);
}
}
saveAs(await zip.generateAsync({ type: "blob" }), zipFilename + ".zip");
}
//base64デコード処理
function decodeBase64(base64) {
const bin = atob(base64.replace(/^.*,/, ''));
const buffer = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; i++) {
buffer[i] = bin.charCodeAt(i);
}
return buffer.buffer;
}

View File

@ -0,0 +1,43 @@
/*
@config :next999.json
@filename : ${psFileBasename}
@title : 90_スタートメッセージ表示
@name :
@siteIds : 310405
@siteTitles : Re③依頼項目
@disabled: false
*/
//スタートアップメッセージ表示
$p.ex.startupMessage = function () {
let count = 0;
for (message of messageData) {
//2つ目以降のメッセージの際にクリアフラグを0に設定。
let clearFlag = 0;//count > 0 ? 0 : 1;
$p.ex.setMyMessage(message.colorCode, message.message, clearFlag);
count++;
}
//開いたときに表示するメッセージ一覧
switch ($('#Results_Status').val()) {
case '100': //新規登録
break;
case '200': //登録完了
break;
case '300': //積算依頼
break;
case '400': //積算受付
break;
case '500': //積算対応中
break;
case '800': //一部完了
break;
case '900': //完了
break;
case '910': //保留
break;
case '920': //取消
break;
}
}

View File

@ -0,0 +1,123 @@
/*
@config :next999.json
@filename : ${psFileBasename}
@title : 99_更新履歴保存スクリプト
@name :
@siteIds : 310405
@siteTitles : Re③依頼項目
@disabled: false
*/
//変更内容を保存
$p.ex.saveHistory = function () {
let history = '';
let count = 0;
//履歴に表示しない項目リスト
let excludeList = [
'Results_Timestamp',
'Results_ClassL',
'Results_ClassM',
'Results_ClassN',
'Results_CheckA',
'Results_Class035',
'Results_Class036',
'Results_Class037',
'Results_Class038',
'Results_Class043',
'Results_Class045',
'Results_Class046',
'Results_Class047',
'Results_Class048',
'Results_Class191',
'Results_Class192',
'Results_Class193',
'Results_Class071',
'Results_Class072',
'Results_Class073',
'Results_Class074',
'Results_DescriptionX',
'Results_Description055',
'Results_Description115',
'Results_Description131',
'Results_Attachments131',
'Results_Date131',
'Results_Description132',
'Results_Attachments132',
'Results_Num131',
'Results_Num132',
'Results_Description135',
'Results_Class136',
'Results_Date136',
'Results_Description136',
'Results_Class151',
'Results_Class152',
'Results_Date151',
'Results_Class153',
'Results_Date152',
'Results_Description151',
'Results_Description155',
'Results_NumX',
'Results_NumY',
'Results_Description200'
];
if ($p.data.MainForm) {
$p.set($('#Results_Description200'), '');
history = '◆ 変更内容 ◆\n';
$.each($p.data.MainForm, function (index, val) {
if (index.startsWith('Results')) {
if (!excludeList.includes(index)) {
//項目名の取得
let colName = $('label[for="' + index + '"]').text();
let text;
//セレクトボックス判定
if ($('#' + index + '.control-dropdown').length) {
//セレクトボックス処理
if ($('#' + index).prop("multiple")) {
text = $('#' + index + '_ms span').eq(-1).text();
} else {
text = $('#' + index + ' option:selected').text();
}
} else if ($('#' + index + '.radio-value').length) {
//ラジオボタン処理
text = val != '' ? $('label[for="' + index + val + '"').text() : '';
} else {
//その他
text = val;
}
history += '▷ ' + colName + ' : ' + text + '\n';
count++;
}
}
});
if (count) {
//console.log(history);
$p.set($('#Results_Description200'), history);
$p.set($('#Comments'), history);
}
}
}
//古いコメントを削除するスクリプトを作成予定
$p.ex.deleteOldComments = function () {
$p.apiGet({
'id': $p.id(),
'data': {
'ApiVersion': 1.1,
//'ApiKey': apiKey,
},
'done': function (data) {
//console.log(data.Response.Data[0].Comments);
let comments = JSON.parse(data.Response.Data[0].Comments);
console.log(comments);
console.log(comments.slice(0, 5));
console.log(JSON.stringify(comments));
console.log(JSON.stringify(comments.slice(0, 5)));
}
});
}

View File

@ -0,0 +1,37 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.0/FileSaver.min.js"
integrity="sha512-csNcFYJniKjJxRWRV1R7fvnXrycHP6qDR21mgz1ZP55xY5d+aHLfo9/FcGDQLfn2IfngbAHd8LdfsagcCqgTcQ=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"
integrity="sha512-XMVd28F1oH/O71fzwBnV7HucLxVwtxf26XV8P4wPk26EDxuGZ91N8bsOttmnomcCD3CS5ZMRL50H0GgOHvegtg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, user-scalable=yes">
<title>{{flow_title}}</title>
</head>
<body>
`<table>
<tbody>
{{#messageData}}
<tr>
<td class="shitsugi_type">{{type}}</td>
<td class="shitsugi_userName">{{userName}}</td>
<td class="shitsugi_messageTime">{{messageTime}}</td>
</tr>
<tr>
<td colspan="3" class="shitsugi_messageBody">
<pre class="shitsugi_preWrap">{{{messageBody}}}</pre>
</td>
</tr>
{{/flowArray}}
</tbody>
</table>`;
</body>
</html>

View File

@ -0,0 +1,219 @@
/*
@config :next999.json
@filename : ${psFileBasename}
@title :01.原価閲覧メンバー照会
@name :01.原価閲覧メンバー照会
@siteIds : 310405
@siteTitles : Re③依頼項目
@disabled: false
*/
//原価閲覧メンバーを紹介し、リストを返すサーバースクリプト
try {
if (context.ControlId) {
//自動ポストバック
//context.Log('自動ポストバック: ' + context.ControlId);
let controlIdPrefix = context.ControlId.substring(0, 16);
switch (controlIdPrefix) {
case 'Results_Class045':
//context.Log('Results_Class045の自動ポストバック');
columns.Class035.AddChoiceHash(model.Class045, model.Class045);
context.ResponseSet('Class035', model.Class045); //Class045の値をClass035に設定
//部材リストを読取り専用に設定
columns.Class042.ExtendedFieldCss = 'code-readonly2';
context.ResponseSet('Class042', ''); //Class042を空に設定
break;
case 'Results_Class046':
//context.Log('Results_Class046の自動ポストバック');
columns.Class036.AddChoiceHash(model.Class046, model.Class046);
context.ResponseSet('Class036', model.Class046); //Class045の値をClass035に設定
//部材リストを読取り専用に設定
columns.Class042.ExtendedFieldCss = 'code-readonly2';
context.ResponseSet('Class042', ''); //Class042を空に設定
break;
case 'Results_Class047':
//context.Log('Results_Class047の自動ポストバック');
columns.Class037.AddChoiceHash(model.Class047, model.Class047);
context.ResponseSet('Class037', model.Class047); //Class047の値をClass037に設定
//部材リストを読取り専用に設定
columns.Class042.ExtendedFieldCss = 'code-readonly2';
context.ResponseSet('Class042', ''); //Class042を空に設定
break;
case 'Results_Class048':
//context.Log('Results_Class048の自動ポストバック');
columns.Class038.AddChoiceHash(model.Class048, model.Class048);
context.ResponseSet('Class038', model.Class048); //Class048の値をClass038に設定
//部材リストを読取り専用に設定
//columns.Class042.ExtendedFieldCss = 'code-readonly2';
context.ResponseSet('Class042', ''); //Class042を空に設定
break;
}
//自動ポストバックの処理はここで終了
} else {
//部材リストを読取り専用に設定
columns.Class042.ExtendedFieldCss = 'code-readonly2';
//【営業積算】原価閲覧グループ 63 のメンバーを取得
getSekisanMenberList();
//全従業員グループ 27 のメンバーを取得
getUserList();
//マスターシートからデータを取得し、一部を格納する
getMSSdata();
//メッセージデータを取得
getMessageData();
}
} catch (error) {
context.Log(error);
}
function getMSSdata() {
try {
let mssDataId = model.ClassY;
if (!mssDataId) {
//context.Log('マスターシートのデータIDが設定されていません。');
return;
} else {
context.Log(`マスターシートのデータID: ${mssDataId}`);
let records = items.Get(mssDataId);
hidden.Add('mssData_Brand', records[0].Class033);
hidden.Add('mssData_Series', records[0].Class035);
}
} catch (error) {
context.Log(error);
}
}
function getSekisanMenberList() {
try {
//【営業積算】原価閲覧グループ 63 のメンバーを取得
let group = groups.Get(63);
let memberIds = []
let deptIds = []
for (let member of group.GetMembers()) {
if (member.UserId == 0) {
deptIds.push(member.DeptId);
} else {
memberIds.push(member.UserId);
}
//context.Log(`${member.DeptId},${member.UserId}`);
}
//【営業積算】原価閲覧グループの組織とメンバーをHTML隠し要素に出力
hidden.Add('sekisanMemberList', JSON.stringify(memberIds));
hidden.Add('sekisanDeptList', JSON.stringify(deptIds));
} catch (error) {
context.Log(error);
}
}
//ユーザー情報をHTML内に格納する関数
function getUserList() {
try {
//---------------------------------------------------------------------
group = groups.Get(27); //全従業員グループ27
let userList = {};
//ユーザー情報を取得してリストを作成
for (let member of group.GetMembers()) {
//ユーザー情報情報取得
let user = users.Get(member.UserId);
let rows = extendedSql.ExecuteTable('GetUserMailAddresses', '{"OwnerId": ' + user.UserId + '}');
let mailAddrs = [];
for (let row of rows) {
mailAddrs.push(row.MailAddress);
}
let dept = depts.Get(user.DeptId);
let deptName = dept ? dept.DeptName : '';
userList[user.UserId] = {
userId: user.UserId,
name: user.Name,
deptId: user.DeptId,
deptName: deptName,
mailAddresses: mailAddrs.join(','),
//deptName: dept.Name
}
}
//context.Log(`ユーザーリスト: ${JSON.stringify(userList)}`);
// ユーザーリストをHTML隠し要素に出力
hidden.Add('userList', JSON.stringify(userList));
} catch (error) {
context.Log(error);
}
}
//メッセージデータ取得
function getMessageData() {
//メッセージデータを取得
let data = {
"View": {
"ColumnFilterHash": {
"ClassA": "[\"" + model.SiteId + "\"]",
"ClassB": model.Status
},
"ColumnSorterHash": {
"ClassA": "asc",
"ClassB": "asc",
"NumA": "asc"
}
}
}
let results = items.Get(326371, JSON.stringify(data));
if (results.length === 0) {
//context.Log('メッセージデータが見つかりませんでした。');
return;
}
let messageData = []
for (let item of results) {
const status = item.ClassB;
const colorCode = item.ClassC;
const message = item.ClassD;
messageData.push({
"status": status,
"colorCode": colorCode,
"message": message,
});
}
//取得したメッセージデータをhiddenに格納
if (messageData.length > 0) {
hidden.Add('messageData', JSON.stringify(messageData));
} else {
//context.Log('メッセージデータが見つかりませんでした。');
}
}

View File

@ -0,0 +1,33 @@
function getUserList() {
try {
//---------------------------------------------------------------------
group = groups.Get(27); //全従業員グループ27
let userList = {};
//ユーザー情報を取得してリストを作成
for (let member of group.GetMembers()) {
//ユーザー情報情報取得
let user = users.Get(member.UserId);
let dept = depts.Get(user.DeptId);
//let dept = depts.Get(user.DeptId);
context.Log(`ユーザーID: ${user.UserId}, 名前: ${user.Name}, 部署ID: ${user.DeptId}, 部署名: ${dept.DeptName}`);
userList[user.UserId] = {
userId: user.UserId,
name: user.Name,
deptId: user.DeptId,
deptName: dept.DeptName
}
}
//context.Log(`ユーザーリスト: ${JSON.stringify(userList)}`);
// ユーザーリストをHTML隠し要素に出力
hidden.Add('userList', JSON.stringify(userList));
} catch (error) {
context.Log(error);
}
}
getUserList();

View File

@ -0,0 +1,134 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 01_読み取り専用スタイル
@name
@siteIds : 310405
@siteTitles : Re依頼項目
@disabled: false
*/
label.error {
pointer-events: none;
z-index: 100;
border-top: none !important;
}
.code-readonly {
pointer-events: none;
background-color: lightgrey;
font-weight: bold;
}
.code-readonly2,
.code-readonly2+button,
.code-readonly2+div.ui-icon,
.code-readonly3,
.code-readonly3+button,
.code-readonly3+div.ui-icon {
font-weight: bold;
&:active {
pointer-events: none;
}
a:not(.ui-spinner-button) {
pointer-events: auto;
}
}
.code-readonly2 select,
.code-readonly2 input,
.code-readonly2 button.ui-multiselect,
.code-readonly2 .control-markup,
.code-readonly2 .ui-spinner,
span[data-readonly="1"] {
pointer-events: none;
border: dashed 1px black !important;
background-color: lightgray !important;
color: black !important;
.ui-spinner-input {
border: none;
}
}
.code-readonly3 select,
.code-readonly3 input,
.code-readonly3 button.ui-multiselect,
.code-readonly3 .control-markup,
.code-readonly3 .ui-spinner {
pointer-events: none;
border: dashed 1px black !important;
.ui-spinner-input {
border: none;
}
}
.code-readonly2,
.code-readonly3,
.field-normal:has(span[data-readonly="1"]),
.field-wide:has(span[data-readonly="1"]) {
position: relative;
&:hover::after {
content: "読取り専用です";
position: absolute;
left: 120px;
top: calc(100% - 9px);
margin-top: 4px;
background: #00000080;
color: #fff;
padding: 4px 10px;
border-radius: 4px;
font-size: 12px;
font-weight: normal !important;
pointer-events: none;
z-index: 9999;
white-space: nowrap;
}
}
.code-required,
select[data-validate-required="1"],
input[data-validate-required="1"] {
border: double 3px red !important;
&+button.ui-multiselect {
border: double 3px red !important;
}
}
.field-normal:has(.code-required),
.field-wide:has(.code-required),
.field-normal:has(select[data-validate-required="1"]),
.field-wide:has(select[data-validate-required="1"]),
.field-normal:has(input[data-validate-required="1"]),
.field-wide:has(input[data-validate-required="1"]) {
position: relative;
&:hover::after {
content: "入力必須です";
position: absolute;
left: 120px;
top: calc(100% - 9px);
margin-top: 4px;
background: #ff000080;
color: #fff;
padding: 4px 10px;
border-radius: 4px;
font-size: 12px;
font-weight: normal !important;
pointer-events: none;
z-index: 9999;
white-space: nowrap;
}
}
.error {
border: double 3px red !important;
}

View File

@ -0,0 +1,30 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 02_共通スタイル
@name
@siteIds : 310405
@siteTitles : Re依頼項目
@disabled: false
*/
/*見出しサイズ*/
.field-section {
font-size: 1.5em !important;
font-weight: bold !important;
height: auto;
}
/*項目の後ろの行間を少し狭める*/
.field-normal {
height: 35px;
}
.field-wide {
min-height: 35px;
padding: 0 10px 5px 0;
}
/*コメントのある項目の高さだけ少し広げる*/
div:has(.commentAdd).field-normal {
height: 50px;
}

View File

@ -0,0 +1,14 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 03_プロセスボタン表示調整
@name
@siteIds : 310405
@siteTitles : Re依頼項目
@disabled: false
*/
.processButtonSize {
font-size: 1.2em !important;
font-weight: bold !important;
}

View File

@ -0,0 +1,94 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 04_質疑回答テーブル
@name
@siteIds : 310405
@siteTitles : Re依頼項目
@disabled: false
*/
#messageTable {
width: 98%;
margin: 8px;
border-collapse: separate !important;
}
.radius-table {
border-radius: 10px !important;
border-spacing: 0;
border: none;
border-left: 1px solid #999;
border-top: 1px solid #999;
}
.radius-table tr>* {
padding: 5px 10px;
border: none;
border-right: 1px solid #999;
border-bottom: 1px solid #999;
}
.radius-table tr:first-child>*:first-child {
border-radius: 10px 0 0 0;
}
.radius-table tr:first-child>*:last-child {
border-radius: 0 10px 0 0;
}
.radius-table tr:last-child>*:first-child {
border-radius: 0 0 0 10px;
}
.radius-table tr:last-child>*:last-child {
border-radius: 0 0 10px 0;
}
.Question>td {
background-color: coral;
vertical-align: middle;
}
.Question\.Disabled>td,
.Answer\.Disabled>td {
background-color: grey !important;
}
.Answer>td {
background-color: yellow;
vertical-align: middle;
}
.shitsugi_type {
font-weight: bold;
font-size: 1.5em;
}
.shitsugi_userName {
text-align: center;
width: 150px;
font-size: 1.2em;
}
.shitsugi_messageTime {
text-align: right;
font-size: 1.2em;
}
.shitsugi_messageBody {
background-color: white !important;
}
.shitsugi_deleteCheck {
background-color: white !important;
text-align: center;
width: 80px;
}
.shitsugi_preWrap {
white-space: pre-wrap;
text-overflow: ellipsis;
break-inside: avoid;
}

View File

@ -0,0 +1,171 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 05_項目のサイズ変更
@name
@siteIds : 310405
@siteTitles : Re依頼項目
@disabled: false
*/
.control-markup {
background: white !important;
}
#Results_Description071\.viewer,
#Results_Description072\.viewer,
#Results_Description073\.viewer,
#Results_Description074\.viewer,
#Results_Description075\.viewer {
min-height: auto !important;
}
#Results_Description074\.viewer,
label[for="Results_Description074"] {
font-size: 1.5em !important;
font-weight: bold !important;
span {
font-weight: bold !important;
}
}
#Results_Description075\.viewer,
label[for="Results_Description075"] {
font-size: 1.3em !important;
font-weight: bold !important;
span {
font-weight: bold !important;
}
}
#Results_ClassC {
width: 230px;
}
#Results_ClassC,
label[for="Results_ClassC"] {
font-size: 1.5em !important;
font-weight: bold !important;
height: 2.2em !important;
}
#Results_Class041 {
width: 330px;
}
#Results_Class041,
label[for="Results_Class041"] {
font-size: 1.5em !important;
font-weight: bold !important;
height: 2.2em !important;
}
#Results_Class041Field {
height: 60px !important;
}
label[for="Results_ClassO"],
label[for="Results_ClassP"],
label[for="Results_ClassQ"],
label[for="Results_DescriptionO"] {
font-size: 1.2em !important;
font-weight: bold !important;
}
.container-radio label {
font-size: 1.2em !important;
font-weight: bold !important;
}
label[for="Results_DateJ"] {
font-weight: bold;
color: red;
}
#Results_DateI {
font-weight: bold;
font-size: 1.2em;
background-color: lightblue;
}
#Results_DateJ {
font-weight: bold;
font-size: 1.2em;
background-color: red !important;
color: white !important;
}
.dateI_alert {
background-color: red !important;
color: white !important;
}
#Results_DescriptionOField {
margin-bottom: 10px;
}
a[href="#FieldSetTab4"] {
background-color: purple;
color: white !important;
}
a[href="#FieldSetTab5"] {
background-color: darkgreen;
color: white !important;
}
#Results_Class012 {
background-color: lightyellow;
border: 2px solid red;
}
.matrix-input {
margin: 0px;
padding: 0px;
width: 60px;
text-align: center;
}
p.field-label>label {
white-space: nowrap;
overflow: hidden;
}
.buzaiComment {
font-size: 0.9em !important;
font-weight: bold !important;
color: white !important;
background-color: black !important;
width: 30%;
display: inline-block;
padding: 10px;
border-radius: 10px;
}
.brandComment {
font-size: 0.9em !important;
font-weight: bold !important;
color: white !important;
background-color: black !important;
width: 30%;
display: inline-block;
float: left;
padding: 10px;
border-radius: 10px;
}
.commentAdd2 {
font-size: 0.7em;
font-weight: bold;
color: red;
margin-left: 10px;
}
.commentAdd3 {
font-size: 0.7em;
font-weight: bold;
color: blue;
margin-left: 10px;
}

View File

@ -0,0 +1,4 @@
{
"apiKey": "c38903157cbffc30961f50bc29d0991a6cd8af495ab3009b05c5f98e82b2e61b94ba2d5c0a48fc518b1cd74c9e427b01051a228f670f3c5282544dfbec93db87",
"url": "https://neo999.next-hd.net/pleasanter/"
}

View File

@ -0,0 +1,207 @@
/**
* canvasJs
*/
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
const clearButton = document.getElementById("clear");
const saveButton = document.getElementById('saveSign');
let isDragging = false;
let lastPosition = {
x: null,
y: null
};
/**
* 描画処理
*/
function draw(x, y) {
if (!isDragging) {
return;
}
// 線端の形状, 太さ, 色
context.lineCap = "round";
context.lineWidth = 3;
context.strokeStyle = "black";
if (lastPosition.x === null || lastPosition.y === null) {
context.moveTo(x, y);
} else {
context.moveTo(lastPosition.x, lastPosition.y);
}
context.lineTo(x, y);
context.stroke();
// 座標保持
lastPosition.x = x;
lastPosition.y = y;
}
/**
* 描画の開始
*/
function dragStart(event) {
context.beginPath();
isDragging = true;
}
/**
* 描画の終了
*/
function dragEnd(event) {
context.closePath();
isDragging = false;
// 座標リセット
lastPosition.x = null;
lastPosition.y = null;
}
/**
* 描画の削除
*/
function clear() {
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "#FFFFFF"; //筆に白い絵の具をつけて
context.fillRect(0, 0, 800, 200); //四角を描く
}
/**
* イベント定義
*/
function init() {
clear();
// PC用
canvas.addEventListener("mousedown", dragStart);
canvas.addEventListener("mouseup", dragEnd);
canvas.addEventListener("mouseout", dragEnd);
canvas.addEventListener("mousemove", (e) => {
//console.log(canvas.getBoundingClientRect().top);
draw(
e.layerX - canvas.getBoundingClientRect().left + 4,
e.layerY - canvas.getBoundingClientRect().top + 130
);
});
// SP用
canvas.addEventListener("touchstart", dragStart);
canvas.addEventListener("touchcancel", dragEnd);
canvas.addEventListener("touchend", dragEnd);
canvas.addEventListener("touchmove", (e) => {
// 描きづらいのでスワイプさせない
e.preventDefault();
let x = e.touches[0].clientX - canvas.getBoundingClientRect().left;
let y = e.touches[0].clientY - canvas.getBoundingClientRect().top;
draw(x, y);
});
// リセット
clearButton.addEventListener("click", clear);
saveButton.addEventListener('click', saveSign);
}
function saveSign() {
let base64 = canvas.toDataURL('image/png');
/*
console.log(base64);
$p.apiCreate({
"id": $p.id(),
"data": {
"ApiVersion": 1.1,
"Title": "署名",
"AttachmentHash": {
"AttachmentA": {
"ContentType": "image/png",
"Name": "署名.txt",
"Base64": base64
}
}
},
"done": function (data) {
console.log(data);
},
"fail": function (data) {
console.log(data);
},
"always": function (data) {
console.log(data);
}
});
*/
// Canvas から Blob オブジェクトを生成
canvas.toBlob(async (blob) => {
// 画像データをクリップボードに書き込む
const item = new ClipboardItem({
'image/png': blob
});
await navigator.clipboard.write([item]);
//window.alert('クリップボードにコピーしました。');
myClipboard2Column('DescriptionA', false);
/*
//ペースト
let pasteArea = document.getElementById('Results_Body');
navigator.clipboard.readText()
.then(function(text) {
pasteArea.style.display = 'block';
pasteArea.focus();
let KEvent = new KeyboardEvent("keydown", {
key: "A"
});
pasteArea.dispatchEvent(KEvent);
});
*/
});
}
$p.events.on_editor_load = function () {
init();
}
/*
myClipboard2Column
引数
columnName:対象カラム (ex:'分類A':ラベル'ClassA':論理名)
appendFlg:追記フラグ (true:追記false:上書き)
使い方
myClipboard2Column('説明です', true);
myClipboard2Column('ClassA', false);
注意点
ブラウザが前面のある時しか動作しません
*/
async function myClipboard2Column(columnName, appendFlg) {
try {
const $control = $p.getControl(columnName);
const clipboardContents = await navigator.clipboard.read();
for (const item of clipboardContents) {
if (item.types.includes("text/plain")) {
const str0 = (appendFlg) ? $control.val() : "";
const str1 = await (await item.getType("text/plain")).text();
$p.set($control, str0 + str1);
$p.setFormChanged($control);
}
else if (item.types.includes('image/png')) {
if ($control.hasClass("upload-image")) {
if (!appendFlg) $p.set($control, "");
const blob = await item.getType("image/png");
$p.uploadImage($control.attr('id'), blob);
$p.setFormChanged($control);
}
}
}
}
catch (error) {
console.error(error.message);
}
}

View File

@ -0,0 +1,214 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : mermaid_Editor
@name :
@siteIds : 326341
@siteTitles : MD作成
@disabled: false
*/
let pageLoading = 0; //ページのロード状態を管理する変数
//----------------------------------------------------------------------
//初期処理
window.addEventListener('load', function () {
if (pageLoading == 0) {
console.log('Window load Event');
$p.ex.onLoad();
}
});
$p.events.on_editor_load = function () {
if (pageLoading == 0) {
console.log('on Editor Load');
$p.ex.onLoad();
}
}
//----------------------------------------------------------------------
$p.ex.onLoad = function () {
//ロード開始
pageLoading = 1;
//初期処理
$p.ex.init();
}
//初期処理
$p.ex.init = function () {
//初期化
const mermaidContent = $('#Results_Body').val(); //値を取得
if ($('#mermaidWindow').length) {
$('#mermaidWindow').remove(); //既存のMermaidウインドウを削除
}
//Mermaidウインドウ
let mermaidWindow = document.createElement('div');
mermaidWindow.id = 'mermaidWindow'; //任意のIDを指定
mermaidWindow.className = 'mermaidWindow'; //任意のクラスを指定
let h1 = document.createElement('h1');
h1.innerHTML = 'Mermaid Viewer';
mermaidWindow.appendChild(h1);
let h2 = document.createElement('h2');
h2.innerHTML = 'Mermaid記法で記述された図がプレビューされます。';
mermaidWindow.appendChild(h2);
//Preview用Preタグを作成
const pre = document.createElement('pre');
pre.id = 'mermaidPreview';
pre.className = 'mermaid'; //Mermaid描画用のクラスを設定
pre.textContent = mermaidContent; //Mermaid記法を設定
//描画エリアに追加
mermaidWindow.appendChild(pre);
$('#Editor').after(mermaidWindow);
//Mermaidを再レンダリング
if (window.mermaid) {
mermaid.init(undefined, '#mermaidPreview');
} else {
console.error('Mermaidライブラリが読み込まれていません。');
}
//PNG出力ボタンを作成
createExportButton();
};
//Mermaid図をPNG形式で出力するボタンを作成
function createExportButton() {
const exportButton = document.createElement('button');
exportButton.id = 'exportMermaid';
exportButton.textContent = 'PNGとして保存';
exportButton.style.marginTop = '10px';
//ボタンのクリックイベント
exportButton.addEventListener('click', function () {
const mermaidPreview = document.getElementById('mermaidPreview');
if (mermaidPreview) {
html2canvas(mermaidPreview).then(canvas => {
const link = document.createElement('a');
link.download = 'mermaid-diagram.png';
link.href = canvas.toDataURL('image/png');
link.click();
}).catch(error => {
console.error('PNG出力中にエラーが発生しました:', error);
});
} else {
console.error('Mermaidプレビューエリアが見つかりません。');
}
});
//Mermaidウインドウにボタンを追加
const mermaidWindow = document.getElementById('mermaidWindow');
if (mermaidWindow) {
mermaidWindow.appendChild(exportButton);
$(exportButton).button({
icon: "ui-icon-image",
showLabel: true
});
} else {
console.error('Mermaidウインドウが見つかりません。');
}
}
//#Results_Body の中身が変更されたら処理を実行
$p.on('change', 'Body', function () {
$p.ex.init();
});
$p.events.after_set = function (args) {
$p.ex.init();
}
$p.events.before_validate_Update = async function (args) {
console.log('Mermaid画像の保存を開始します。');
// saveMermaidImage() の完了を待つ
const result = await saveMermaidImage();
if (result) {
console.log('Mermaid画像の保存が成功しました。次の処理を実行します。');
// 次の処理をここに記述
} else {
console.error('Mermaid画像の保存に失敗しました。処理を中断します。');
return false; // 処理を中断
}
// 必要に応じて次の処理を続行
console.log('次の処理を実行中...');
return false; // 処理を続行
};
async function saveMermaidImage() {
const mermaidPreview = document.getElementById('mermaidPreview');
if (mermaidPreview) {
try {
const canvas = await html2canvas(mermaidPreview);
const pngBase64 = canvas.toDataURL('image/png').replace(/^data:image\/png;base64,/, '');
// uploadImage関数のレスポンスを待つ
const res = await uploadImage(pngBase64);
console.log('アップロード結果:', res);
if (res && res.StatusCode === 200) {
console.log('アップロードが成功しました。');
return true; // 成功
} else {
console.error('アップロードに失敗しました。');
return false; // 失敗
}
} catch (error) {
console.error('PNG変換またはアップロード中にエラーが発生しました:', error);
return false; // エラー
}
} else {
console.error('Mermaidプレビューエリアが見つかりません。');
return false; // プレビューエリアがない
}
}
async function uploadImage(pngBase64) {
const url = 'https://' + location.hostname + '/pleasanter/api/items/' + $p.id() + '/update'
const json = {
'ApiVersion': 1.1,
'DescriptionHash': {
'DescriptionA': '' // Mermaid記法を設定
},
'ImageHash': {
'DescriptionA': {
'Base64': pngBase64,
}
}
}
const res = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(json)
});
return res.json();
}
//要素が読み込まれるまで待機し、返す
function waitForElement(selector, callback, interval = 100, timeout = 5000) {
const startTime = Date.now();
const checkExist = setInterval(function () {
if ($(selector).length) {
clearInterval(checkExist); //要素が見つかったら停止
callback();
} else if (Date.now() - startTime > timeout) {
clearInterval(checkExist); //タイムアウト処理
console.warn(`指定した要素 '${selector}' が ${timeout / 1000} 秒以内に見つかりませんでした。`);
}
}, interval);
}

View File

@ -0,0 +1,210 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : mermaid_Editor2
@name :
@siteIds : 326341
@siteTitles : Mermaidチャート生成
@disabled: false
*/
let pageLoading = 0; //ページのロード状態を管理する変数
//----------------------------------------------------------------------
//初期処理
window.addEventListener('load', function () {
if (pageLoading == 0) {
console.log('Window load Event');
$p.ex.onLoad();
}
});
$p.events.on_editor_load = function () {
if (pageLoading == 0) {
console.log('on Editor Load');
$p.ex.onLoad();
}
}
//----------------------------------------------------------------------
$p.ex.onLoad = function () {
//ロード開始
pageLoading = 1;
//初期処理
$p.ex.init();
}
//初期処理
$p.ex.init = function () {
initMermaid();
};
async function initMermaid() {
//初期化
//初期化
const mermaidContent = $('#Results_Body').val(); //値を取得
if ($('#mermaidWindow').length) {
$('#mermaidWindow').remove(); //既存のMermaidウインドウを削除
}
//Mermaidウインドウ
let mermaidWindow = document.createElement('div');
mermaidWindow.id = 'mermaidWindow'; //任意のIDを指定
mermaidWindow.className = 'mermaidWindow'; //任意のクラスを指定
let h1 = document.createElement('h1');
h1.innerHTML = 'Mermaid Viewer';
mermaidWindow.appendChild(h1);
let h2 = document.createElement('h2');
h2.innerHTML = 'Mermaid記法で記述された図がプレビューされます。';
mermaidWindow.appendChild(h2);
//Preview用Preタグを作成
const pre = document.createElement('pre');
pre.id = 'mermaidPreview';
pre.className = 'mermaid'; //Mermaid描画用のクラスを設定
pre.textContent = mermaidContent; //Mermaid記法を設定
//描画エリアに追加
mermaidWindow.appendChild(pre);
$('#Editor').after(mermaidWindow);
//Mermaidを再レンダリング
if (window.mermaid) {
await mermaid.init(undefined, '#mermaidPreview');
} else {
console.error('Mermaidライブラリが読み込まれていません。');
}
//PNG出力ボタンを作成
createExportButton();
//クリップボード保存ボタンを作成
//createSaveImageButton();
}
//Mermaid図をPNG形式で出力するボタンを作成
function createExportButton() {
const exportButton = document.createElement('button');
exportButton.id = 'exportMermaid';
exportButton.textContent = 'PNGとして保存';
exportButton.style.marginTop = '10px';
//ボタンのクリックイベント
exportButton.addEventListener('click', function () {
const mermaidPreview = document.getElementById('mermaidPreview');
if (mermaidPreview) {
html2canvas(mermaidPreview).then(canvas => {
const link = document.createElement('a');
link.download = 'mermaid-diagram.png';
link.href = canvas.toDataURL('image/png');
link.click();
}).catch(error => {
console.error('PNG出力中にエラーが発生しました:', error);
});
} else {
console.error('Mermaidプレビューエリアが見つかりません。');
}
});
//Mermaidウインドウにボタンを追加
const mermaidWindow = document.getElementById('mermaidWindow');
if (mermaidWindow) {
mermaidWindow.appendChild(exportButton);
$(exportButton).button({
icon: "ui-icon-image",
showLabel: true
});
} else {
console.error('Mermaidウインドウが見つかりません。');
}
}
//#Results_Body の中身が変更されたら処理を実行
$p.on('change', 'Body', async function () {
await initMermaid();
await saveMermaidImage();
});
$p.events.after_set = function (args) {
initMermaid();
}
$p.events.before_validate_Update = function (args) {
}
async function saveMermaidImage() {
const mermaidPreview = document.getElementById('mermaidPreview');
const canvas = await html2canvas(mermaidPreview);
canvas.toBlob(async (blob) => {
try {
await navigator.clipboard.write([
new ClipboardItem({ 'image/png': blob })
]);
console.log('クリップボードにコピーしました。');
// myClipboard2Columnを呼び出してクリップボードの内容をカラムに設定
await myClipboard2Column('DescriptionA', false); // 'DescriptionA'は適切なカラム名に置き換えてください
} catch (err) {
console.error('クリップボードへのコピーに失敗しました:', err);
}
}, 'image/png');
}
//myClipboard2Column
async function myClipboard2Column(columnName, appendFlg) {
try {
const $control = $p.getControl(columnName);
const clipboardContents = await navigator.clipboard.read();
for (const item of clipboardContents) {
if (item.types.includes("text/plain")) {
const str0 = (appendFlg) ? $control.val() : "";
const str1 = await (await item.getType("text/plain")).text();
$p.set($control, str0 + str1);
$p.setFormChanged($control);
}
else if (item.types.includes('image/png')) {
if ($control.hasClass("upload-image")) {
if (!appendFlg) $p.set($control, "");
const blob = await item.getType("image/png");
$p.uploadImage($control.attr('id'), blob);
$p.setFormChanged($control);
}
}
}
}
catch (error) {
console.error(error.message);
}
}
function createSaveImageButton() {
const saveImageButton = document.createElement('button');
saveImageButton.id = 'saveMermaidImage';
saveImageButton.textContent = 'Mermaidをクリップボードにコピー';
saveImageButton.style.marginTop = '10px';
// ボタンのクリックイベント
saveImageButton.addEventListener('click', function () {
saveMermaidImage(); // saveMermaidImage() を実行
});
// Mermaidウインドウにボタンを追加
const mermaidWindow = document.getElementById('mermaidWindow');
if (mermaidWindow) {
mermaidWindow.appendChild(saveImageButton);
$(saveImageButton).button({
icon: "ui-icon-clipboard",
showLabel: true
});
} else {
console.error('Mermaidウインドウが見つかりません。');
}
}

View File

@ -0,0 +1,51 @@
/*
@config : next999.json
@filename : style.css
@title : style.css
@name :
@siteIds : 326341
@siteTitles : MD作成
@disabled: false
*/
#Editor {
width: 40%;
}
#RecordHeader {
display: none;
}
.mermaidWindow {
width: 60%;
float: left;
padding: 0 15px 15px 15px;
h1 {
font-size: 2em;
margin-bottom: 5px;
font-weight: bold;
}
h2 {
font-size: 1.2em;
margin-bottom: 5px;
margin-left: 3px;
}
pre {
background-color: antiquewhite;
border-radius: 15px;
padding: 10px;
}
}
#Results_Body,
#Results_Body\.viewer {
min-height: 400px !important;
max-height: 1200px !important;
}
#Results_Body\.viewer {
overflow: hidden;
}

Some files were not shown because too many files have changed in this diff Show More