Skip to content

Commit 052ddae

Browse files
committed
fix(pat modal): replace jquery-form plugin with native fetch API
1 parent 7fda203 commit 052ddae

1 file changed

Lines changed: 81 additions & 29 deletions

File tree

src/pat/modal/modal.js

Lines changed: 81 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -229,29 +229,53 @@ export default Base.extend({
229229
$form.trigger("submit");
230230

231231
self.loading.show(false);
232-
$form.ajaxSubmit({
233-
timeout: options.timeout,
234-
data: extraData,
235-
url: url,
236-
error: function (xhr, textStatus, errorStatus) {
237-
self.loading.hide();
238-
if (textStatus === "timeout" && options.onTimeout) {
239-
options.onTimeout.apply(self, xhr, errorStatus);
240-
// on "error", "abort", and "parsererror"
241-
} else if (options.onError) {
242-
if (typeof options.onError === "string") {
243-
window[options.onError](xhr, textStatus, errorStatus);
244-
} else {
245-
options.onError(xhr, textStatus, errorStatus);
246-
}
247-
} else {
248-
// window.alert(_t('There was an error submitting the form.'));
249-
console.log("error happened", textStatus, " do something");
250-
}
251-
self.emit("formActionError", [xhr, textStatus, errorStatus]);
252-
},
253-
success: function (response, state, xhr, form) {
232+
233+
// Use native fetch API with FormData
234+
const formData = new FormData($form[0]);
235+
236+
// Add extra data from the clicked action
237+
for (const key in extraData) {
238+
if (extraData[key]) {
239+
formData.append(key, extraData[key]);
240+
}
241+
}
242+
243+
// Setup timeout using AbortController
244+
const controller = new AbortController();
245+
const timeoutId = setTimeout(() => controller.abort(), options.timeout);
246+
247+
fetch(url, {
248+
method: $form.attr("method") || "POST",
249+
body: formData,
250+
signal: controller.signal,
251+
credentials: "same-origin",
252+
})
253+
.then((response) => {
254+
clearTimeout(timeoutId);
255+
256+
// Create a mock xhr object for compatibility with existing callbacks
257+
const mockXhr = {
258+
status: response.status,
259+
statusText: response.statusText,
260+
getResponseHeader: (header) => response.headers.get(header),
261+
getAllResponseHeaders: () => {
262+
let headers = "";
263+
response.headers.forEach((value, key) => {
264+
headers += `${key}: ${value}\r\n`;
265+
});
266+
return headers;
267+
},
268+
};
269+
270+
return response.text().then((text) => ({
271+
response: text,
272+
state: "success",
273+
xhr: mockXhr,
274+
}));
275+
})
276+
.then(({ response, state, xhr }) => {
254277
self.loading.hide();
278+
255279
// if error is found (NOTE: check for both the portal errors
256280
// and the form field-level errors)
257281
if (
@@ -265,10 +289,10 @@ export default Base.extend({
265289
response,
266290
state,
267291
xhr,
268-
form
292+
$form[0]
269293
);
270294
} else {
271-
options.onFormError(self, response, state, xhr, form);
295+
options.onFormError(self, response, state, xhr, $form[0]);
272296
}
273297
} else {
274298
self.redraw(response, patternOptions);
@@ -290,9 +314,9 @@ export default Base.extend({
290314

291315
if (options.onSuccess) {
292316
if (typeof options.onSuccess === "string") {
293-
window[options.onSuccess](self, response, state, xhr, form);
317+
window[options.onSuccess](self, response, state, xhr, $form[0]);
294318
} else {
295-
options.onSuccess(self, response, state, xhr, form);
319+
options.onSuccess(self, response, state, xhr, $form[0]);
296320
}
297321
}
298322

@@ -305,9 +329,37 @@ export default Base.extend({
305329
self.reloadWindow();
306330
}
307331
}
308-
self.emit("formActionSuccess", [response, state, xhr, form]);
309-
},
310-
});
332+
self.emit("formActionSuccess", [response, state, xhr, $form[0]]);
333+
})
334+
.catch((error) => {
335+
clearTimeout(timeoutId);
336+
self.loading.hide();
337+
338+
const textStatus = error.name === "AbortError" ? "timeout" : "error";
339+
const errorStatus = error.message;
340+
341+
// Create a mock xhr object for error callbacks
342+
const mockXhr = {
343+
status: 0,
344+
statusText: textStatus,
345+
responseText: "",
346+
};
347+
348+
if (textStatus === "timeout" && options.onTimeout) {
349+
options.onTimeout.apply(self, [mockXhr, errorStatus]);
350+
// on "error", "abort", and "parsererror"
351+
} else if (options.onError) {
352+
if (typeof options.onError === "string") {
353+
window[options.onError](mockXhr, textStatus, errorStatus);
354+
} else {
355+
options.onError(mockXhr, textStatus, errorStatus);
356+
}
357+
} else {
358+
// window.alert(_t('There was an error submitting the form.'));
359+
console.log("error happened", textStatus, " do something");
360+
}
361+
self.emit("formActionError", [mockXhr, textStatus, errorStatus]);
362+
});
311363
},
312364
handleLinkAction: function ($action, options, patternOptions) {
313365
var self = this;

0 commit comments

Comments
 (0)