@modernman00/shared-js-lib 1.2.75 → 1.2.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AcctMgt/code.js CHANGED
@@ -18,7 +18,8 @@ export function createCodeSubmitHandler({
18
18
  redirect,
19
19
  theme,
20
20
  lengthLimit: lengthLimitArray,
21
- optionalFields: [inputId],
21
+ optionalFields: [],
22
22
  recaptchaAction
23
23
  });
24
24
  }
25
+ // testing
package/AcctMgt/forgot.js CHANGED
@@ -18,7 +18,7 @@ export function forgotSubmitHandler({
18
18
  redirect,
19
19
  theme,
20
20
  lengthLimit: lengthLimitArray,
21
- optionalFields: [inputId],
21
+ optionalFields: [],
22
22
  recaptchaAction
23
23
  });
24
24
  }
@@ -18,6 +18,11 @@ export const loginSubmission = async ({
18
18
  optionalFields = [],
19
19
  recaptchaToken = null // { token, action } or null
20
20
  }) => {
21
+ let loaderClasses = "loader";
22
+ if (css === 'tailwind') {
23
+ loaderClasses = "animate-spin mx-auto block w-10 h-10 border-4 border-blue-600 border-t-transparent rounded-full";
24
+ }
25
+
21
26
  try {
22
27
  const formInput = id(formId);
23
28
 
@@ -37,14 +42,17 @@ export const loginSubmission = async ({
37
42
  formData.massValidate(optionalFields, { email: 'email', password: 'password' });
38
43
 
39
44
  if (formData.result !== 1) {
40
- alert('The form cannot be submitted. Please check the errors');
45
+ const firstError = document.querySelector('[id$="_error"]:not(:empty)');
46
+ if (firstError) {
47
+ firstError.scrollIntoView({ behavior: 'smooth', block: 'center' });
48
+ }
41
49
  return;
42
50
  }
43
51
 
44
52
  const notificationElement = id(`${formId}_notification`) || formInput;
45
53
  notificationElement.scrollIntoView({ behavior: 'smooth' });
46
54
 
47
- showLoader();
55
+ showLoader('setLoader', loaderClasses);
48
56
  localStorage.setItem('redirect', redirect);
49
57
 
50
58
  await postFormData(loginURL, formId, redirect, css, recaptchaToken);
@@ -52,6 +60,6 @@ export const loginSubmission = async ({
52
60
  } catch (err) {
53
61
  showError(err);
54
62
  } finally {
55
- clearLoader();
63
+ clearLoader('setLoader', loaderClasses);
56
64
  }
57
65
  };
package/Cookie.js CHANGED
@@ -7,7 +7,7 @@
7
7
  */
8
8
  export const setCookie = (cname, cvalue, exdays = 365) => {
9
9
  const d = new Date(Date.now() + exdays * 864e5);
10
- document.cookie = `${cname}=${cvalue}; expires=${d.toUTCString()}; path=/`;
10
+ document.cookie = `${cname}=${cvalue}; expires=${d.toUTCString()}; path=/; SameSite=Lax`;
11
11
  }
12
12
 
13
13
  /**
package/DateTime.js CHANGED
@@ -45,8 +45,10 @@ let element = document.querySelectorAll('time[data-time]')
45
45
  */
46
46
  export const updateTimeRealTime = () => {
47
47
  for (const entry of element) {
48
- const seconds = (Date.now() - new Date(entry.dataset.time).getTime()) / 1000;
49
- entry.textContent = getDuration(seconds);
48
+ try {
49
+ const seconds = (Date.now() - new Date(entry.dataset.time).getTime()) / 1000;
50
+ entry.textContent = getDuration(seconds);
51
+ } catch (_) { /* skip malformed entry, continue updating others */ }
50
52
  }
51
53
  setTimeout(updateTimeRealTime, 1000 * 60);
52
54
  };
@@ -93,9 +95,11 @@ const getDuration = (timeAgoInSeconds) => {
93
95
  */
94
96
  export const timeAgo = (date) => {
95
97
  const timeAgoInSeconds = Math.floor((new Date() - new Date(date)) / 1000);
96
- const { interval, epoch } = getDuration(timeAgoInSeconds);
98
+ const duration = getDuration(timeAgoInSeconds);
99
+ if (!duration) return '0 seconds ago';
100
+ const { interval, epoch } = duration;
97
101
  const suffix = interval === 1 ? '' : 's';
98
102
  return `${interval} ${epoch}${suffix} ago`;
99
103
  };
100
104
 
101
- export const date2String = (date) => new Date().toDateString(date)
105
+ export const date2String = (date) => new Date(date).toDateString()
package/FileUpload.js CHANGED
@@ -9,8 +9,11 @@ import { id } from './UtilityHtml.js';
9
9
  * @param {string} fileName - the id of the element where the selected file names will be displayed.
10
10
  */
11
11
  export const showImageFileUploadFn = (uploadBtn, inputId, fileName) => {
12
+ const btn = id(uploadBtn);
12
13
  const input = id(inputId);
13
14
  const fileNamesEl = id(fileName);
14
- id(uploadBtn).addEventListener('click', () => input.click());
15
+ if (!btn || !input || !fileNamesEl) return;
16
+
17
+ btn.addEventListener('click', () => input.click());
15
18
  input.addEventListener('change', () => fileNamesEl.innerText = Array.from(input.files).map(file => file.name).join(', '));
16
19
  };
package/FormHelper.js CHANGED
@@ -114,10 +114,15 @@ export default class FormHelper {
114
114
  !id ||
115
115
  ['submit', 'button', 'g-recaptcha-response', 'cancel'].includes(name) ||
116
116
  ['button', 'showPassword', 'token', 'g-recaptcha-response'].includes(id) ||
117
- type === 'button' || optionalFields.includes(id) ||
118
- id === 'checkbox'
117
+ type === 'button' || optionalFields.includes(id)
119
118
  ) continue;
120
119
 
120
+ // Skip hidden elements (if the user can't see it, they can't fill it)
121
+ const el = this.id(id);
122
+ if (el && (el.offsetParent === null || window.getComputedStyle(el).display === 'none')) {
123
+ continue;
124
+ }
125
+
121
126
 
122
127
 
123
128
 
@@ -131,7 +136,7 @@ export default class FormHelper {
131
136
  }
132
137
 
133
138
  // Required field check
134
- if (val === '' || val === 'select') {
139
+ if (val === '' || val === 'select' || (type === 'checkbox' && !input.checked)) {
135
140
  if (errorEl) errorEl.innerHTML = `<li style="color:red;">${id} cannot be left empty.</li>`;
136
141
  this.error.push(`${id.toUpperCase()} cannot be left empty.`);
137
142
  continue;
package/Http.js CHANGED
@@ -96,6 +96,7 @@ export const postFormData = async (url, formId, redirect = null, css = null, rec
96
96
  const processFormDataAction = (cssClass, message, formNotificationId) => {
97
97
  if (formNotificationId) {
98
98
  formNotificationId.style.display = 'block';
99
+ formNotificationId.classList.add('notification');
99
100
  formNotificationId.classList.add(cssClass);
100
101
 
101
102
  const errorElement = id('error');
@@ -103,7 +104,12 @@ const processFormDataAction = (cssClass, message, formNotificationId) => {
103
104
  errorElement.scrollIntoView({ behavior: 'smooth' });
104
105
  errorElement.style.color = 'white';
105
106
  errorElement.innerHTML = message;
107
+ } else {
108
+ // Ensure we scroll to the notification if no specific error element exists
109
+ formNotificationId.scrollIntoView({ behavior: 'smooth', block: 'center' });
106
110
  }
111
+ formNotificationId.innerHTML = message;
112
+
107
113
  const loader = id('setLoader');
108
114
  if (loader) loader.classList.remove('loader');
109
115
  } else {
package/Loader.js CHANGED
@@ -24,14 +24,17 @@ export const clearLoader = (elementId = 'setLoader', loaderClass = "loader") =>
24
24
  }
25
25
 
26
26
  loader.style.display = "none";
27
- loader.classList.remove(loaderClass);
28
-
27
+ loaderClass.split(' ').forEach(cls => {
28
+ if (cls) loader.classList.remove(cls);
29
+ });
29
30
  }
30
31
  export const showLoader = (elementId ='setLoader', loaderClass = "loader") => {
31
32
  const loader = id(elementId);
32
33
  if (!loader) {
33
34
  throw new Error(`Element not found`);
34
35
  }
35
- loader.classList.add(loaderClass);
36
+ loaderClass.split(' ').forEach(cls => {
37
+ if (cls) loader.classList.add(cls);
38
+ });
36
39
  loader.style.display = "block";
37
40
  };
package/ShowResponse.js CHANGED
@@ -22,16 +22,22 @@ export const showNotification = (
22
22
  message,
23
23
  timer = 5000,
24
24
  ) => {
25
- // display the success information for 10sec
26
- id(`${elementId}`).style.display = 'block'; // unblock the notification
27
- id(`${elementId}`).classList.add(addClass); // add the success class
28
- id(`${elementId}`).innerHTML = message; // error element
29
- id('loader').classList.remove('loader'); // remove loader
25
+ const el = id(`${elementId}`);
26
+ if (!el) return;
27
+
28
+ el.style.display = 'block';
29
+ el.classList.add(addClass);
30
+ el.innerHTML = message;
31
+
32
+ const loaderEl = id('loader');
33
+ if (loaderEl) loaderEl.classList.remove('loader');
30
34
 
31
35
  setTimeout(() => {
32
- id(`${elementId}`).style.backgroundColor = '';
33
- id(`${elementId}`).style.color = '';
34
- id(`${elementId}`).innerHTML = '';
36
+ const target = id(`${elementId}`);
37
+ if (!target) return;
38
+ target.style.backgroundColor = '';
39
+ target.style.color = '';
40
+ target.innerHTML = '';
35
41
  }, timer);
36
42
  };
37
43
 
@@ -39,10 +45,10 @@ export const showNotification = (
39
45
 
40
46
  export const showResponse = (theId, message, status) => {
41
47
  const responseEl = id(theId);
42
- const col = status ? 'green' : 'red';
48
+ if (!responseEl) return;
43
49
 
50
+ const col = status ? 'green' : 'red';
44
51
  responseEl.innerHTML = message;
45
- responseEl.style.color = 'green';
46
52
  responseEl.style.backgroundColor = col;
47
53
  responseEl.style.color = 'white';
48
54
  setTimeout(() => {
package/axiosWrapper.js CHANGED
@@ -4,16 +4,14 @@ import axiosRetry from 'axios-retry';
4
4
 
5
5
  axiosRetry(axios, { retries: 3 });
6
6
 
7
- const csrfToken = getCookieValue('XSRF-TOKEN');
8
-
9
7
  axios.interceptors.request.use(config => {
10
8
  config.headers['X-Requested-With'] = 'XMLHttpRequest';
11
- // config.headers['Accept'] = 'application/json';
12
9
 
10
+ const csrfToken = getCookieValue('XSRF-TOKEN');
13
11
  if (csrfToken) {
14
12
  config.headers['X-XSRF-TOKEN'] = csrfToken;
15
13
  }
16
-
14
+
17
15
  return config;
18
16
  });
19
17
 
@@ -1,3 +1,3 @@
1
1
  <?php
2
- define('APP_VERSION', 'v1.2.74');
2
+ define('APP_VERSION', 'v1.2.75');
3
3
 
package/general.js CHANGED
@@ -14,6 +14,8 @@ export const matchInput = (first, second, err) => {
14
14
  firstInput = id(first);
15
15
  secondInput = id(second);
16
16
 
17
+ if (!error || !firstInput || !secondInput) return;
18
+
17
19
  secondInput.addEventListener('keyup', () => {
18
20
 
19
21
  if (secondInput.value !== firstInput.value) {
@@ -61,10 +63,12 @@ export const parseErrorResponse = (error) => {
61
63
 
62
64
  export const showFileName = (fileCss) => {
63
65
  const fileInput = document.querySelector(`#${fileCss} input[type=file]`);
66
+ if (!fileInput) return;
67
+
64
68
  fileInput.onchange = () => {
65
69
  if (fileInput.files.length > 0) {
66
70
  const fileName = document.querySelector(`#${fileCss} .file-name`);
67
- fileName.textContent = fileInput.files[0].name;
71
+ if (fileName) fileName.textContent = fileInput.files[0].name;
68
72
  }
69
73
  };
70
74
  }
package/index.js CHANGED
@@ -4,7 +4,6 @@ export * from './Utility.js';
4
4
  export * from './Loader.js';
5
5
  export * from './Cookie.js';
6
6
  export * from './FormHelper.js'
7
- export * from './Loader.js';
8
7
  export * from './ShowResponse.js';
9
8
  export * from './DateTime.js';
10
9
  export * from './CountryCode.js'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modernman00/shared-js-lib",
3
- "version": "1.2.75",
3
+ "version": "1.2.81",
4
4
  "description": "Reusable JS utilities for numerous js problems",
5
5
  "homepage": "https://github.com/modernman00/shared-js-lib#readme",
6
6
  "keywords": [