モバイル風お問い合わせフォーム

ここではモバイルデバイスを想定した、お問い合わせフォーム画面を作成する方法を紹介します。

ここではInputManJSを利用してモバイルを想定した、お問い合わせフォーム画面を作成する方法を紹介します。 各コントロールで次の機能を追加しています。 お名前、お名前(ふりがな)、会社名(GcTextBox):入力補助のためのウォーターマークを設定しています。 お名前(ふりがな)(GcTextBox):お名前の入力欄を入力時にふりがなを自動取得しています。 電話番号(GcMask):ウォーターマークと数値のみのマスク処理の設定、入力完了後に次のコントロールへ自動フォーカス移動します。 メールアドレス(GcMask):ウォーターマークとメールアドレス用マスク処理の設定、Enterキーを入力で次のコントロールへ自動フォーカス移動します。 お問い合わせ内容(GcMultiLineTextBox):ヘルプボタンで入力可能文字数を表示します。 *モバイルの画面を超えてメッセージが表示される場合があります 必須項目の検証(GcValidator):送信ボタンを押下した時に、お名前、お名前(ふりがな)、会社名、メールアドレス、お問い合わせ内容の入力項目に対して、入力済みかを検証します。 文字列長の検証(GcValidator):お問い合わせ内容の入力項目に対して、1文字以上200文字以下かを検証します。
import './styles.css'; import { InputMan } from '@mescius/inputman'; import '@mescius/inputman/CSS/gc.inputman-js.css'; InputMan.appearanceStyle = InputMan.AppearanceStyle.Modern; document.readyState === 'complete' ? init() : window.onload = init; function init() { const username = new InputMan.GcTextBox(document.getElementById('username'), { watermarkDisplayNullText: '例)入力太郎', }); const furigana = new InputMan.GcTextBox(document.getElementById('furigana'), { watermarkDisplayNullText: '例)にゅうりょくたろう', }); username.onIMEReadingStringOutput((sender, eArgs) => { furigana.text = eArgs.readingString; }); username.onInput((sender, eArgs) => { if (sender.text.length === 0) { furigana.clear(); } }); username.onFocusOut(() => validator.validate(furigana)); const company = new InputMan.GcTextBox(document.getElementById('company'), { watermarkDisplayNullText: '例)入力 株式会社', }); const phone = new InputMan.GcMask(document.getElementById('phone'), { watermarkDisplayNullText: '例)000-0000-0000', formatPattern: '\\D{2,4}-\\D{2,4}-\\D{4}', exitOnLastChar: true, }); // メールアドレス const mail = new InputMan.GcMask(document.getElementById('mail'), { watermarkDisplayNullText: '例)example@gmail.com', formatPattern: '[\\W_.+-]+@[\\W]+.[\\W.]+', exitOnEnterKey: 'enter', }); // お問い合わせ内容 const question = new InputMan.GcMultiLineTextBox( document.getElementById('question'), { height: 100, container: document.querySelector(".display"), showHelpButton: true, helpContent: '200文字以内で入力してしてください。', scrollBarMode: 'automatic', scrollBars: 'vertical', } ); let isPosted = false; document.getElementById('btn').addEventListener('click', () => { if (isPosted) return; if (validator.validate()) { document.getElementById('message').innerText = 'お問い合わせ内容は正しく送信されました。'; document.getElementById('message').classList.remove('falid'); document.getElementById('message').classList.add('posted'); username.clear(); company.clear(); phone.clear(); mail.clear(); question.clear(); validator.destroy(); username.watermarkDisplayNullText = ''; company.watermarkDisplayNullText = ''; phone.watermarkDisplayNullText = ''; mail.watermarkDisplayNullText = ''; question.watermarkDisplayNullText = ''; username.enabled = false; furigana.enabled = false; company.enabled = false; phone.enabled = false; mail.enabled = false; question.enabled = false; isPosted = true; setTimeout(() => { document.getElementById('message').innerText = ''; document.getElementById('message').classList.remove('posted'); }, 5000); } else { document.getElementById('message').innerText = '入力に不備があります、再度お確かめください。'; document.getElementById('message').classList.add('falid'); } }); const validator = new InputMan.GcValidator({ items: [ { control: username, ruleSet: [ { rule: InputMan.ValidateType.Required, }, ], }, { control: furigana, ruleSet: [ { rule: InputMan.ValidateType.Required, }, ], }, { control: company, ruleSet: [ { rule: InputMan.ValidateType.Required, }, ], }, { control: mail, ruleSet: [ { rule: InputMan.ValidateType.Required, }, ], }, { control: question, ruleSet: [ { rule: function (control) { return control.text.length > 0 && control.text.length <= 200; }, }, ], }, ], defaultNotify: { fail: { icon: { direction: InputMan.IconDirection.Inside, }, controlState: true, }, success: { icon: { direction: InputMan.IconDirection.Inside, }, controlState: true, }, }, }); }
<!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="mobile"> <div class="display"> <div class="header"> <h2 class="title">お問い合わせフォーム</h2> </div> <div id="message"></div> <div class="scroll-area"> <span class="tag required">必須</span><span class="label">お名前</span> <div class="margintop"></div> <input id="username" /> <div class="margintop"></div> <span class="tag required">必須</span><span class="label">お名前(ふりがな)</span> <div class="margintop"></div> <input id="furigana" /> <div class="margintop"></div> <span class="tag required">必須</span><span class="label">会社名</span> <div class="margintop"></div> <input id="company" /> <div class="margintop"></div> <span class="tag voluntary">任意</span><span class="label">電話番号</span> <div class="margintop"></div> <input id="phone" /> <div class="margintop"></div> <span class="tag required">必須</span><span class="label">メールアドレス</span> <div class="margintop"></div> <input id="mail" /> <div class="margintop"></div> <span class="tag required">必須</span><span class="label">お問い合わせ内容</span> <div class="margintop"></div> <textarea id="question" class="question"></textarea> <div class="margintop"></div> <a id="btn" class="btn">送信する</a> </div> </div> <div class="btn2"></div> </div> </body> </html>
body { font-family: sans-serif; font-size: 14px; margin: 50px 15px; } .mobile { height: 600px; width: 350px; margin: 0 auto 0; border: 1px solid #cfd8df; background-color: black; border-radius: 50px; } .display { margin-top: 50px; height: 480px; width: 91%; margin-left: 16px; border: 1px solid #cfd8df; background-color: #fff; justify-content: center; border-radius: 5px; } .tag { color: white; font-size: 14px; margin-left: 0.1rem; padding: 0 5px; border-radius: 6px; } .required { background-color: orange; } .voluntary { background-color: rgb(88, 111, 117); } .scroll-area { margin-top: 10%; height: 350px; margin-left: 35px; overflow-y: scroll; } .label { font-size: 15px; font-weight: bold; padding: 0 5px; } .scroll-area::-webkit-scrollbar { display: none; } .gcim{ width: 120% } .gcim_watermark_null { color: lightgrey; } .margintop{ margin-top: 20px; } a.btn { display: block; text-align: center; text-decoration: none; width: 140px; padding: 1rem 2rem; font-weight: bold; border: 2px solid #27acd9; background: #27acd9; color: #fff; transition: 0.5s; margin-left: 15px } a.btn:hover { color: #27acd9; background: #fff; } .btn2 { background-color: whitesmoke; margin-top: 10px; position: relative; left: 43%; width: 45px; height: 45px; border-radius: 50%; } .header{ height: 50px; width: 100%; background-color: lightgrey; display: flex; justify-content: center; align-items: center; } .posted{ background-color: rgba(201, 250, 168, 0.986); height: 30px; text-align: center; font-weight:bold } .falid{ background-color: rgba(245, 233, 202, 0.986); height: 30px; text-align: center; color: red; font-weight:bold } .question .gcim__help-button_tip { background-color: #fff; color: rgb(194, 189, 189); font-weight: bold; font-size: 14px; } .gcim__side-button{ margin-bottom: 142%; }
body { font-family: sans-serif; font-size: 14px; margin: 50px 15px; } [gcim-control-appearance="modern"] .mobile { height: 600px; width: 350px; margin: 0 auto 0; border: 1px solid #cfd8df; background-color: black; border-radius: 50px; } [gcim-control-appearance="modern"] .display { margin-top: 50px; height: 480px; width: 91%; margin-left: 16px; border: 1px solid #cfd8df; background-color: #fff; justify-content: center; border-radius: 5px; } [gcim-control-appearance="modern"] .tag { color: white; font-size: 14px; margin-left: 0.1rem; padding: 0 5px; border-radius: 6px; } [gcim-control-appearance="modern"] .required { background-color: orange; } [gcim-control-appearance="modern"] .voluntary { background-color: rgb(88, 111, 117); } [gcim-control-appearance="modern"] .scroll-area { margin-top: 10%; height: 350px; margin-left: 35px; overflow-y: scroll; } [gcim-control-appearance="modern"] .label { font-size: 15px; font-weight: bold; padding: 0 5px; } [gcim-control-appearance="modern"] .scroll-area::-webkit-scrollbar { display: none; } [gcim-control-appearance="modern"] .gcim { width: 120%; } [gcim-control-appearance="modern"] .gcim_watermark_null { color: lightgrey; } [gcim-control-appearance="modern"] .margintop { margin-top: 20px; } [gcim-control-appearance="modern"] a.btn { display: block; text-align: center; text-decoration: none; width: 140px; padding: 1rem 2rem; font-weight: bold; border: 2px solid #27acd9; background: #27acd9; color: #fff; transition: 0.5s; margin-left: 15px; } [gcim-control-appearance="modern"] a.btn:hover { color: #27acd9; background: #fff; } [gcim-control-appearance="modern"] .btn2 { background-color: whitesmoke; margin-top: 10px; position: relative; left: 43%; width: 45px; height: 45px; border-radius: 50%; } [gcim-control-appearance="modern"] .header { height: 50px; width: 100%; background-color: lightgrey; display: flex; justify-content: center; align-items: center; } [gcim-control-appearance="modern"] .posted { background-color: rgba(201, 250, 168, 0.986); height: 30px; text-align: center; font-weight: bold; } [gcim-control-appearance="modern"] .falid { background-color: rgba(245, 233, 202, 0.986); height: 30px; text-align: center; color: red; font-weight: bold; } [gcim-control-appearance="modern"] .question .gcim__help-button_tip { background-color: #fff; color: rgb(194, 189, 189); font-weight: bold; font-size: 14px; } [gcim-control-appearance="modern"] .gcim__side-button { margin-bottom: 142%; }
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', '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' }, } });