PageSourceSearch

https://www.cesa2drivered.org/clibs/js/form_validator.js

js cesa2drivered.org collected 2026-10-10 00:11:55 UTC 5,523 bytes, 207 lines download raw bytes

1(function()
2{
3  var _form_elements = document.querySelectorAll('form') || [];
4  var _optional_require = document.querySelectorAll('.optional-require') || [];
5
6  // Wait until all page assets has fully loaded such as the captcha script
7  window.addEventListener('load', function()
8  {
9    //****************************************
10    // Add event listeners to required fields
11    //****************************************
12
13    if(_form_elements.length > 0)
14    {
15      _form_elements.forEach(function(form_element)
16      {
17        var required_fields = form_element.querySelectorAll('[required]') || [];
18        var submit_button = form_element.querySelector('[type="submit"]') || false;
19
20        if(required_fields.length > 0 && submit_button)
21        {
22          required_fields.forEach(function(field)
23          {
24            // Determine if there is a value in the field (used for the animated label on top the input style)
25            Validate_Empty_Field(field);
26
27            field.addEventListener('keyup', function()
28            {
29              Validate_Empty_Field(this);
30            });
31
32            field.addEventListener('change', function()
33            {
34              Validate_Empty_Field(this);
35            });
36
37            // Validate field immediately after it's out of focus
38            field.addEventListener('blur', function()
39            {
40              Validate_Field(form_element, this);
41            });
42
43            // Prevent validity message from displaying
44            field.addEventListener('invalid', function(e)
45            {
46              e.preventDefault();
47            });
48          });
49
50          // Validate all fields when the submit button is clicked
51          submit_button.addEventListener('click', function()
52          {
53            required_fields.forEach(function(field)
54            {
55              Validate_Field(form_element, field);
56            });
57          });
58
59          // Disable the submit button to prevent accident spamming
60          form_element.addEventListener('submit', function()
61          {
62            submit_button.disabled = true;
63          });
64
65          // Enable submit button
66          // Prevents the submit button from being disabled when using the back button in the browser to this page
67          window.addEventListener('visibilitychange', function()
68          {
69            submit_button.disabled = false;
70          });
71        }
72      });
73    }
74
75    //****************************************
76    // Optional require sections
77    // Watch for any fields in the section to be populated with a value, then makes all the fields in the section required
78    //****************************************
79
80    if(_optional_require.length > 0)
81    {
82      _optional_require.forEach(function(section)
83      {
84        var fields = section.querySelectorAll('input, select, textarea') || [];
85
86        Update_Fields_Require_Attr(fields);
87
88        fields.forEach(function(field)
89        {
90          field.addEventListener('blur', function()
91          {
92            Update_Fields_Require_Attr(fields);
93          });
94        });
95      });
96    }
97  });
98
99  //****************************************
100  // Validate empty field
101  //****************************************
102
103  function Validate_Empty_Field(field)
104  {
105    if(field.type !== 'fieldset')
106    {
107      if(field.value.length > 0)
108      {
109        field.classList.add('entered');
110      }
111      else
112      {
113        field.classList.remove('entered');
114      }
115    }
116  }
117
118  //****************************************
119  // Validate Fields
120  //****************************************
121
122  function Validate_Field(form, field)
123  {
124    var valid = field.checkValidity();
125
126    if(field.type === 'fieldset')
127    {
128      // Add highlight to legend if invalid
129      var legend = field.querySelector('legend') || false;
130
131      if(legend)
132      {
133        if(valid)
134        {
135          legend.classList.remove('invalid');
136        }
137        else
138        {
139          legend.classList.add('invalid');
140        }
141      }
142    }
143    else
144    {
145      // Add highlight to field if invalid
146      if(valid)
147      {
148        field.classList.remove('invalid');
149      }
150      else
151      {
152        field.classList.add('invalid');
153      }
154
155      // Attempt to remove label highlight if available
156      var label = form.querySelector('label[for="' + field.id + '"]') || false;
157
158      if(label)
159      {
160        if(valid)
161        {
162          label.classList.remove('invalid');
163        }
164        else
165        {
166          label.classList.add('invalid');
167        }
168      }
169    }
170  }
171
172  //****************************************
173  // Update fields require attribute
174  //****************************************
175
176  function Update_Fields_Require_Attr(fields)
177  {
178    var require = false;
179
180    // Find a field with a value in the section. If one is found, all fields will be marked as required
181    //  Using breakable for loop to stop the loop once the criteria has been met
182    for(var i = 0; i < fields.length; i++)
183    {
184      if(fields[i].value !== '')
185      {
186        require = true;
187        break;
188      }
189    }
190
191    // Update all the fields in the section
192    fields.forEach(function(field)
193    {
194      // Capture the current require state if the new state is false
195      var validate_field = (!require && field.required);
196
197      // Update the new require state
198      field.required = require;
199
200      // Re-validate the field if the previous state was true
201      if(validate_field)
202      {
203        Validate_Field(field);
204      }
205    });
206  }
207})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.