Splitting jQuery code into reusable modules
up vote
1
down vote
favorite
I am in the middle of php app development with some addition of js. Since my JS knowledge is not particularly good, I rely on jQuery. However, I like to work with reusable code rather than spaghetti. So, there is a situation.
I have two kinds of form in the app - classic ones and ajax ones. Now I want to move my ajax form handlers to separated file, module and initiate it in main js file.
My current code:
main.js
import forms from './plugins/ajaxForms';
forms.init($('form.ajax'));
ajaxForms.js
function init(form) {
const obj = this;
form.on('submit', function (e) {
e.preventDefault();
const form = $(this);
const url = form.attr('action');
const data = form.serialize();
const method = form.find('input[name="method"]').val() ? form.find('input[name="method"]').val() : form.attr('method');
const call = $.ajax({
type: method,
url: url,
data: data,
dataType: "json",
beforeSend: function() {
obj.beforeSend(form);
}
});
call.done(function (response) {
Toastr["success"](response.message);
});
call.fail(function (response) {
Toastr["error"](response.responseJSON.message);
obj.renderErrors(form);
});
call.always(function () {
obj.after(form);
});
});
}
function beforeSend(container) {
if(container === null) {
return;
}
container.find('.form-loading-overlay').show();
}
function after(container) {
if(container === null) {
return;
}
container.find('.form-loading-overlay').hide();
}
export default {
init: init,
beforeSend: beforeSend,
after: after,
};
Expected solution:
I do not like the way I am using other functions from this module (such as after(container) - I needed to pass "this" to const obj in order to get it to work with i.e. beforeSend in const call.
In short, I believe there is better way to write this piece of code. I suppose that this particular example is overcomplicated and could be just left as a jquery code closed in submit event. However, I insist on making it modular as I want to learn on this example and refactor rest of my code myself.
Also, I need to be able to access methods like beforeSend(...) and after(...) without using init(...) method, as I am referecing to this methods in other modules while using ajax calls without forms - I still want to display loading overlay on given container during ajax action.
javascript jquery modules
New contributor
ficus is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
|
show 8 more comments
up vote
1
down vote
favorite
I am in the middle of php app development with some addition of js. Since my JS knowledge is not particularly good, I rely on jQuery. However, I like to work with reusable code rather than spaghetti. So, there is a situation.
I have two kinds of form in the app - classic ones and ajax ones. Now I want to move my ajax form handlers to separated file, module and initiate it in main js file.
My current code:
main.js
import forms from './plugins/ajaxForms';
forms.init($('form.ajax'));
ajaxForms.js
function init(form) {
const obj = this;
form.on('submit', function (e) {
e.preventDefault();
const form = $(this);
const url = form.attr('action');
const data = form.serialize();
const method = form.find('input[name="method"]').val() ? form.find('input[name="method"]').val() : form.attr('method');
const call = $.ajax({
type: method,
url: url,
data: data,
dataType: "json",
beforeSend: function() {
obj.beforeSend(form);
}
});
call.done(function (response) {
Toastr["success"](response.message);
});
call.fail(function (response) {
Toastr["error"](response.responseJSON.message);
obj.renderErrors(form);
});
call.always(function () {
obj.after(form);
});
});
}
function beforeSend(container) {
if(container === null) {
return;
}
container.find('.form-loading-overlay').show();
}
function after(container) {
if(container === null) {
return;
}
container.find('.form-loading-overlay').hide();
}
export default {
init: init,
beforeSend: beforeSend,
after: after,
};
Expected solution:
I do not like the way I am using other functions from this module (such as after(container) - I needed to pass "this" to const obj in order to get it to work with i.e. beforeSend in const call.
In short, I believe there is better way to write this piece of code. I suppose that this particular example is overcomplicated and could be just left as a jquery code closed in submit event. However, I insist on making it modular as I want to learn on this example and refactor rest of my code myself.
Also, I need to be able to access methods like beforeSend(...) and after(...) without using init(...) method, as I am referecing to this methods in other modules while using ajax calls without forms - I still want to display loading overlay on given container during ajax action.
javascript jquery modules
New contributor
ficus is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
You can set thecontext:thisatjQuery.ajax()for the same object to be set asthisatbeforeSendand.always(). Why can you not accessbeforeSendandafterwithoutinit?
– guest271314
Nov 19 at 5:19
1
My bad. Ultimate goal is to move this code to its own module and make parts of it reusable (for i.e. displaying loading screen on given container). jQuery is just a way to accomplish that as I know it a bit. Didn't mean to override any jquery method.
– ficus
2 days ago
1
They are. Currect code works properly, however I belive it can be done better. It already got quite messy and it will get worse the moment I decide to add some stuff there. It looks more like random code closed in pseudo object rather than real object -> i.e. cannot usethis.beforeSend(...)in ajax.beforeSend, need var "obj" as a workaround.
– ficus
2 days ago
1
thisis theformwithinsubmitevent, correct? Have you tried passingbeforeSendandaftertoinit(form, beforeSend, after)and using.bind()? Which should setthisto the currentformwithinbeforeSendbeforeSend:beforeSend.bind(this)
– guest271314
2 days ago
1
Yes, correct. I didn't try it tho. It doesn't really make sense for me to pass same object methods from outside to itself. It would generate something like "forms.init($('form.ajax'), forms.beforeSend($('form.ajax'), forms.after($('form.ajax')", wouldn't it? Otherwise I didnt get an idea of bind usage here :(
– ficus
yesterday
|
show 8 more comments
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I am in the middle of php app development with some addition of js. Since my JS knowledge is not particularly good, I rely on jQuery. However, I like to work with reusable code rather than spaghetti. So, there is a situation.
I have two kinds of form in the app - classic ones and ajax ones. Now I want to move my ajax form handlers to separated file, module and initiate it in main js file.
My current code:
main.js
import forms from './plugins/ajaxForms';
forms.init($('form.ajax'));
ajaxForms.js
function init(form) {
const obj = this;
form.on('submit', function (e) {
e.preventDefault();
const form = $(this);
const url = form.attr('action');
const data = form.serialize();
const method = form.find('input[name="method"]').val() ? form.find('input[name="method"]').val() : form.attr('method');
const call = $.ajax({
type: method,
url: url,
data: data,
dataType: "json",
beforeSend: function() {
obj.beforeSend(form);
}
});
call.done(function (response) {
Toastr["success"](response.message);
});
call.fail(function (response) {
Toastr["error"](response.responseJSON.message);
obj.renderErrors(form);
});
call.always(function () {
obj.after(form);
});
});
}
function beforeSend(container) {
if(container === null) {
return;
}
container.find('.form-loading-overlay').show();
}
function after(container) {
if(container === null) {
return;
}
container.find('.form-loading-overlay').hide();
}
export default {
init: init,
beforeSend: beforeSend,
after: after,
};
Expected solution:
I do not like the way I am using other functions from this module (such as after(container) - I needed to pass "this" to const obj in order to get it to work with i.e. beforeSend in const call.
In short, I believe there is better way to write this piece of code. I suppose that this particular example is overcomplicated and could be just left as a jquery code closed in submit event. However, I insist on making it modular as I want to learn on this example and refactor rest of my code myself.
Also, I need to be able to access methods like beforeSend(...) and after(...) without using init(...) method, as I am referecing to this methods in other modules while using ajax calls without forms - I still want to display loading overlay on given container during ajax action.
javascript jquery modules
New contributor
ficus is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
I am in the middle of php app development with some addition of js. Since my JS knowledge is not particularly good, I rely on jQuery. However, I like to work with reusable code rather than spaghetti. So, there is a situation.
I have two kinds of form in the app - classic ones and ajax ones. Now I want to move my ajax form handlers to separated file, module and initiate it in main js file.
My current code:
main.js
import forms from './plugins/ajaxForms';
forms.init($('form.ajax'));
ajaxForms.js
function init(form) {
const obj = this;
form.on('submit', function (e) {
e.preventDefault();
const form = $(this);
const url = form.attr('action');
const data = form.serialize();
const method = form.find('input[name="method"]').val() ? form.find('input[name="method"]').val() : form.attr('method');
const call = $.ajax({
type: method,
url: url,
data: data,
dataType: "json",
beforeSend: function() {
obj.beforeSend(form);
}
});
call.done(function (response) {
Toastr["success"](response.message);
});
call.fail(function (response) {
Toastr["error"](response.responseJSON.message);
obj.renderErrors(form);
});
call.always(function () {
obj.after(form);
});
});
}
function beforeSend(container) {
if(container === null) {
return;
}
container.find('.form-loading-overlay').show();
}
function after(container) {
if(container === null) {
return;
}
container.find('.form-loading-overlay').hide();
}
export default {
init: init,
beforeSend: beforeSend,
after: after,
};
Expected solution:
I do not like the way I am using other functions from this module (such as after(container) - I needed to pass "this" to const obj in order to get it to work with i.e. beforeSend in const call.
In short, I believe there is better way to write this piece of code. I suppose that this particular example is overcomplicated and could be just left as a jquery code closed in submit event. However, I insist on making it modular as I want to learn on this example and refactor rest of my code myself.
Also, I need to be able to access methods like beforeSend(...) and after(...) without using init(...) method, as I am referecing to this methods in other modules while using ajax calls without forms - I still want to display loading overlay on given container during ajax action.
javascript jquery modules
javascript jquery modules
New contributor
ficus is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
ficus is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited Nov 18 at 20:43
Stephen Rauch
3,75051530
3,75051530
New contributor
ficus is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked Nov 18 at 14:04
ficus
162
162
New contributor
ficus is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
ficus is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
ficus is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
You can set thecontext:thisatjQuery.ajax()for the same object to be set asthisatbeforeSendand.always(). Why can you not accessbeforeSendandafterwithoutinit?
– guest271314
Nov 19 at 5:19
1
My bad. Ultimate goal is to move this code to its own module and make parts of it reusable (for i.e. displaying loading screen on given container). jQuery is just a way to accomplish that as I know it a bit. Didn't mean to override any jquery method.
– ficus
2 days ago
1
They are. Currect code works properly, however I belive it can be done better. It already got quite messy and it will get worse the moment I decide to add some stuff there. It looks more like random code closed in pseudo object rather than real object -> i.e. cannot usethis.beforeSend(...)in ajax.beforeSend, need var "obj" as a workaround.
– ficus
2 days ago
1
thisis theformwithinsubmitevent, correct? Have you tried passingbeforeSendandaftertoinit(form, beforeSend, after)and using.bind()? Which should setthisto the currentformwithinbeforeSendbeforeSend:beforeSend.bind(this)
– guest271314
2 days ago
1
Yes, correct. I didn't try it tho. It doesn't really make sense for me to pass same object methods from outside to itself. It would generate something like "forms.init($('form.ajax'), forms.beforeSend($('form.ajax'), forms.after($('form.ajax')", wouldn't it? Otherwise I didnt get an idea of bind usage here :(
– ficus
yesterday
|
show 8 more comments
You can set thecontext:thisatjQuery.ajax()for the same object to be set asthisatbeforeSendand.always(). Why can you not accessbeforeSendandafterwithoutinit?
– guest271314
Nov 19 at 5:19
1
My bad. Ultimate goal is to move this code to its own module and make parts of it reusable (for i.e. displaying loading screen on given container). jQuery is just a way to accomplish that as I know it a bit. Didn't mean to override any jquery method.
– ficus
2 days ago
1
They are. Currect code works properly, however I belive it can be done better. It already got quite messy and it will get worse the moment I decide to add some stuff there. It looks more like random code closed in pseudo object rather than real object -> i.e. cannot usethis.beforeSend(...)in ajax.beforeSend, need var "obj" as a workaround.
– ficus
2 days ago
1
thisis theformwithinsubmitevent, correct? Have you tried passingbeforeSendandaftertoinit(form, beforeSend, after)and using.bind()? Which should setthisto the currentformwithinbeforeSendbeforeSend:beforeSend.bind(this)
– guest271314
2 days ago
1
Yes, correct. I didn't try it tho. It doesn't really make sense for me to pass same object methods from outside to itself. It would generate something like "forms.init($('form.ajax'), forms.beforeSend($('form.ajax'), forms.after($('form.ajax')", wouldn't it? Otherwise I didnt get an idea of bind usage here :(
– ficus
yesterday
You can set the
context : this at jQuery.ajax() for the same object to be set as this at beforeSend and .always(). Why can you not access beforeSend and after without init?– guest271314
Nov 19 at 5:19
You can set the
context : this at jQuery.ajax() for the same object to be set as this at beforeSend and .always(). Why can you not access beforeSend and after without init?– guest271314
Nov 19 at 5:19
1
1
My bad. Ultimate goal is to move this code to its own module and make parts of it reusable (for i.e. displaying loading screen on given container). jQuery is just a way to accomplish that as I know it a bit. Didn't mean to override any jquery method.
– ficus
2 days ago
My bad. Ultimate goal is to move this code to its own module and make parts of it reusable (for i.e. displaying loading screen on given container). jQuery is just a way to accomplish that as I know it a bit. Didn't mean to override any jquery method.
– ficus
2 days ago
1
1
They are. Currect code works properly, however I belive it can be done better. It already got quite messy and it will get worse the moment I decide to add some stuff there. It looks more like random code closed in pseudo object rather than real object -> i.e. cannot use
this.beforeSend(...) in ajax.beforeSend, need var "obj" as a workaround.– ficus
2 days ago
They are. Currect code works properly, however I belive it can be done better. It already got quite messy and it will get worse the moment I decide to add some stuff there. It looks more like random code closed in pseudo object rather than real object -> i.e. cannot use
this.beforeSend(...) in ajax.beforeSend, need var "obj" as a workaround.– ficus
2 days ago
1
1
this is the form within submit event, correct? Have you tried passing beforeSend and after to init(form, beforeSend, after) and using .bind()? Which should set this to the current form within beforeSend beforeSend:beforeSend.bind(this)– guest271314
2 days ago
this is the form within submit event, correct? Have you tried passing beforeSend and after to init(form, beforeSend, after) and using .bind()? Which should set this to the current form within beforeSend beforeSend:beforeSend.bind(this)– guest271314
2 days ago
1
1
Yes, correct. I didn't try it tho. It doesn't really make sense for me to pass same object methods from outside to itself. It would generate something like "forms.init($('form.ajax'), forms.beforeSend($('form.ajax'), forms.after($('form.ajax')", wouldn't it? Otherwise I didnt get an idea of bind usage here :(
– ficus
yesterday
Yes, correct. I didn't try it tho. It doesn't really make sense for me to pass same object methods from outside to itself. It would generate something like "forms.init($('form.ajax'), forms.beforeSend($('form.ajax'), forms.after($('form.ajax')", wouldn't it? Otherwise I didnt get an idea of bind usage here :(
– ficus
yesterday
|
show 8 more comments
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
ficus is a new contributor. Be nice, and check out our Code of Conduct.
ficus is a new contributor. Be nice, and check out our Code of Conduct.
ficus is a new contributor. Be nice, and check out our Code of Conduct.
ficus is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f207920%2fsplitting-jquery-code-into-reusable-modules%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You can set the
context:thisatjQuery.ajax()for the same object to be set asthisatbeforeSendand.always(). Why can you not accessbeforeSendandafterwithoutinit?– guest271314
Nov 19 at 5:19
1
My bad. Ultimate goal is to move this code to its own module and make parts of it reusable (for i.e. displaying loading screen on given container). jQuery is just a way to accomplish that as I know it a bit. Didn't mean to override any jquery method.
– ficus
2 days ago
1
They are. Currect code works properly, however I belive it can be done better. It already got quite messy and it will get worse the moment I decide to add some stuff there. It looks more like random code closed in pseudo object rather than real object -> i.e. cannot use
this.beforeSend(...)in ajax.beforeSend, need var "obj" as a workaround.– ficus
2 days ago
1
thisis theformwithinsubmitevent, correct? Have you tried passingbeforeSendandaftertoinit(form, beforeSend, after)and using.bind()? Which should setthisto the currentformwithinbeforeSendbeforeSend:beforeSend.bind(this)– guest271314
2 days ago
1
Yes, correct. I didn't try it tho. It doesn't really make sense for me to pass same object methods from outside to itself. It would generate something like "forms.init($('form.ajax'), forms.beforeSend($('form.ajax'), forms.after($('form.ajax')", wouldn't it? Otherwise I didnt get an idea of bind usage here :(
– ficus
yesterday