ここでは、InputManJSのステッパーコンポーネントとツアーコンポーネントを組み合わせて、会員登録手順を実装する方法を紹介します。
ステッパーコンポーネント
ステッパー(GcStepper)を使用し、4つのステップ(基本情報、詳細情報、確認、完了)で会員登録を案内します。
各ステップの有効性を検証結果と連動し、すべての項目が正しく入力されるまで次のステップに進めないように制御します。
完了ステップに進むと前のステップへの戻りを無効化し、登録内容の整合性を保ちます。
ツアーコンポーネント
ツアーコンポーネント(GcTour)を使用し、各ステップで操作方法や注意点を表示し、入力支援を行います。
カスタムツールチップ機能を使用して、「前へ」ボタンを「前のステップへ戻る」ボタンにカスタマイズし、ボタンをクリックすると前の画面に移動します。
各ステップのタイトルの横にインフォメーションアイコンを配置し、ユーザーの必要なタイミングでツアーを再開できます。
ステップを切り替えるとツアーが自動的に表示され、次に入力すべき項目を案内します。
検証失敗時にツールチップにエラーメッセージを表示します。
Tabキーを押下すると、ツールチップ内の「次へ」ボタン(または「前へ」ボタン)にフォーカスが移動し、キーボード操作のみでステップを進めたり戻ったりすることができます。
検証機能との連携
検証コントロール(GcValidator)を使用し、入力内容をリアルタイムで検証を実行します。
検証失敗時の結果をツアーコンポーネントのツールチップにエラーメッセージを表示します。
import '@mescius/inputman/CSS/gc.inputman-js.css';
import { InputMan } from '@mescius/inputman';
import './styles.css';
InputMan.appearanceStyle = InputMan.AppearanceStyle.Modern;
const username = new InputMan.GcTextBox(document.getElementById('username'), {
watermarkDisplayNullText: '例)InputManJS Taro',
exitOnEnterKey: InputMan.ExitKey.Both,
width: 300,
height: 35,
});
const email = new InputMan.GcTextBox(document.getElementById('email'), {
watermarkDisplayNullText: '例)inputmanjs@example.com',
exitOnEnterKey: InputMan.ExitKey.Both,
width: 300,
height: 35,
});
const password = new InputMan.GcTextBox(document.getElementById('password'), {
watermarkDisplayNullText: '6文字以上のパスワードを入力してください',
exitOnEnterKey: InputMan.ExitKey.Both,
width: 300,
height: 35,
useSystemPasswordChar: true,
passwordRevelationMode: InputMan.PasswordRevelationMode.ShowEyeButton,
});
const fullName = new InputMan.GcTextBox(document.getElementById('fullName'), {
watermarkDisplayNullText: '例)入力太郎',
exitOnEnterKey: InputMan.ExitKey.Both,
width: 300,
height: 35,
});
const phone = new InputMan.GcMask(document.getElementById('phone'), {
formatPattern: '\\D{2,3}-\\D{2,3}-\\D{4}',
watermarkDisplayNullText: '例)090-1234-5678',
exitOnLeftRightKey: InputMan.ExitOnLeftRightKey.Both,
exitOnLastChar: true,
exitOnEnterKey: InputMan.ExitKey.Both,
width: 300,
height: 35,
});
const prefecture = new InputMan.GcTextBox(document.getElementById('prefecture'), {
watermarkDisplayNullText: '都道府県名を選択してください',
exitOnLeftRightKey: InputMan.ExitOnLeftRightKey.Both,
exitOnEnterKey: InputMan.ExitKey.Both,
width: 300,
height: 35,
});
const dropDown = prefecture.createDropDown();
dropDown.getElement().appendChild(document.getElementById('prefDropdown'));
document.getElementById('prefDropdown').addEventListener('click', (e) => {
if (e.target.tagName.toLowerCase() == 'span') {
prefecture.text = e.target.innerText;
dropDown.close();
}
});
const birthDate = new InputMan.GcDateTime(document.getElementById('birthDate'), {
exitOnEnterKey: InputMan.ExitKey.Both,
width: 300,
height: 35,
watermarkDisplayNullText: '生年月日を選択してください',
displayFormatPattern: 'ggg E年M月d日',
formatPattern: 'yyyy/MM/dd',
value: null,
showDropDownButton: true,
dropDownConfig: {
dropDownType: InputMan.DateDropDownType.Calendar,
defaultDate: new Date('1995-01-01'),
}
});
document.getElementById('nextBtn1').disabled = true;
document.getElementById('nextBtn2').disabled = true;
document.getElementById('submitBtn').disabled = true;
const validator1 = new InputMan.GcValidator({
items: [
{
control: username,
ruleSet: [
{
rule: InputMan.ValidateType.Required,
failMessage: '必須項目です。',
},
],
validateWhen: InputMan.ValidateWhen.Typing,
},
{
control: email,
ruleSet: [
{
rule: InputMan.ValidateType.Required,
failMessage: '必須項目です。',
},
{
rule: (control) => {
const regexp =
/^[A-Za-z0-9]{1}[A-Za-z0-9_.-]*@{1}[A-Za-z0-9_.-]{1,}\.[A-Za-z0-9]{1,}$/;
return regexp.test(control.value);
},
failMessage: '正しいメールアドレス形式で入力してください',
},
],
validateWhen: InputMan.ValidateWhen.Typing,
},
{
control: password,
ruleSet: [
{
rule: InputMan.ValidateType.GreaterThanOrEqualToInputLength,
inputLength: 6,
failMessage: '6文字以上に入力してください',
},
],
validateWhen: InputMan.ValidateWhen.Typing,
}
],
defaultNotify: {
fail: {
controlState: true
}
}
});
validator1.validate();
validator1.addEventListener(InputMan.GcValidatorEvent.ValidationFailed, (s, e) => {
const stepIndex = [, username, email, password].findIndex((v) => v === e.control);
step1Tour.steps[stepIndex].message = `<div style="color: red;">${e.context.failMessage}<div>`;
step1Tour.steps[stepIndex].disableNextButton = true;
gcStepper.steps[0].isValid = false;
document.getElementById('nextBtn1').disabled = true;
});
let isValidating = false;
validator1.addEventListener(InputMan.GcValidatorEvent.ValidationSucceeded, (s, e) => {
const stepIndex = [, username, email, password].findIndex((v) => v === e.control);
step1Tour.steps[stepIndex].message = '';
step1Tour.steps[stepIndex].disableNextButton = false;
if (!isValidating) {
isValidating = true;
gcStepper.steps[0].isValid = validator1.validate();
document.getElementById('nextBtn1').disabled = !gcStepper.steps[0].isValid;
isValidating = false;
}
});
const validator2 = new InputMan.GcValidator({
items: [
{
control: fullName,
ruleSet: [
{
rule: InputMan.ValidateType.Required,
failMessage: '必須項目です。',
},
],
validateWhen: InputMan.ValidateWhen.Typing,
},
{
control: phone,
ruleSet: [
{
rule: InputMan.ValidateType.Required,
failMessage: '必須項目です。',
},
],
validateWhen: InputMan.ValidateWhen.Typing,
}
],
defaultNotify: {
fail: {
controlState: true
}
}
});
validator2.validate();
validator2.addEventListener(InputMan.GcValidatorEvent.ValidationFailed, (s, e) => {
const stepIndex = [, fullName, phone].findIndex((v) => v === e.control);
step2Tour.steps[stepIndex].message = `<div style="color: red;">${e.context.failMessage}<div>`;
step2Tour.steps[stepIndex].disableNextButton = true;
gcStepper.steps[1].isValid = false;
document.getElementById('nextBtn2').disabled = true;
});
let isValidating2 = false;
validator2.addEventListener(InputMan.GcValidatorEvent.ValidationSucceeded, (s, e) => {
const stepIndex = [, fullName, phone].findIndex((v) => v === e.control);
step2Tour.steps[stepIndex].message = '';
step2Tour.steps[stepIndex].disableNextButton = false;
if (!isValidating2) {
isValidating2 = true;
gcStepper.steps[1].isValid = validator2.validate();
document.getElementById('nextBtn2').disabled = !gcStepper.steps[1].isValid;
isValidating2 = false;
}
});
const gcStepper = new InputMan.GcStepper(document.getElementById('gcStepper'), {
steps: [
{
label: '基本情報',
title: '基本情報の入力',
target: () => document.getElementById('form1'),
},
{
label: '詳細情報',
title: '詳細情報の入力',
target: () => document.getElementById('form2'),
},
{
label: '確認',
title: '入力内容の確認',
target: () => document.getElementById('form3'),
},
{
label: '完了',
title: '登録完了',
target: () => document.getElementById('form4'),
},
],
linear: true
});
const step1Tour = new InputMan.GcTour({
steps: [
{
title: '会員登録へようこそ',
description: 'InputManJSの会員登録を開始します。まずは基本情報を入力してください。',
},
{
target: username,
title: 'ユーザー名の設定',
description: 'ログイン時に使用するユーザー名を入力してください。',
},
{
target: email,
title: 'メールアドレスの登録',
description: '正確なメールアドレスを入力してください。重要なお知らせや確認メールの送信先として使用します。',
},
{
target: password,
title: 'パスワードの設定',
description: '6文字以上の安全なパスワードを設定してください。',
},
{
target: () => document.getElementById('nextBtn1'),
title: '次のステップへ',
description: '基本情報の入力が完了しましたら、次のステップにお進みください。',
},
],
customTip: (context) => {
if (context.tour.activeIndex === 0) {
context.dom.previousButton.style.display = 'none';
}
},
hideDoneButton: true
});
const step2Tour = new InputMan.GcTour({
steps: [
{
title: '詳細情報の入力',
description: '詳細な情報をご入力ください。任意項目もありますが、入力いただくとより便利にご利用いただけます。',
},
{
target: fullName,
title: '氏名の入力',
description: '本人確認や連絡の際に使用します。',
},
{
target: phone,
title: '電話番号の登録',
description: '緊急時の連絡に使用する場合があります。',
},
{
target: prefecture,
title: '住所の登録',
description: '地域に応じたサービス提供に使用します。(任意)',
},
{
target: birthDate,
title: '生年月日の入力',
description: '年齢に応じたサービス提供に活用します。(任意)',
},
{
target: () => document.getElementById('nextBtn2'),
title: '確認画面へ',
description: '詳細情報の入力が完了しましたら、確認画面にお進みください。',
},
],
customTip: (context) => {
if (context.tour.activeIndex === 0) {
context.dom.previousButton.style.display = 'none';
const backButton = renderBackButton();
backButton.addEventListener('click', () => gcStepper.goTo(0));
context.dom.previousButton.before(backButton);
}
},
hideDoneButton: true
});
const step3Tour = new InputMan.GcTour({
steps: [
{
target: () => document.querySelector('.confirmation-table'),
title: '登録情報の確認',
description: 'ご入力いただいた内容を確認してください。修正が必要な場合は、前のステップに戻って修正してください。',
},
{
target: document.getElementById('agreeTerms'),
title: '利用規約とプライバシーポリシーの同意',
description: '詳細については当社ホームページをご確認ください。',
message: `<div style="color: red;">利用規約とプライバシーポリシーに同意するには、チェックを入れてください。<div>`,
disableNextButton: true,
},
{
target: document.querySelector('.submitBtn'),
title: '会員登録の完了',
description: '「登録する」ボタンをクリックして会員登録を完了してください。',
},
],
customTip: (context) => {
if (context.tour.activeIndex === 0) {
context.dom.previousButton.style.display = 'none';
const backButton = renderBackButton();
backButton.addEventListener('click', () => gcStepper.goTo(1));
context.dom.previousButton.before(backButton);
}
},
hideDoneButton: true
});
function renderBackButton() {
const button = document.createElement('button');
button.classList.add('gcim__tour-footer-btn');
button.textContent = '前のステップへ戻る';
return button;
}
document.getElementById('agreeTermsCheckbox').addEventListener('change', (e) => {
const isChecked = e.target.checked;
if (!isChecked) {
step3Tour.steps[1].message = `<div style="color: red;">利用規約とプライバシーポリシーに同意するには、チェックを入れてください。<div>`;
} else {
step3Tour.steps[1].message = '';
}
step3Tour.steps[1].disableNextButton = !isChecked;
gcStepper.steps[2].isValid = isChecked;
document.getElementById('submitBtn').disabled = !gcStepper.steps[2].isValid;
});
gcStepper.addEventListener(InputMan.GcStepperEvent.StepChanged, (s, e) => {
const stepIndex = e.newIndex;
step1Tour.close();
step2Tour.close();
step3Tour.close();
setTimeout(() => {
switch (stepIndex) {
case 0:
step1Tour.start(true);
break;
case 1:
validator2.validate();
step2Tour.start(true);
break;
case 2:
updateConfirmation();
step3Tour.start(true);
break;
case 3:
gcStepper.steps[0].disabled = true;
gcStepper.steps[1].disabled = true;
gcStepper.steps[2].disabled = true;
break;
}
}, 500);
});
function updateConfirmation() {
document.getElementById('confirmUsername').textContent = username.text ? username.text : '-';
document.getElementById('confirmEmail').textContent = email.text ? email.text : '-';
document.getElementById('confirmFullName').textContent = fullName.text ? fullName.text : '-';
document.getElementById('confirmPhone').textContent = phone.value ? phone.text : '-';
document.getElementById('confirmBirthDate').textContent =
birthDate.value ? birthDate.getDisplayText() : '-';
}
document
.querySelectorAll('.prevBtn')
.forEach((v) => v.addEventListener('click', () => gcStepper.previous()));
document
.querySelectorAll('.nextBtn')
.forEach((v) => v.addEventListener('click', () => gcStepper.next()));
document.querySelector('.submitBtn').addEventListener('click', () => {
gcStepper.goTo(3);
});
document.getElementById('backToStartBtn').addEventListener('click', () => {
username.clear();
email.clear();
password.clear();
fullName.clear();
phone.clear();
birthDate.clear();
document.getElementById('agreeTermsCheckbox').checked = false;
document.getElementById('nextBtn1').disabled = true;
document.getElementById('nextBtn2').disabled = true;
document.getElementById('submitBtn').disabled = true;
gcStepper.steps.forEach((s) => {
s.isValid = null;
s.disabled = false;
});
step1Tour.close();
step2Tour.close();
step3Tour.close();
gcStepper.goTo(0);
});
document.getElementById('tour1').addEventListener('click', () => step1Tour.start(true));
document.getElementById('tour2').addEventListener('click', () => step2Tour.start(true));
document.getElementById('tour3').addEventListener('click', () => step3Tour.start(true));
setTimeout(() => {
step1Tour.start();
validator1.validate();
}, 1000);
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>実用例 - 会員登録</title>
<!-- SystemJS -->
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
window.onload = function () {
System.import('./src/app');
}
</script>
</head>
<body>
<div class="container">
<div id="gcStepper"></div>
</div>
<div id="form1" class="form-step">
<h3>
基本情報の入力
<img src="$IMDEMOROOT$/ja/samples/examples/registerMember/img/guide.svg" id="tour1" title="ガイドを表示" alt="ガイド" />
</h3>
<table class="form-table">
<tbody>
<tr>
<td class="label-cell">
<label for="username">ユーザー名 <span class="required">*</span></label>
</td>
<td class="input-cell">
<input id="username" />
</td>
</tr>
<tr>
<td class="label-cell">
<label for="email">メールアドレス <span class="required">*</span></label>
</td>
<td class="input-cell">
<input id="email" />
</td>
</tr>
<tr>
<td class="label-cell">
<label for="password">パスワード <span class="required">*</span></label>
</td>
<td class="input-cell">
<input id="password" />
</td>
</tr>
</tbody>
</table>
<div class="button-group">
<button class="nextBtn" id="nextBtn1">次へ</button>
</div>
</div>
<div id="form2" class="form-step">
<h3>
詳細情報の入力
<img src="$IMDEMOROOT$/ja/samples/examples/registerMember/img/guide.svg" id="tour2" title="ガイドを表示" alt="ガイド" />
</h3>
<table class="form-table">
<tbody>
<tr>
<td class="label-cell">
<label for="fullName">氏名 <span class="required">*</span></label>
</td>
<td class="input-cell">
<input id="fullName" />
</td>
</tr>
<tr>
<td class="label-cell">
<label for="phone">電話番号 <span class="required">*</span></label>
</td>
<td class="input-cell">
<input id="phone" />
</td>
</tr>
<tr>
<td class="label-cell">
<label for="address">住所</label>
</td>
<td class="input-cell">
<input id="prefecture" class="prefecture">
</td>
</tr>
<tr>
<td class="label-cell">
<label for="birthDate">生年月日</label>
</td>
<td class="input-cell">
<input id="birthDate" />
</td>
</tr>
</tbody>
</table>
<div id="prefDropdown">
<table>
<tbody>
<tr>
<th>北海道</th>
<td><span>北海道</span></td>
</tr>
<tr>
<th>東北</th>
<td><span>青森県</span><span>岩手県</span><span>宮城県</span><span>秋田県</span><span>山形県</span><span>福島県</span>
</td>
</tr>
<tr>
<th>関東</th>
<td><span>茨城県</span><span>栃木県</span><span>群馬県</span><span>埼玉県</span><span>千葉県</span><span>東京都</span><span>神奈川県</span>
</td>
</tr>
<tr>
<th>甲信越</th>
<td><span>山梨県</span><span>長野県</span><span>新潟県</span></td>
</tr>
<tr>
<th>北陸</th>
<td><span>富山県</span><span>石川県</span><span>福井県</span></td>
</tr>
<tr>
<th>東海</th>
<td><span>岐阜県</span><span>静岡県</span><span>愛知県</span><span>三重県</span></td>
</tr>
<tr>
<th>近畿</th>
<td><span>滋賀県</span><span>京都府</span><span>大阪府</span><span>兵庫県</span><span>奈良県</span><span>和歌山県</span>
</td>
</tr>
<tr>
<th>中国</th>
<td><span>鳥取県</span><span>島根県</span><span>岡山県</span><span>広島県</span><span>山口県</span>
</td>
</tr>
<tr>
<th>四国</th>
<td><span>徳島県</span><span>香川県</span><span>愛媛県</span><span>高知県</span>
</td>
</tr>
<tr>
<th>九州</th>
<td><span>福岡県</span><span>佐賀県</span><span>長崎県</span><span>熊本県</span><span>大分県</span><span>宮崎県</span><span>鹿児島県</span>
</td>
</tr>
<tr>
<th>沖縄</th>
<td><span>沖縄県</span></td>
</tr>
</tbody>
</table>
</div>
<div class="button-group">
<button class="prevBtn">戻る</button>
<button class="nextBtn" id="nextBtn2">次へ</button>
</div>
</div>
<div id="form3" class="form-step">
<h3>
入力内容の確認
<img src="$IMDEMOROOT$/ja/samples/examples/registerMember/img/guide.svg" id="tour3" title="ガイドを表示" alt="ガイド" />
</h3>
<table class="confirmation-table">
<tbody>
<tr>
<td class="confirm-label">ユーザー名</td>
<td class="confirm-value">
<span id="confirmUsername"></span>
</td>
</tr>
<tr>
<td class="confirm-label">メールアドレス</td>
<td class="confirm-value">
<span id="confirmEmail"></span>
</td>
</tr>
<tr>
<td class="confirm-label">氏名</td>
<td class="confirm-value">
<span id="confirmFullName"></span>
</td>
</tr>
<tr>
<td class="confirm-label">電話番号</td>
<td class="confirm-value">
<span id="confirmPhone"></span>
</td>
</tr>
<tr>
<td class="confirm-label">生年月日</td>
<td class="confirm-value">
<span id="confirmBirthDate"></span>
</td>
</tr>
</tbody>
</table>
<div class="agreement-section" id="agreeTerms">
<div class="agreement-checkbox">
<input type="checkbox" id="agreeTermsCheckbox" />
<label for="agreeTermsCheckbox">
利用規約とプライバシーポリシーに同意します。 <span class="required">*</span>
</label>
</div>
</div>
<div class="button-group">
<button class="prevBtn">戻る</button>
<button class="submitBtn" id="submitBtn">登録する</button>
</div>
</div>
<div id="form4" class="form-step">
<h3>会員登録完了</h3>
<div class="completion-message">
<p>🎉 会員登録が正常に完了しました!</p>
<p>ご登録いただいたメールアドレスに確認メールを送信いたします。</p>
</div>
<div class="button-group">
<button id="backToStartBtn" class="nextBtn">最初の画面に戻る</button>
</div>
</div>
</body>
</html>
.container {
border: 1px solid #ccc;
margin: 10px auto;
background: #fff;
border-radius: 12px;
padding: 32px 36px 28px 36px;
min-height: 600px;
}
.nextBtn,
.submitBtn {
min-width: 70px;
padding: 8px 16px;
border: 2px solid #007bff;
border-radius: 6px;
background: #007bff;
color: white;
font-size: 12px;
font-weight: 600;
cursor: pointer;
margin-left: 6px;
margin-top: 6px;
box-shadow: 0 2px 4px rgba(0, 123, 255, 0.2);
transition: all 0.2s ease;
}
.nextBtn:hover,
.submitBtn:hover {
background: #4a90e2;
border-color: #4a90e2;
box-shadow: 0 4px 8px rgba(0, 123, 255, 0.3);
transform: translateY(-1px);
}
.nextBtn:disabled,
.submitBtn:disabled {
background-color: #e0e0e0;
border-color: #e0e0e0;
color: #a0a0a0;
cursor: not-allowed;
box-shadow: none;
opacity: 0.7;
}
.prevBtn {
min-width: 70px;
padding: 8px 16px;
border: 2px solid #c3c4c5;
border-radius: 6px;
background: transparent;
color: #c3c4c5;
font-size: 12px;
font-weight: 600;
cursor: pointer;
margin-left: 6px;
margin-top: 6px;
box-shadow: 0 1px 1px rgba(108, 117, 125, 0.1);
transition: all 0.2s ease;
}
.prevBtn:hover {
background: #c3c4c5;
color: white;
box-shadow: 0 1px 1px rgba(108, 117, 125, 0.2);
transform: translateY(-1px);
}
.button-group {
margin-top: 30px;
display: flex;
gap: 10px;
justify-content: center;
align-items: center;
}
.form-table,
.confirmation-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
background: white;
}
.form-table > tbody > tr,
.confirmation-table > tbody > tr {
border-bottom: 1px solid #e9ecef;
}
.label-cell,
.confirm-label {
width: 150px;
padding: 15px 10px;
vertical-align: middle;
text-align: right;
background-color: #f8f9fa;
border-right: 1px solid #e9ecef;
font-weight: 600;
color: #555;
}
.input-cell,
.confirm-value {
padding: 15px 20px;
vertical-align: middle;
}
.label-cell label,
.confirm-label {
margin: 0;
}
.required {
color: #dc3545;
font-weight: bold;
}
.confirm-value {
color: #212529;
font-weight: 500;
}
.form-step {
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
}
.form-step h3 {
color: #333;
margin-bottom: 25px;
font-size: 18px;
border-bottom: 2px solid #007bff;
padding-bottom: 10px;
text-align: left;
display: flex;
align-items: center;
justify-content: flex-start;
gap: 15px;
}
.form-step h3 img {
width: 20px;
height: 20px;
cursor: pointer;
opacity: 0.7;
transition: all 0.2s ease;
margin-left: 0;
}
.form-step h3 img:hover {
opacity: 1;
transform: scale(1.1);
}
.gcim_watermark_null {
color: lightgrey;
}
#prefDropdown table {
background-color: rgb(248, 248, 248);
border: darkgray 1px solid;
border-radius: 5px;
max-height: 180px;
max-width: 400px;
display: block;
overflow-y: auto;
width: 100%
}
#prefDropdown th {
padding: 0 0.5rem;
border-right: steelblue 2px solid;
font-weight: bold;
}
#prefDropdown td {
word-wrap: break-word;
word-break: break-all;
white-space: normal;
max-width: 300px;
line-height: 1.4;
font-weight: bold;
}
#prefDropdown span {
display: inline-block;
padding: 2px 4px;
white-space: nowrap;
margin: 0 0.5rem;
color: blue;
cursor: pointer;
}
.prefecture {
vertical-align: bottom;
}
.container {
border: 1px solid #ccc;
margin: 10px auto;
background: #fff;
border-radius: 12px;
padding: 32px 36px 28px 36px;
min-height: 600px;
}
.nextBtn,
.submitBtn {
min-width: 70px;
padding: 8px 16px;
border: 2px solid #007bff;
border-radius: 6px;
background: #007bff;
color: white;
font-size: 12px;
font-weight: 600;
cursor: pointer;
margin-left: 6px;
margin-top: 6px;
box-shadow: 0 2px 4px rgba(0, 123, 255, 0.2);
transition: all 0.2s ease;
}
.nextBtn:hover,
.submitBtn:hover {
background: #4a90e2;
border-color: #4a90e2;
box-shadow: 0 4px 8px rgba(0, 123, 255, 0.3);
transform: translateY(-1px);
}
.nextBtn:disabled,
.submitBtn:disabled {
background-color: #e0e0e0;
border-color: #e0e0e0;
color: #a0a0a0;
cursor: not-allowed;
box-shadow: none;
opacity: 0.7;
}
.prevBtn {
min-width: 70px;
padding: 8px 16px;
border: 2px solid #c3c4c5;
border-radius: 6px;
background: transparent;
color: #c3c4c5;
font-size: 12px;
font-weight: 600;
cursor: pointer;
margin-left: 6px;
margin-top: 6px;
box-shadow: 0 1px 1px rgba(108, 117, 125, 0.1);
transition: all 0.2s ease;
}
.prevBtn:hover {
background: #c3c4c5;
color: white;
box-shadow: 0 1px 1px rgba(108, 117, 125, 0.2);
transform: translateY(-1px);
}
.button-group {
margin-top: 30px;
display: flex;
gap: 10px;
justify-content: center;
align-items: center;
}
.form-table,
.confirmation-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
background: white;
}
.form-table > tbody > tr,
.confirmation-table > tbody > tr {
border-bottom: 1px solid #e9ecef;
}
.label-cell,
.confirm-label {
width: 150px;
padding: 15px 10px;
vertical-align: middle;
text-align: right;
background-color: #f8f9fa;
border-right: 1px solid #e9ecef;
font-weight: 600;
color: #555;
}
.input-cell,
.confirm-value {
padding: 15px 20px;
vertical-align: middle;
}
.label-cell label,
.confirm-label {
margin: 0;
}
.required {
color: #dc3545;
font-weight: bold;
}
.confirm-value {
color: #212529;
font-weight: 500;
}
.form-step {
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
}
.form-step h3 {
color: #333;
margin-bottom: 25px;
font-size: 18px;
border-bottom: 2px solid #007bff;
padding-bottom: 10px;
text-align: left;
display: flex;
align-items: center;
justify-content: flex-start;
gap: 15px;
}
.form-step h3 img {
width: 20px;
height: 20px;
cursor: pointer;
opacity: 0.7;
transition: all 0.2s ease;
margin-left: 0;
}
.form-step h3 img:hover {
opacity: 1;
transform: scale(1.1);
}
[gcim-control-appearance="modern"] .gcim_watermark_null {
color: lightgrey;
}
[gcim-control-appearance="modern"] #prefDropdown table {
background-color: rgb(248, 248, 248);
border: darkgray 1px solid;
border-radius: 5px;
max-height: 180px;
max-width: 400px;
display: block;
overflow-y: auto;
width: 100%
}
[gcim-control-appearance="modern"] #prefDropdown th {
padding: 0 0.5rem;
border-right: steelblue 2px solid;
font-weight: bold;
}
[gcim-control-appearance="modern"] #prefDropdown td {
word-wrap: break-word;
word-break: break-all;
white-space: normal;
max-width: 300px;
line-height: 1.4;
font-weight: bold;
}
[gcim-control-appearance="modern"] #prefDropdown span {
display: inline-block;
padding: 2px 4px;
white-space: nowrap;
margin: 0 0.5rem;
color: blue;
cursor: pointer;
}
[gcim-control-appearance="modern"] .prefecture {
vertical-align: bottom;
}
System.config({
transpiler: 'plugin-babel',
babelOptions: {
es2015: true
},
meta: {
'*.css': { loader: 'css' }
},
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
'@mescius/inputman': 'npm:@mescius/inputman/index.js',
'@mescius/inputman/CSS': 'npm:@mescius/inputman/CSS',
'@mescius/inputman.richtexteditor': 'npm:@mescius/inputman.richtexteditor/index.js',
"@mescius/inputman.richtexteditor/CSS": "npm:@mescius/inputman.richtexteditor/CSS",
'@mescius/inputman.richtexteditor/JS/plugins/advlist': 'npm:@mescius/inputman.richtexteditor/JS/plugins/advlist/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/all': 'npm:@mescius/inputman.richtexteditor/JS/plugins/all/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/autosave': 'npm:@mescius/inputman.richtexteditor/JS/plugins/autosave/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/charmap': 'npm:@mescius/inputman.richtexteditor/JS/plugins/charmap/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/directionality': 'npm:@mescius/inputman.richtexteditor/JS/plugins/directionality/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/emoticons': 'npm:@mescius/inputman.richtexteditor/JS/plugins/emoticons/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/fullscreen': 'npm:@mescius/inputman.richtexteditor/JS/plugins/fullscreen/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/htmlcode': 'npm:@mescius/inputman.richtexteditor/JS/plugins/htmlcode/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/image': 'npm:@mescius/inputman.richtexteditor/JS/plugins/image/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/link': 'npm:@mescius/inputman.richtexteditor/JS/plugins/link/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/lists': 'npm:@mescius/inputman.richtexteditor/JS/plugins/lists/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/media': 'npm:@mescius/inputman.richtexteditor/JS/plugins/media/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/pagebreak': 'npm:@mescius/inputman.richtexteditor/JS/plugins/pagebreak/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/preview': 'npm:@mescius/inputman.richtexteditor/JS/plugins/preview/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/save': 'npm:@mescius/inputman.richtexteditor/JS/plugins/save/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/searchreplace': 'npm:@mescius/inputman.richtexteditor/JS/plugins/searchreplace/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/table': 'npm:@mescius/inputman.richtexteditor/JS/plugins/table/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/template': 'npm:@mescius/inputman.richtexteditor/JS/plugins/template/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/wordcount': 'npm:@mescius/inputman.richtexteditor/JS/plugins/wordcount/plugin.js',
'@mescius/inputman.comment': 'npm:@mescius/inputman.comment/index.js',
'@mescius/inputman.comment/CSS': 'npm:@mescius/inputman.comment/CSS',
'@mescius/wijmo': 'npm:@mescius/wijmo/index.js',
'@mescius/wijmo.styles': 'npm:@mescius/wijmo.styles',
'@mescius/wijmo.cultures': 'npm:@mescius/wijmo.cultures',
'@mescius/wijmo.input': 'npm:@mescius/wijmo.input/index.js',
'@mescius/wijmo.grid': 'npm:@mescius/wijmo.grid/index.js',
'@mescius/wijmo.nav': 'npm:@mescius/wijmo.nav/index.js',
'@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js',
'@mescius/spread-sheets-resources-ja': 'npm:@mescius/spread-sheets-resources-ja/index.js',
'@mescius/spread-sheets/styles': 'npm:@mescius/spread-sheets/styles',
'css': 'npm:systemjs-plugin-css/css.js',
'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js',
'systemjs-babel-build': 'npm:systemjs-plugin-babel/systemjs-babel-browser.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
src: {
defaultExtension: 'js'
},
"node_modules": {
defaultExtension: 'js'
},
}
});