ap-laravel-ajax-helper 1.0.0 → 1.0.2
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/README.md +69 -29
- package/dist/laravel-ajax.cjs.js +107 -0
- package/dist/laravel-ajax.esm.js +87 -0
- package/dist/laravel-ajax.min.js +1 -0
- package/package.json +22 -7
- package/src/index.js +45 -20
- package/dist/index.js +0 -81
package/README.md
CHANGED
@@ -1,24 +1,46 @@
|
|
1
1
|
# Laravel AJAX Helper
|
2
2
|
|
3
|
-
A lightweight utility to simplify Laravel
|
3
|
+
A lightweight JavaScript utility to simplify AJAX requests in Laravel applications. Handles CSRF protection, form data submission, and validation error display with minimal setup.
|
4
4
|
|
5
|
-
|
5
|
+
---
|
6
6
|
|
7
|
-
|
7
|
+
## 🚀 Features
|
8
|
+
|
9
|
+
* ✅ One-liner AJAX integration with Laravel routes
|
10
|
+
* ✅ Automatically appends CSRF token from `<meta name="csrf-token">`
|
11
|
+
* ✅ Displays validation errors in `.error-[field_name]` elements
|
12
|
+
* ✅ Optional loading spinner with button text
|
13
|
+
* ✅ Built for modern browsers and Laravel developers
|
14
|
+
|
15
|
+
---
|
16
|
+
|
17
|
+
## 📦 Installation
|
18
|
+
|
19
|
+
```bash
|
20
|
+
npm install laravel-ajax-helper
|
21
|
+
```
|
22
|
+
|
23
|
+
---
|
24
|
+
|
25
|
+
## 📄 HTML Form Example
|
26
|
+
|
27
|
+
Add proper `name` attributes to inputs and matching `.error-[field_name]` spans for error display.
|
8
28
|
|
9
29
|
```html
|
10
30
|
<form id="loginForm">
|
11
31
|
<input type="email" name="email" />
|
12
|
-
<span class="error-email
|
32
|
+
<span class="error-email"></span>
|
13
33
|
|
14
34
|
<input type="password" name="password" />
|
15
|
-
<span class="error-password
|
35
|
+
<span class="error-password"></span>
|
16
36
|
|
17
37
|
<button id="loginBtn">Login</button>
|
18
38
|
</form>
|
19
39
|
```
|
20
40
|
|
21
|
-
|
41
|
+
---
|
42
|
+
|
43
|
+
## 🧠 JavaScript Usage
|
22
44
|
|
23
45
|
```js
|
24
46
|
import laravelAjax from 'laravel-ajax-helper';
|
@@ -28,7 +50,8 @@ laravelAjax({
|
|
28
50
|
method: 'POST',
|
29
51
|
formId: 'loginForm',
|
30
52
|
buttonId: 'loginBtn',
|
31
|
-
loadingText: 'Logging in...'
|
53
|
+
loadingText: 'Logging in...',
|
54
|
+
csrf: true // Will read from <meta name="csrf-token" content="...">
|
32
55
|
})
|
33
56
|
.then(response => {
|
34
57
|
console.log('Success:', response);
|
@@ -38,45 +61,62 @@ laravelAjax({
|
|
38
61
|
});
|
39
62
|
```
|
40
63
|
|
41
|
-
|
64
|
+
---
|
65
|
+
|
66
|
+
## ⚙️ Parameters
|
67
|
+
|
68
|
+
| Parameter | Type | Required | Description |
|
69
|
+
| ------------- | ------- | -------- | ----------------------------------------------------------------------------- |
|
70
|
+
| `url` | string | ✅ Yes | Laravel route URL. |
|
71
|
+
| `method` | string | ❌ No | HTTP method: 'POST', 'GET', 'PUT', 'DELETE'. Defaults to `'POST'`. |
|
72
|
+
| `formId` | string | ✅ Yes | HTML form ID (grabs data from inputs). |
|
73
|
+
| `buttonId` | string | ❌ No | Button ID for loading state UX. |
|
74
|
+
| `loadingText` | string | ❌ No | Text to show with spinner while loading. Defaults to `'Loading...'`. |
|
75
|
+
| `csrf` | boolean | ❌ No | If `true`, automatically uses `<meta name="csrf-token">`. Defaults to `true`. |
|
76
|
+
|
77
|
+
---
|
78
|
+
|
79
|
+
## ❗️ CSRF Handling
|
80
|
+
|
81
|
+
If `csrf: true` and no meta tag is found, the function will throw an error.
|
82
|
+
|
83
|
+
Make sure your HTML includes:
|
84
|
+
|
85
|
+
```html
|
86
|
+
<meta name="csrf-token" content="{{ csrf_token() }}">
|
87
|
+
```
|
42
88
|
|
43
|
-
|
44
|
-
| ------------- | ------ | -------- | -------------------------------------------------------------------- |
|
45
|
-
| `url` | string | ✅ Yes | The Laravel route URL for the AJAX request. |
|
46
|
-
| `method` | string | ❌ No | Request method: 'POST', 'GET', 'PUT', 'DELETE'. Default: 'POST'. |
|
47
|
-
| `formId` | string | ✅ Yes | ID of the form element (do not pass form data manually). |
|
48
|
-
| `buttonId` | string | ❌ No | ID of the button to show a loading spinner during request. |
|
49
|
-
| `loadingText` | string | ❌ No | Text to show with spinner during the request. Default: 'Loading...'. |
|
89
|
+
---
|
50
90
|
|
51
|
-
##
|
91
|
+
## ⚠️ Error Handling
|
52
92
|
|
53
|
-
*
|
93
|
+
* **422 Validation Errors**: Automatically shown in `.error-[field_name]` spans.
|
94
|
+
* **Other Errors (500, 403, etc.)**: Logged to console or returned via `.catch()`.
|
54
95
|
|
55
|
-
|
56
|
-
* On other errors (like 500), a generic error is returned.
|
96
|
+
---
|
57
97
|
|
58
|
-
## 📁 File Structure
|
98
|
+
## 📁 File Structure
|
59
99
|
|
60
100
|
```
|
61
101
|
laravel-ajax-helper/
|
62
|
-
├── dist/
|
63
|
-
│ └── index.js # Transpiled output
|
102
|
+
├── dist/ # Compiled code
|
64
103
|
├── src/
|
65
|
-
│ └── index.js #
|
104
|
+
│ └── index.js # Core logic
|
66
105
|
├── README.md
|
67
106
|
├── LICENSE
|
68
107
|
├── package.json
|
69
108
|
```
|
70
109
|
|
71
|
-
|
110
|
+
---
|
72
111
|
|
73
|
-
|
112
|
+
## 🗪 License
|
74
113
|
|
75
|
-
|
114
|
+
Licensed under the MIT License.
|
76
115
|
|
77
|
-
|
116
|
+
---
|
78
117
|
|
79
118
|
## 💬 Author
|
80
119
|
|
81
|
-
Akash Ap
|
82
|
-
Built with ❤️ for Laravel developers
|
120
|
+
**Akash Ap**
|
121
|
+
Built with ❤️ for Laravel developers
|
122
|
+
GitHub: [@aakashap01](https://github.com/aakashap01)
|
@@ -0,0 +1,107 @@
|
|
1
|
+
var __defProp = Object.defineProperty;
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
5
|
+
var __export = (target, all) => {
|
6
|
+
for (var name in all)
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
8
|
+
};
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
11
|
+
for (let key of __getOwnPropNames(from))
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
14
|
+
}
|
15
|
+
return to;
|
16
|
+
};
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
18
|
+
|
19
|
+
// src/index.js
|
20
|
+
var index_exports = {};
|
21
|
+
__export(index_exports, {
|
22
|
+
default: () => laravelAjax
|
23
|
+
});
|
24
|
+
module.exports = __toCommonJS(index_exports);
|
25
|
+
function laravelAjax({
|
26
|
+
url,
|
27
|
+
method = "POST",
|
28
|
+
formId,
|
29
|
+
buttonId = null,
|
30
|
+
loadingText = "Loading...",
|
31
|
+
csrf = false,
|
32
|
+
onSuccess = null,
|
33
|
+
onError = null
|
34
|
+
}) {
|
35
|
+
return new Promise((resolve, reject) => {
|
36
|
+
if (!url) return reject({ error: "URL is required." });
|
37
|
+
if (!formId) return reject({ error: "formId is required." });
|
38
|
+
const form = document.getElementById(formId);
|
39
|
+
if (!form) return reject({ error: `Form with ID "${formId}" not found.` });
|
40
|
+
form.addEventListener("submit", (e) => e.preventDefault());
|
41
|
+
const formData = new FormData(form);
|
42
|
+
const btn = buttonId ? document.getElementById(buttonId) : null;
|
43
|
+
const originalBtnText = btn ? btn.innerHTML : null;
|
44
|
+
if (btn) {
|
45
|
+
btn.disabled = true;
|
46
|
+
btn.innerHTML = `<span class="spinner-border spinner-border-sm me-2"></span>${loadingText}`;
|
47
|
+
}
|
48
|
+
document.querySelectorAll('[class^="error-"]').forEach((el) => {
|
49
|
+
if (["DIV", "SPAN"].includes(el.tagName)) el.innerText = "";
|
50
|
+
});
|
51
|
+
const headers = {};
|
52
|
+
if (csrf) {
|
53
|
+
const tokenTag = document.querySelector('meta[name="csrf-token"]');
|
54
|
+
if (!tokenTag) {
|
55
|
+
if (btn) {
|
56
|
+
btn.disabled = false;
|
57
|
+
btn.innerHTML = originalBtnText;
|
58
|
+
}
|
59
|
+
return reject({
|
60
|
+
error: `CSRF token not found. Please add <meta name="csrf-token" content="..."> in <head>.`
|
61
|
+
});
|
62
|
+
}
|
63
|
+
headers["X-CSRF-TOKEN"] = tokenTag.getAttribute("content");
|
64
|
+
}
|
65
|
+
$.ajax({
|
66
|
+
url,
|
67
|
+
method,
|
68
|
+
data: formData,
|
69
|
+
headers,
|
70
|
+
contentType: false,
|
71
|
+
processData: false,
|
72
|
+
cache: false,
|
73
|
+
success: function(response) {
|
74
|
+
if (btn) {
|
75
|
+
btn.disabled = false;
|
76
|
+
btn.innerHTML = originalBtnText;
|
77
|
+
}
|
78
|
+
if (typeof onSuccess === "function") onSuccess(response);
|
79
|
+
resolve(response);
|
80
|
+
},
|
81
|
+
error: function(xhr) {
|
82
|
+
if (btn) {
|
83
|
+
btn.disabled = false;
|
84
|
+
btn.innerHTML = originalBtnText;
|
85
|
+
}
|
86
|
+
if (xhr.status === 422 && xhr.responseJSON?.errors) {
|
87
|
+
const errors = xhr.responseJSON.errors;
|
88
|
+
for (const field in errors) {
|
89
|
+
const el = document.querySelector(`.error-${field}`);
|
90
|
+
if (el && ["DIV", "SPAN"].includes(el.tagName)) {
|
91
|
+
el.innerText = errors[field][0];
|
92
|
+
}
|
93
|
+
}
|
94
|
+
if (typeof onError === "function") onError(errors);
|
95
|
+
reject(errors);
|
96
|
+
} else {
|
97
|
+
const fallbackError = { error: "Unexpected error occurred." };
|
98
|
+
if (typeof onError === "function") onError(fallbackError);
|
99
|
+
reject(fallbackError);
|
100
|
+
}
|
101
|
+
}
|
102
|
+
});
|
103
|
+
});
|
104
|
+
}
|
105
|
+
if (typeof window !== "undefined") {
|
106
|
+
window.laravelAjax = laravelAjax;
|
107
|
+
}
|
@@ -0,0 +1,87 @@
|
|
1
|
+
// src/index.js
|
2
|
+
function laravelAjax({
|
3
|
+
url,
|
4
|
+
method = "POST",
|
5
|
+
formId,
|
6
|
+
buttonId = null,
|
7
|
+
loadingText = "Loading...",
|
8
|
+
csrf = false,
|
9
|
+
onSuccess = null,
|
10
|
+
onError = null
|
11
|
+
}) {
|
12
|
+
return new Promise((resolve, reject) => {
|
13
|
+
if (!url) return reject({ error: "URL is required." });
|
14
|
+
if (!formId) return reject({ error: "formId is required." });
|
15
|
+
const form = document.getElementById(formId);
|
16
|
+
if (!form) return reject({ error: `Form with ID "${formId}" not found.` });
|
17
|
+
form.addEventListener("submit", (e) => e.preventDefault());
|
18
|
+
const formData = new FormData(form);
|
19
|
+
const btn = buttonId ? document.getElementById(buttonId) : null;
|
20
|
+
const originalBtnText = btn ? btn.innerHTML : null;
|
21
|
+
if (btn) {
|
22
|
+
btn.disabled = true;
|
23
|
+
btn.innerHTML = `<span class="spinner-border spinner-border-sm me-2"></span>${loadingText}`;
|
24
|
+
}
|
25
|
+
document.querySelectorAll('[class^="error-"]').forEach((el) => {
|
26
|
+
if (["DIV", "SPAN"].includes(el.tagName)) el.innerText = "";
|
27
|
+
});
|
28
|
+
const headers = {};
|
29
|
+
if (csrf) {
|
30
|
+
const tokenTag = document.querySelector('meta[name="csrf-token"]');
|
31
|
+
if (!tokenTag) {
|
32
|
+
if (btn) {
|
33
|
+
btn.disabled = false;
|
34
|
+
btn.innerHTML = originalBtnText;
|
35
|
+
}
|
36
|
+
return reject({
|
37
|
+
error: `CSRF token not found. Please add <meta name="csrf-token" content="..."> in <head>.`
|
38
|
+
});
|
39
|
+
}
|
40
|
+
headers["X-CSRF-TOKEN"] = tokenTag.getAttribute("content");
|
41
|
+
}
|
42
|
+
$.ajax({
|
43
|
+
url,
|
44
|
+
method,
|
45
|
+
data: formData,
|
46
|
+
headers,
|
47
|
+
contentType: false,
|
48
|
+
processData: false,
|
49
|
+
cache: false,
|
50
|
+
success: function(response) {
|
51
|
+
if (btn) {
|
52
|
+
btn.disabled = false;
|
53
|
+
btn.innerHTML = originalBtnText;
|
54
|
+
}
|
55
|
+
if (typeof onSuccess === "function") onSuccess(response);
|
56
|
+
resolve(response);
|
57
|
+
},
|
58
|
+
error: function(xhr) {
|
59
|
+
if (btn) {
|
60
|
+
btn.disabled = false;
|
61
|
+
btn.innerHTML = originalBtnText;
|
62
|
+
}
|
63
|
+
if (xhr.status === 422 && xhr.responseJSON?.errors) {
|
64
|
+
const errors = xhr.responseJSON.errors;
|
65
|
+
for (const field in errors) {
|
66
|
+
const el = document.querySelector(`.error-${field}`);
|
67
|
+
if (el && ["DIV", "SPAN"].includes(el.tagName)) {
|
68
|
+
el.innerText = errors[field][0];
|
69
|
+
}
|
70
|
+
}
|
71
|
+
if (typeof onError === "function") onError(errors);
|
72
|
+
reject(errors);
|
73
|
+
} else {
|
74
|
+
const fallbackError = { error: "Unexpected error occurred." };
|
75
|
+
if (typeof onError === "function") onError(fallbackError);
|
76
|
+
reject(fallbackError);
|
77
|
+
}
|
78
|
+
}
|
79
|
+
});
|
80
|
+
});
|
81
|
+
}
|
82
|
+
if (typeof window !== "undefined") {
|
83
|
+
window.laravelAjax = laravelAjax;
|
84
|
+
}
|
85
|
+
export {
|
86
|
+
laravelAjax as default
|
87
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
var laravelAjax=(()=>{var m=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var x=(t,r)=>{for(var o in r)m(t,o,{get:r[o],enumerable:!0})},A=(t,r,o,f)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of D(r))!N.call(t,i)&&i!==o&&m(t,i,{get:()=>r[i],enumerable:!(f=w(r,i))||f.enumerable});return t};var k=t=>A(m({},"__esModule",{value:!0}),t);var q={};x(q,{default:()=>p});function p({url:t,method:r="POST",formId:o,buttonId:f=null,loadingText:i="Loading...",csrf:S=!1,onSuccess:T=null,onError:l=null}){return new Promise((g,s)=>{if(!t)return s({error:"URL is required."});if(!o)return s({error:"formId is required."});let d=document.getElementById(o);if(!d)return s({error:`Form with ID "${o}" not found.`});d.addEventListener("submit",n=>n.preventDefault());let L=new FormData(d),e=f?document.getElementById(f):null,c=e?e.innerHTML:null;e&&(e.disabled=!0,e.innerHTML=`<span class="spinner-border spinner-border-sm me-2"></span>${i}`),document.querySelectorAll('[class^="error-"]').forEach(n=>{["DIV","SPAN"].includes(n.tagName)&&(n.innerText="")});let y={};if(S){let n=document.querySelector('meta[name="csrf-token"]');if(!n)return e&&(e.disabled=!1,e.innerHTML=c),s({error:'CSRF token not found. Please add <meta name="csrf-token" content="..."> in <head>.'});y["X-CSRF-TOKEN"]=n.getAttribute("content")}$.ajax({url:t,method:r,data:L,headers:y,contentType:!1,processData:!1,cache:!1,success:function(n){e&&(e.disabled=!1,e.innerHTML=c),typeof T=="function"&&T(n),g(n)},error:function(n){if(e&&(e.disabled=!1,e.innerHTML=c),n.status===422&&n.responseJSON?.errors){let a=n.responseJSON.errors;for(let b in a){let u=document.querySelector(`.error-${b}`);u&&["DIV","SPAN"].includes(u.tagName)&&(u.innerText=a[b][0])}typeof l=="function"&&l(a),s(a)}else{let a={error:"Unexpected error occurred."};typeof l=="function"&&l(a),s(a)}}})})}typeof window<"u"&&(window.laravelAjax=p);return k(q);})();
|
package/package.json
CHANGED
@@ -1,14 +1,18 @@
|
|
1
1
|
{
|
2
2
|
"name": "ap-laravel-ajax-helper",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.2",
|
4
4
|
"description": "A lightweight JavaScript utility for Laravel-style AJAX requests.",
|
5
|
-
"main": "dist/
|
6
|
-
"module": "dist/
|
5
|
+
"main": "dist/laravel-ajax.cjs.js",
|
6
|
+
"module": "dist/laravel-ajax.esm.js",
|
7
|
+
"browser": "dist/laravel-ajax.min.js",
|
8
|
+
"exports": {
|
9
|
+
"import": "./dist/laravel-ajax.esm.js",
|
10
|
+
"require": "./dist/laravel-ajax.cjs.js",
|
11
|
+
"default": "./dist/laravel-ajax.min.js"
|
12
|
+
},
|
7
13
|
"scripts": {
|
8
|
-
"build": "
|
14
|
+
"build": "esbuild src/index.js --bundle --minify --format=iife --global-name=laravelAjax --outfile=dist/laravel-ajax.min.js && esbuild src/index.js --bundle --format=cjs --outfile=dist/laravel-ajax.cjs.js && esbuild src/index.js --bundle --format=esm --outfile=dist/laravel-ajax.esm.js"
|
9
15
|
},
|
10
|
-
"author": "AkashAp",
|
11
|
-
"license": "MIT",
|
12
16
|
"keywords": [
|
13
17
|
"laravel",
|
14
18
|
"ajax",
|
@@ -16,10 +20,13 @@
|
|
16
20
|
"validation",
|
17
21
|
"jquery"
|
18
22
|
],
|
23
|
+
"author": "AkashAp",
|
24
|
+
"license": "MIT",
|
19
25
|
"devDependencies": {
|
20
26
|
"@babel/cli": "^7.28.0",
|
21
27
|
"@babel/core": "^7.28.0",
|
22
28
|
"@babel/preset-env": "^7.28.0",
|
29
|
+
"esbuild": "^0.25.8",
|
23
30
|
"rollup": "^3.0.0"
|
24
31
|
},
|
25
32
|
"peerDependencies": {
|
@@ -30,5 +37,13 @@
|
|
30
37
|
"src/",
|
31
38
|
"README.md",
|
32
39
|
"LICENSE"
|
33
|
-
]
|
40
|
+
],
|
41
|
+
"repository": {
|
42
|
+
"type": "git",
|
43
|
+
"url": "https://github.com/aakashap01/ap-laravel-ajax-helper.git"
|
44
|
+
},
|
45
|
+
"bugs": {
|
46
|
+
"url": "https://github.com/aakashap01/ap-laravel-ajax-helper/issues"
|
47
|
+
},
|
48
|
+
"homepage": "https://github.com/aakashap01/ap-laravel-ajax-helper#readme"
|
34
49
|
}
|
package/src/index.js
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
export default function laravelAjax({
|
2
2
|
url,
|
3
3
|
method = 'POST',
|
4
|
-
formId
|
4
|
+
formId,
|
5
5
|
buttonId = null,
|
6
6
|
loadingText = 'Loading...',
|
7
|
+
csrf = false,
|
8
|
+
onSuccess = null,
|
9
|
+
onError = null,
|
7
10
|
}) {
|
8
11
|
return new Promise((resolve, reject) => {
|
9
12
|
if (!url) return reject({ error: 'URL is required.' });
|
@@ -12,57 +15,79 @@ export default function laravelAjax({
|
|
12
15
|
const form = document.getElementById(formId);
|
13
16
|
if (!form) return reject({ error: `Form with ID "${formId}" not found.` });
|
14
17
|
|
15
|
-
|
18
|
+
// Prevent default form submission
|
19
|
+
form.addEventListener('submit', (e) => e.preventDefault());
|
16
20
|
|
21
|
+
const formData = new FormData(form);
|
17
22
|
const btn = buttonId ? document.getElementById(buttonId) : null;
|
18
|
-
const
|
23
|
+
const originalBtnText = btn ? btn.innerHTML : null;
|
19
24
|
|
20
|
-
// Disable and show loading on button
|
21
25
|
if (btn) {
|
22
26
|
btn.disabled = true;
|
23
27
|
btn.innerHTML = `<span class="spinner-border spinner-border-sm me-2"></span>${loadingText}`;
|
24
28
|
}
|
25
29
|
|
26
|
-
// Clear all validation error messages
|
27
30
|
document.querySelectorAll('[class^="error-"]').forEach((el) => {
|
28
|
-
if (
|
29
|
-
el.innerText = '';
|
30
|
-
}
|
31
|
+
if (['DIV', 'SPAN'].includes(el.tagName)) el.innerText = '';
|
31
32
|
});
|
32
33
|
|
34
|
+
const headers = {};
|
35
|
+
if (csrf) {
|
36
|
+
const tokenTag = document.querySelector('meta[name="csrf-token"]');
|
37
|
+
if (!tokenTag) {
|
38
|
+
if (btn) {
|
39
|
+
btn.disabled = false;
|
40
|
+
btn.innerHTML = originalBtnText;
|
41
|
+
}
|
42
|
+
return reject({
|
43
|
+
error: `CSRF token not found. Please add <meta name="csrf-token" content="..."> in <head>.`,
|
44
|
+
});
|
45
|
+
}
|
46
|
+
headers['X-CSRF-TOKEN'] = tokenTag.getAttribute('content');
|
47
|
+
}
|
48
|
+
|
33
49
|
$.ajax({
|
34
50
|
url,
|
35
51
|
method,
|
36
52
|
data: formData,
|
53
|
+
headers,
|
37
54
|
contentType: false,
|
38
55
|
processData: false,
|
39
56
|
cache: false,
|
40
57
|
success: function (response) {
|
41
58
|
if (btn) {
|
42
|
-
btn.innerHTML = originalButtonText;
|
43
59
|
btn.disabled = false;
|
60
|
+
btn.innerHTML = originalBtnText;
|
44
61
|
}
|
62
|
+
if (typeof onSuccess === 'function') onSuccess(response);
|
45
63
|
resolve(response);
|
46
64
|
},
|
47
65
|
error: function (xhr) {
|
48
|
-
if (
|
49
|
-
|
66
|
+
if (btn) {
|
67
|
+
btn.disabled = false;
|
68
|
+
btn.innerHTML = originalBtnText;
|
69
|
+
}
|
70
|
+
|
71
|
+
if (xhr.status === 422 && xhr.responseJSON?.errors) {
|
72
|
+
const errors = xhr.responseJSON.errors;
|
50
73
|
for (const field in errors) {
|
51
|
-
const
|
52
|
-
if (
|
53
|
-
|
74
|
+
const el = document.querySelector(`.error-${field}`);
|
75
|
+
if (el && ['DIV', 'SPAN'].includes(el.tagName)) {
|
76
|
+
el.innerText = errors[field][0];
|
54
77
|
}
|
55
78
|
}
|
79
|
+
if (typeof onError === 'function') onError(errors);
|
56
80
|
reject(errors);
|
57
81
|
} else {
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
if (btn) {
|
62
|
-
btn.innerHTML = originalButtonText;
|
63
|
-
btn.disabled = false;
|
82
|
+
const fallbackError = { error: 'Unexpected error occurred.' };
|
83
|
+
if (typeof onError === 'function') onError(fallbackError);
|
84
|
+
reject(fallbackError);
|
64
85
|
}
|
65
86
|
},
|
66
87
|
});
|
67
88
|
});
|
68
89
|
}
|
90
|
+
|
91
|
+
if (typeof window !== 'undefined') {
|
92
|
+
window.laravelAjax = laravelAjax;
|
93
|
+
}
|
package/dist/index.js
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
4
|
-
value: true
|
5
|
-
});
|
6
|
-
exports["default"] = laravelAjax;
|
7
|
-
function laravelAjax(_ref) {
|
8
|
-
var url = _ref.url,
|
9
|
-
_ref$method = _ref.method,
|
10
|
-
method = _ref$method === void 0 ? 'POST' : _ref$method,
|
11
|
-
_ref$formId = _ref.formId,
|
12
|
-
formId = _ref$formId === void 0 ? null : _ref$formId,
|
13
|
-
_ref$buttonId = _ref.buttonId,
|
14
|
-
buttonId = _ref$buttonId === void 0 ? null : _ref$buttonId,
|
15
|
-
_ref$loadingText = _ref.loadingText,
|
16
|
-
loadingText = _ref$loadingText === void 0 ? 'Loading...' : _ref$loadingText;
|
17
|
-
return new Promise(function (resolve, reject) {
|
18
|
-
if (!url) return reject({
|
19
|
-
error: 'URL is required.'
|
20
|
-
});
|
21
|
-
if (!formId) return reject({
|
22
|
-
error: 'formId is required.'
|
23
|
-
});
|
24
|
-
var form = document.getElementById(formId);
|
25
|
-
if (!form) return reject({
|
26
|
-
error: "Form with ID \"".concat(formId, "\" not found.")
|
27
|
-
});
|
28
|
-
var formData = new FormData(form);
|
29
|
-
var btn = buttonId ? document.getElementById(buttonId) : null;
|
30
|
-
var originalButtonText = btn ? btn.innerHTML : null;
|
31
|
-
|
32
|
-
// Disable and show loading on button
|
33
|
-
if (btn) {
|
34
|
-
btn.disabled = true;
|
35
|
-
btn.innerHTML = "<span class=\"spinner-border spinner-border-sm me-2\"></span>".concat(loadingText);
|
36
|
-
}
|
37
|
-
|
38
|
-
// Clear all validation error messages
|
39
|
-
document.querySelectorAll('[class^="error-"]').forEach(function (el) {
|
40
|
-
if (el.tagName === 'DIV' || el.tagName === 'SPAN') {
|
41
|
-
el.innerText = '';
|
42
|
-
}
|
43
|
-
});
|
44
|
-
$.ajax({
|
45
|
-
url: url,
|
46
|
-
method: method,
|
47
|
-
data: formData,
|
48
|
-
contentType: false,
|
49
|
-
processData: false,
|
50
|
-
cache: false,
|
51
|
-
success: function success(response) {
|
52
|
-
if (btn) {
|
53
|
-
btn.innerHTML = originalButtonText;
|
54
|
-
btn.disabled = false;
|
55
|
-
}
|
56
|
-
resolve(response);
|
57
|
-
},
|
58
|
-
error: function error(xhr) {
|
59
|
-
if (xhr.status === 422) {
|
60
|
-
var _xhr$responseJSON;
|
61
|
-
var errors = ((_xhr$responseJSON = xhr.responseJSON) === null || _xhr$responseJSON === void 0 ? void 0 : _xhr$responseJSON.errors) || {};
|
62
|
-
for (var field in errors) {
|
63
|
-
var target = document.querySelector(".error-".concat(field));
|
64
|
-
if (target && (target.tagName === 'DIV' || target.tagName === 'SPAN')) {
|
65
|
-
target.innerText = errors[field][0];
|
66
|
-
}
|
67
|
-
}
|
68
|
-
reject(errors);
|
69
|
-
} else {
|
70
|
-
reject({
|
71
|
-
error: 'Unexpected error occurred.'
|
72
|
-
});
|
73
|
-
}
|
74
|
-
if (btn) {
|
75
|
-
btn.innerHTML = originalButtonText;
|
76
|
-
btn.disabled = false;
|
77
|
-
}
|
78
|
-
}
|
79
|
-
});
|
80
|
-
});
|
81
|
-
}
|