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
|
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
You can set thecontext
:this
atjQuery.ajax()
for the same object to be set asthis
atbeforeSend
and.always()
. Why can you not accessbeforeSend
andafter
withoutinit
?
– 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
this
is theform
withinsubmit
event, correct? Have you tried passingbeforeSend
andafter
toinit(form, beforeSend, after)
and using.bind()
? Which should setthis
to the currentform
withinbeforeSend
beforeSend: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
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
New contributor
edited Nov 18 at 20:43
Stephen Rauch
3,75051530
3,75051530
New contributor
asked Nov 18 at 14:04
ficus
162
162
New contributor
New contributor
You can set thecontext
:this
atjQuery.ajax()
for the same object to be set asthis
atbeforeSend
and.always()
. Why can you not accessbeforeSend
andafter
withoutinit
?
– 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
this
is theform
withinsubmit
event, correct? Have you tried passingbeforeSend
andafter
toinit(form, beforeSend, after)
and using.bind()
? Which should setthis
to the currentform
withinbeforeSend
beforeSend: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
:this
atjQuery.ajax()
for the same object to be set asthis
atbeforeSend
and.always()
. Why can you not accessbeforeSend
andafter
withoutinit
?
– 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
this
is theform
withinsubmit
event, correct? Have you tried passingbeforeSend
andafter
toinit(form, beforeSend, after)
and using.bind()
? Which should setthis
to the currentform
withinbeforeSend
beforeSend: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
:this
atjQuery.ajax()
for the same object to be set asthis
atbeforeSend
and.always()
. Why can you not accessbeforeSend
andafter
withoutinit
?– 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
this
is theform
withinsubmit
event, correct? Have you tried passingbeforeSend
andafter
toinit(form, beforeSend, after)
and using.bind()
? Which should setthis
to the currentform
withinbeforeSend
beforeSend: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