templates/app/partials/_teacher_fields_js.html.twig line 1

Open in your IDE?
  1. {# JS for the shared teacher fields partial.
  2.  # Param: country_selector = jQuery selector of a country <select> to gate the
  3.  #        school autocomplete dynamically (optional). When omitted, the initial
  4.  #        CZ visibility comes from the wrapper's data-cz flag. #}
  5. <script nonce="{{ app_nonce() }}">
  6.   $(function () {
  7.     const $school = $('#teacher_school');
  8.     const $schoolWrapper = $('[data-school-wrapper]');
  9.     const $schoolTypeOther = $('[data-school-type-other]');
  10.     const $schoolTypeOtherInput = $('#teacher_school_type_other');
  11.     const countrySelector = '{{ country_selector|default('')|e('js') }}';
  12.     const $country = countrySelector ? $(countrySelector) : $();
  13.     function selectedKind () {
  14.       return $('input[name="teacher_school_type"]:checked').val() || '';
  15.     }
  16.     function isOtherSelected () {
  17.       return selectedKind() === 'other';
  18.     }
  19.     function isCz () {
  20.       if ($country.length) {
  21.         return ($country.val() || '').toUpperCase() === 'CZ';
  22.       }
  23.       return String($schoolWrapper.data('cz')) === '1';
  24.     }
  25.     if ($school.length && $.fn.select2) {
  26.       $school.select2({
  27.         placeholder: '{{ 'register.school.placeholder'|trans|e('js') }}',
  28.         allowClear: true,
  29.         width: '100%',
  30.         minimumInputLength: 2,
  31.         ajax: {
  32.           url: $school.data('schools-url'),
  33.           dataType: 'json',
  34.           delay: 200,
  35.           cache: true,
  36.           data: function (params) {
  37.             return {
  38.               q: params.term || '',
  39.               kind: selectedKind()
  40.             };
  41.           },
  42.           processResults: function (data) {
  43.             return { results: data.results || [] };
  44.           }
  45.         },
  46.         templateResult: function (item) {
  47.           if (!item.id) { return item.text; }
  48.           const name = item.name || item.text;
  49.           const addr = item.address || '';
  50.           const $row = $('<div class="register-school__item"></div>');
  51.           $row.append($('<div class="register-school__name"></div>').text(name));
  52.           if (addr) {
  53.             $row.append($('<div class="register-school__addr"></div>').text(addr));
  54.           }
  55.           return $row;
  56.         },
  57.         templateSelection: function (item) {
  58.           return item.name || item.text || '';
  59.         },
  60.         language: {
  61.           inputTooShort: function (args) {
  62.             const n = args.minimum - args.input.length;
  63.             if ('{{ app.request.locale }}' === 'cs') {
  64.               return 'Zadejte ještě ' + n + ' znak' + (n === 1 ? '' : (n < 5 ? 'y' : 'ů'));
  65.             }
  66.             return 'Please enter ' + n + ' more character' + (n === 1 ? '' : 's');
  67.           },
  68.           noResults: function () { return '{{ 'register.school.noresults'|trans|e('js') }}'; },
  69.           searching: function () { return '{{ 'register.school.searching'|trans|e('js') }}'; },
  70.           errorLoading: function () { return '{{ 'register.school.error'|trans|e('js') }}'; }
  71.         }
  72.       });
  73.     }
  74.     // Visibility only - safe to call on init without wiping a prefilled school.
  75.     function applyVisibility () {
  76.       const cz = isCz();
  77.       const $czOptions = $('[data-country="cz"]');
  78.       const $otherOptions = $('[data-country="other"]');
  79.       if (cz) {
  80.         $czOptions.show();
  81.         $czOptions.find('input').prop('disabled', false);
  82.         $otherOptions.hide();
  83.         $otherOptions.find('input').prop('disabled', true).prop('checked', false);
  84.       } else {
  85.         $czOptions.hide();
  86.         $czOptions.find('input').prop('disabled', true).prop('checked', false);
  87.         $otherOptions.show();
  88.         $otherOptions.find('input').prop('disabled', false);
  89.       }
  90.       const other = isOtherSelected();
  91.       $schoolWrapper.prop('hidden', !cz || other);
  92.       $schoolTypeOther.prop('hidden', !other);
  93.     }
  94.     // User-driven change: also reset the previously selected school so the kind
  95.     // filter takes effect and clear the "other" text when it no longer applies.
  96.     function onUserChange () {
  97.       applyVisibility();
  98.       if (isOtherSelected()) {
  99.         $schoolTypeOtherInput.trigger('focus');
  100.       } else {
  101.         $schoolTypeOtherInput.val('');
  102.       }
  103.       if ($school.length) {
  104.         $school.val(null).trigger('change.select2');
  105.       }
  106.     }
  107.     if ($country.length) {
  108.       $country.on('change', onUserChange);
  109.     }
  110.     $(document).on('change', 'input[name="teacher_school_type"]', onUserChange);
  111.     applyVisibility();
  112.   });
  113. </script>