app/Plugin/NZCustomPlugin/Resource/template/default/form.twig line 1

Open in your IDE?
  1. {% extends layout_template|default('default_frame.twig') %}
  2. {% block main %}
  3. <style>
  4. /* フォント強制読み込み */
  5. @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700&display=swap');
  6. * {
  7.     font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Segoe UI", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, "Noto Sans JP", sans-serif !important;
  8. }
  9. /* NZCustomPlugin専用スタイル */
  10. .nzcustom-form-wrapper {
  11.     max-width: 800px;
  12.     margin: 60px auto;
  13.     padding: 0 20px;
  14.     font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  15. }
  16. .nzcustom-form-card {
  17.     background: #ffffff;
  18.     border-radius: 20px;
  19.     box-shadow: 0 10px 40px rgba(0, 0, 0, 0.08);
  20.     overflow: hidden;
  21. }
  22. .nzcustom-form-header {
  23.     background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  24.     padding: 60px 40px;
  25.     text-align: center;
  26. }
  27. .nzcustom-form-title {
  28.     font-size: 42px;
  29.     font-weight: 800;
  30.     color: #ffffff;
  31.     margin: 0 0 16px 0;
  32.     letter-spacing: -0.5px;
  33. }
  34. .nzcustom-form-description {
  35.     font-size: 18px;
  36.     color: rgba(255, 255, 255, 0.95);
  37.     line-height: 1.7;
  38. }
  39. .nzcustom-form-body {
  40.     padding: 50px 40px;
  41. }
  42. .nzcustom-field {
  43.     margin-bottom: 35px;
  44. }
  45. /* 質問タイトル(メインラベル) */
  46. .nzcustom-main-label,
  47. .nzcustom-field > label {
  48.     display: block !important;
  49.     font-size: 16px !important;
  50.     font-weight: 700 !important;
  51.     color: #2d3748 !important;
  52.     margin-bottom: 14px !important;
  53.     line-height: 1.5 !important;
  54. }
  55. .nzcustom-main-label .required,
  56. .nzcustom-field > label .required {
  57.     color: #e53e3e !important;
  58.     margin-left: 4px !important;
  59. }
  60. .nzcustom-field input[type="text"],
  61. .nzcustom-field input[type="email"],
  62. .nzcustom-field input[type="tel"],
  63. .nzcustom-field input[type="number"],
  64. .nzcustom-field input[type="date"],
  65. .nzcustom-field textarea,
  66. .nzcustom-field select,
  67. .nzcustom-field select.form-control,
  68. .nzcustom-field select.form-select {
  69.     width: 100%;
  70.     padding: 5px 18px;
  71.     font-size: 16px;
  72.     color: #2d3748 !important;
  73.     border: 2px solid #e2e8f0;
  74.     border-radius: 10px;
  75.     background: #ffffff !important;
  76.     background-color: #ffffff !important;
  77.     transition: all 0.3s ease;
  78.     font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Segoe UI", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif !important;
  79.     -webkit-text-fill-color: #2d3748 !important;
  80.     opacity: 1 !important;
  81. }
  82. /* プレースホルダーを薄くする */
  83. .nzcustom-field input::placeholder,
  84. .nzcustom-field textarea::placeholder,
  85. .nzcustom-field select::placeholder {
  86.     color: #aaa !important;
  87.     -webkit-text-fill-color: #aaa !important;
  88.     opacity: 1 !important;
  89. }
  90. .nzcustom-field input::-webkit-input-placeholder,
  91. .nzcustom-field textarea::-webkit-input-placeholder,
  92. .nzcustom-field select::-webkit-input-placeholder {
  93.     color: #aaa !important;
  94.     -webkit-text-fill-color: #aaa !important;
  95. }
  96. .nzcustom-field input::-moz-placeholder,
  97. .nzcustom-field textarea::-moz-placeholder,
  98. .nzcustom-field select::-moz-placeholder {
  99.     color: #aaa !important;
  100.     -webkit-text-fill-color: #aaa !important;
  101.     opacity: 1 !important;
  102. }
  103. .nzcustom-field input:-ms-input-placeholder,
  104. .nzcustom-field textarea:-ms-input-placeholder,
  105. .nzcustom-field select:-ms-input-placeholder {
  106.     color: #aaa !important;
  107.     -webkit-text-fill-color: #aaa !important;
  108. }
  109. select#form_question2,
  110. select[id*="question"],
  111. select[id^="form_"],
  112. .nzcustom-field select,
  113. .nzcustom-form-body select {
  114.     color: #2d3748 !important;
  115.     -webkit-text-fill-color: #2d3748 !important;
  116.     background: white !important;
  117.     opacity: 1 !important;
  118.     visibility: visible !important;
  119.     text-indent: 0 !important;
  120.     text-shadow: none !important;
  121.     font-size: 16px !important;
  122.     font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Segoe UI", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif !important;
  123.     height: auto !important;
  124.     min-height: 30px !important;
  125.     line-height: 1.5 !important;
  126. }
  127. .nzcustom-field select option {
  128.     font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Segoe UI", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif !important;
  129. }
  130. .nzcustom-field select::placeholder {
  131.     color: #999 !important;
  132.     opacity: 0.7 !important;
  133. }
  134. .nzcustom-field select:invalid {
  135.     color: #718096 !important;
  136. }
  137. .nzcustom-field select:valid {
  138.     color: #2d3748 !important;
  139. }
  140. .nzcustom-field select {
  141.     background-color: #ffffff !important;
  142.     background-image: none !important;
  143. }
  144. .nzcustom-field select option {
  145.     color: #2d3748 !important;
  146.     background: #ffffff !important;
  147.     padding: 10px;
  148.     font-size: 16px !important;
  149.     opacity: 1 !important;
  150. }
  151. .nzcustom-field select option:checked {
  152.     background: #667eea !important;
  153.     color: #ffffff !important;
  154. }
  155. .nzcustom-field input:focus,
  156. .nzcustom-field textarea:focus,
  157. .nzcustom-field select:focus {
  158.     outline: none;
  159.     border-color: #667eea;
  160.     box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1);
  161. }
  162. .nzcustom-field textarea {
  163.     min-height: 140px;
  164.     resize: vertical;
  165. }
  166. /* チェックボックス・ラジオボタン - カスタムレンダリング */
  167. .nzcustom-choices {
  168.     display: flex;
  169.     flex-direction: column;
  170.     gap: 8px;
  171. }
  172. .nzcustom-choice-item {
  173.     display: flex;
  174.     align-items: center;
  175.     padding: 12px 16px;
  176.     background: #f7fafc;
  177.     border: 2px solid transparent;
  178.     border-radius: 10px;
  179.     cursor: pointer;
  180.     transition: all 0.3s ease;
  181. }
  182. .nzcustom-choice-item:hover {
  183.     background: #edf2f7;
  184.     border-color: #e2e8f0;
  185. }
  186. .nzcustom-choice-item input[type="checkbox"],
  187. .nzcustom-choice-item input[type="radio"] {
  188.     width: 18px;
  189.     height: 18px;
  190.     margin-right: 10px;
  191.     flex-shrink: 0;
  192.     cursor: pointer;
  193. }
  194. .nzcustom-choice-label {
  195.     font-size: 16px !important;
  196.     font-weight: 500 !important;
  197.     color: #2d3748 !important;
  198.     margin: 0 !important;
  199.     cursor: pointer !important;
  200.     line-height: 1.4 !important;
  201.     flex: 1;
  202. }
  203. /* ファイルアップロード */
  204. .nzcustom-file-upload {
  205.     margin-bottom: 35px;
  206. }
  207. .nzcustom-file-drop-area {
  208.     border: 3px dashed #cbd5e0;
  209.     border-radius: 16px;
  210.     padding: 50px 30px;
  211.     text-align: center;
  212.     background: #f7fafc;
  213.     transition: all 0.3s ease;
  214.     cursor: pointer;
  215.     position: relative;
  216. }
  217. .nzcustom-file-drop-area:hover {
  218.     border-color: #667eea;
  219.     background: #edf2f7;
  220. }
  221. .nzcustom-file-icon {
  222.     font-size: 64px;
  223.     margin-bottom: 16px;
  224. }
  225. .nzcustom-file-text {
  226.     font-size: 18px;
  227.     font-weight: 600;
  228.     color: #2d3748;
  229.     margin-bottom: 8px;
  230. }
  231. .nzcustom-file-hint {
  232.     font-size: 14px;
  233.     color: #718096;
  234. }
  235. .nzcustom-file-drop-area input[type="file"] {
  236.     position: absolute;
  237.     opacity: 0;
  238.     width: 100%;
  239.     height: 100%;
  240.     top: 0;
  241.     left: 0;
  242.     cursor: pointer;
  243. }
  244. .nzcustom-file-selected {
  245.     margin-top: 16px;
  246.     padding: 12px 16px;
  247.     background: #e6fffa;
  248.     border: 1px solid #81e6d9;
  249.     border-radius: 8px;
  250.     display: none;
  251.     align-items: center;
  252.     font-size: 14px;
  253.     color: #234e52;
  254. }
  255. .nzcustom-file-selected::before {
  256.     content: '✓';
  257.     margin-right: 8px;
  258.     color: #38b2ac;
  259.     font-weight: bold;
  260. }
  261. /* 送信ボタン */
  262. .nzcustom-submit-btn {
  263.     width: 100%;
  264.     padding: 18px 40px;
  265.     font-size: 18px;
  266.     font-weight: 700;
  267.     color: #ffffff;
  268.     background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  269.     border: none;
  270.     border-radius: 12px;
  271.     cursor: pointer;
  272.     transition: all 0.3s ease;
  273.     box-shadow: 0 4px 20px rgba(102, 126, 234, 0.3);
  274.     margin-top: 20px;
  275. }
  276. .nzcustom-submit-btn:hover {
  277.     transform: translateY(-3px);
  278.     box-shadow: 0 8px 30px rgba(102, 126, 234, 0.4);
  279. }
  280. /* アラート */
  281. .nzcustom-alert {
  282.     background: linear-gradient(135deg, #fef5e7 0%, #fdebd0 100%);
  283.     border-left: 5px solid #f39c12;
  284.     padding: 20px 24px;
  285.     margin-bottom: 30px;
  286.     border-radius: 10px;
  287.     display: flex;
  288.     align-items: center;
  289. }
  290. .nzcustom-alert::before {
  291.     content: 'ℹ️';
  292.     font-size: 24px;
  293.     margin-right: 12px;
  294. }
  295. .nzcustom-alert-text {
  296.     font-size: 15px;
  297.     color: #7d6608;
  298.     font-weight: 500;
  299. }
  300. @media (max-width: 768px) {
  301.     .nzcustom-form-wrapper {
  302.         margin: 30px 15px;
  303.     }
  304.     .nzcustom-form-header {
  305.         padding: 40px 25px;
  306.     }
  307.     .nzcustom-form-title {
  308.         font-size: 32px;
  309.     }
  310.     .nzcustom-form-body {
  311.         padding: 35px 25px;
  312.     }
  313. }
  314. /* 選択肢は中太 */
  315. .nzcustom-choice-label {
  316.     font-weight: 500 !important;
  317. }
  318. /* 日付フィールド - 横並びプルダウン */
  319. .nzcustom-date-selects {
  320.     display: flex;
  321.     align-items: center;
  322.     gap: 8px;
  323.     flex-wrap: wrap;
  324. }
  325. .nzcustom-date-selects select {
  326.     width: auto !important;
  327.     min-width: 80px;
  328.     flex: 1;
  329.     max-width: 120px;
  330.     padding: 5px 12px !important;
  331.     font-size: 16px !important;
  332.     color: #2d3748 !important;
  333.     border: 2px solid #e2e8f0 !important;
  334.     border-radius: 10px !important;
  335.     background: #ffffff !important;
  336.     height: auto !important;
  337.     min-height: 30px !important;
  338.     line-height: 1.5 !important;
  339.     -webkit-appearance: none !important;
  340.     -moz-appearance: none !important;
  341.     appearance: none !important;
  342.     background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23333' d='M6 8L1 3h10z'/%3E%3C/svg%3E") !important;
  343.     background-repeat: no-repeat !important;
  344.     background-position: right 10px center !important;
  345.     padding-right: 30px !important;
  346. }
  347. .nzcustom-date-selects select:focus {
  348.     outline: none;
  349.     border-color: #667eea !important;
  350.     box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1);
  351. }
  352. .nzcustom-date-label {
  353.     font-size: 16px;
  354.     font-weight: 500;
  355.     color: #2d3748;
  356.     margin-right: 12px;
  357. }
  358. @media (max-width: 480px) {
  359.     .nzcustom-date-selects {
  360.         flex-direction: row;
  361.         justify-content: space-between;
  362.     }
  363.     .nzcustom-date-selects select {
  364.         min-width: 60px;
  365.         max-width: none;
  366.         flex: 1;
  367.     }
  368.     .nzcustom-date-label {
  369.         margin-right: 8px;
  370.     }
  371. }
  372. </style>
  373. <div class="nzcustom-form-wrapper">
  374.     <div class="nzcustom-form-card">
  375.         <div class="nzcustom-form-header">
  376.             <h1 class="nzcustom-form-title">{{ customForm.name }}</h1>
  377.             {% if customForm.description %}
  378.             <div class="nzcustom-form-description">{{ customForm.description|raw }}</div>
  379.             {% endif %}
  380.         </div>
  381.         
  382.         <div class="nzcustom-form-body">
  383.             {% if app.user %}
  384.             <div class="nzcustom-alert">
  385.                 <div class="nzcustom-alert-text">会員情報から自動入力されています。必要に応じて修正してください。</div>
  386.             </div>
  387.             {% endif %}
  388.             
  389.             {{ form_start(form) }}
  390.             
  391.             {% for field in form %}
  392.                 {% if field.vars.name != '_token' and field.vars.block_prefixes[1] != 'submit' %}
  393.                     <div class="nzcustom-field">
  394.                         <div class="nzcustom-main-label">
  395.                             {{ field.vars.label }}
  396.                             {% if field.vars.required is defined and field.vars.required %}
  397.                                 <span class="required">*</span>
  398.                             {% endif %}
  399.                         </div>
  400.                         
  401.                         {% if field.vars.block_prefixes[1] == 'file' %}
  402.                             <div class="nzcustom-file-upload">
  403.                                 <div class="nzcustom-file-drop-area" id="file-drop-{{ field.vars.id }}">
  404.                                     <div class="nzcustom-file-icon">📁</div>
  405.                                     <div class="nzcustom-file-text">ファイルを選択</div>
  406.                                     <div class="nzcustom-file-hint">クリックしてファイルを選択<br>対応形式: PDF, Word, Excel, 画像 (最大5MB)</div>
  407.                                     {{ form_widget(field) }}
  408.                                 </div>
  409.                                 <div class="nzcustom-file-selected" id="file-selected-{{ field.vars.id }}">
  410.                                     <span class="file-name"></span>
  411.                                 </div>
  412.                             </div>
  413.                         {% elseif field.vars.block_prefixes[1] == 'choice' and field.vars.expanded == false %}
  414.                             {{ form_widget(field) }}
  415.                         {% elseif field.vars.block_prefixes[1] == 'date' %}
  416.                             {# 日付フィールド - 横並びプルダウン #}
  417.                             <div class="nzcustom-date-selects">
  418.                                 {{ form_widget(field.year) }}<span class="nzcustom-date-label">年</span>
  419.                                 {{ form_widget(field.month) }}<span class="nzcustom-date-label">月</span>
  420.                                 {{ form_widget(field.day) }}<span class="nzcustom-date-label">日</span>
  421.                             </div>
  422.                         {% elseif field.vars.block_prefixes[1] == 'choice' and field.vars.expanded == true %}
  423.                             <div class="nzcustom-choices">
  424.                                 {% for child in field %}
  425.                                     <div class="nzcustom-choice-item">
  426.                                         <input type="{{ field.vars.multiple ? 'checkbox' : 'radio' }}" 
  427.                                                id="{{ child.vars.id }}" 
  428.                                                name="{{ child.vars.full_name }}" 
  429.                                                value="{{ child.vars.value }}"
  430.                                                {% if child.vars.checked %}checked="checked"{% endif %}
  431.                                                {% if child.vars.disabled %}disabled="disabled"{% endif %}>
  432.                                         <label for="{{ child.vars.id }}" class="nzcustom-choice-label">
  433.                                             {{ child.vars.label }}
  434.                                         </label>
  435.                                     </div>
  436.                                 {% endfor %}
  437.                             </div>
  438.                         {% else %}
  439.                             {{ form_widget(field) }}
  440.                         {% endif %}
  441.                         
  442.                         {{ form_errors(field) }}
  443.                     </div>
  444.                 {% endif %}
  445.             {% endfor %}
  446.             
  447.             {{ form_widget(form._token) }}
  448.             
  449.             <button type="submit" class="nzcustom-submit-btn">送信する</button>
  450.             
  451.             {{ form_end(form, {'render_rest': false}) }}
  452.         </div>
  453.     </div>
  454. </div>
  455. {{ nz_recaptcha_script('form') }}
  456. <script>
  457. document.addEventListener('DOMContentLoaded', function() {
  458.     // ファイルアップロード
  459.     document.querySelectorAll('.nzcustom-file-drop-area').forEach(function(dropArea) {
  460.         const fileInput = dropArea.querySelector('input[type="file"]');
  461.         if (!fileInput) return;
  462.         
  463.         const fileId = dropArea.id.replace('file-drop-', '');
  464.         const selectedDiv = document.getElementById('file-selected-' + fileId);
  465.         
  466.         fileInput.addEventListener('change', function(e) {
  467.             if (this.files.length > 0) {
  468.                 const fileName = this.files[0].name;
  469.                 selectedDiv.querySelector('.file-name').textContent = fileName;
  470.                 selectedDiv.style.display = 'flex';
  471.             }
  472.         });
  473.         
  474.         dropArea.addEventListener('dragover', function(e) {
  475.             e.preventDefault();
  476.             this.style.borderColor = '#667eea';
  477.             this.style.background = '#edf2f7';
  478.         });
  479.         
  480.         dropArea.addEventListener('dragleave', function(e) {
  481.             e.preventDefault();
  482.             this.style.borderColor = '#cbd5e0';
  483.             this.style.background = '#f7fafc';
  484.         });
  485.         
  486.         dropArea.addEventListener('drop', function(e) {
  487.             e.preventDefault();
  488.             this.style.borderColor = '#cbd5e0';
  489.             this.style.background = '#f7fafc';
  490.             
  491.             if (e.dataTransfer.files.length > 0) {
  492.                 fileInput.files = e.dataTransfer.files;
  493.                 const fileName = e.dataTransfer.files[0].name;
  494.                 selectedDiv.querySelector('.file-name').textContent = fileName;
  495.                 selectedDiv.style.display = 'flex';
  496.             }
  497.         });
  498.     });
  499. });
  500. </script>
  501. {% endblock %}