Reputation: 20049
I have a dropdown notification window that I show when I run certain AJAX functions, let's simplify it as:
function notifyComplete(type, alert_el, response) {
var msg = response.output;
var result = response.result;
// Update msg in alert box
alert_el.text(msg);
if (result == 'success') {
alert_el.addClass('alert-success');
} else {
alert_el.addClass('alert-danger');
}
// Slide in alert box
alert_el.addClass('visible');
}
...and I might call it like so:
var alert_el = $('#top_notify').find('.alert');
// Remove any additional classes added by a possible previous run
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');
getAjaxData(loadUrl, dataObject, 'POST', 'json')
.done(function(response) {
notifyComplete(notify_type, alert_el, response);
});
..and here is the getAjaxData
function if of interest:
function getAjaxData(loadUrl, dataObject, action, type) {
return jQuery.ajax({
type: action,
url: loadUrl,
data: dataObject,
dataType: type
});
}
Now what I am trying to do is find a way I can place this code:
var alert_el = $('#top_notify').find('.alert');
// Remove any additional classes added by a possible previous run
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');
...somewhere where I don't have to repeat it every time I want to use the notifyComplete
function.
Obviously if notifyComplete
is going to be always called within an AJAX block then I can't put it inside the function itself as then you wouldn't be able to get the notify box to slide down more than once without a page reload.
Also, I can't do it afterwards as the slide down notify window duration is handled by CSS and hence JS doesn't know when it's complete.
I had built a current working example on CodePen here but it seems it's broken because of an issue with crossorigin.me
Upvotes: 0
Views: 83
Reputation: 1
If you are trying to call
var alert_el = $('#top_notify').find('.alert');
// Remove any additional classes added by a possible previous run
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');
before each $.ajax()
call, you can include the lines within $.ajax()
beforeSend
function within getAjaxData
function getAjaxData(loadUrl, dataObject, action, type) {
return jQuery.ajax({
beforeSend: function(jqxhr, settings) {
var alert_el = $('#top_notify').find('.alert');
// Remove any additional classes added by a possible previous run
alert_el
.removeClass('visible alert-success alert-info alert-danger alert-warning');
},
type: action,
url: loadUrl,
data: dataObject,
dataType: type
});
}
If you are trying to call the two lines after $.ajax()
call, though before notifyComplete
you can pass an array of function to .done()
getAjaxData(loadUrl, dataObject, 'POST', 'json')
.done([
function(response) {
var alert_el = $('#top_notify').find('.alert');
// Remove any additional classes added by a possible previous run
alert_el
.removeClass('visible alert-success alert-info alert-danger alert-warning');
}
, function(response) {
notifyComplete(notify_type, alert_el, response);
}
]);
if I could pass it a function name as a callback rather than use an anonymous function and thus have to resort to using
if/else
inside, but obviously also need a way of including parameters with the callback.
You can use Function.prototype.bind()
to pass additional parameters to a named function set as value of beforeSend
option of $.ajax()
. Include logic to check if the additional object or value is the passed object or jQuery jqxhr
object that is the default first parameter of beforeSend
.
function handleBeforeSend(args, jqxhr, settings) {
console.log(args, jqxhr, settings);
if (args.hasOwnProperty("additionalSettings")) {
// do stuff with `args.additionalSettings`
}
}
$.ajax({
url:"/path/to/server/",
type: "POST",
beforeSend: handleBeforeSend.bind(null, {additionalSettings:[0,1,2]})
});
jsfiddle https://jsfiddle.net/dackdrek/
Implemented within current javascript
$().ready(function() {
function handleBeforeSend(bool, jqxhr, settings) {
console.log(bool, jqxhr, settings);
if (bool === true) {
var alert_el = $('#top_notify').find('.alert');
// Remove any additional classes added by a possible previous run
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');
}
}
function notifyComplete(type, alert_el, response) {
var msg = response.output;
var result = response.result;
// Update msg in alert box
alert_el.text(msg);
if (result == 'success') {
alert_el.addClass('alert-success');
} else {
alert_el.addClass('alert-danger');
}
// Slide in alert box
alert_el.addClass('visible');
}
function getAjaxData(loadUrl, dataObject, action, type, beforeSend, bool) {
return jQuery.ajax({
type: action,
url: loadUrl,
data: dataObject,
dataType: type,
beforeSend: beforeSend.bind(null, bool)
});
}
// pass `true` to `handleBeforeSend`
getAjaxData("/echo/json/", {
json: JSON.stringify({
"output": "123",
"result": "success"
})
}, "POST", "json", handleBeforeSend, true)
.then(function(response) {
notifyComplete(null, $('#top_notify'), response)
});
setTimeout(function() {
// pass `false` to `handleBeforeSend`
getAjaxData("/echo/json/", {
json: JSON.stringify({
"output": "123",
"result": "success"
})
}, "POST", "json", handleBeforeSend, false)
.then(function(response) {
notifyComplete(null, $('#top_notify'), response)
})
}, 5000)
})
jsfiddle https://jsfiddle.net/dackdrek/4/
Upvotes: 1
Reputation: 12329
You have a couple of options.
You can use setTimeout
in the notifyComplete
function, place it at the end and give it a reasonable amount of time so the notification alert disappears automatically after it appears
Also, I can't do it afterwards as the slide down notify window duration is handled by CSS and hence JS doesn't know when it's complete.
That is not correct, you can use the trantisitionend
or animationend
events to check when a CSS effect has finished. If you are using something like bootstrap, you can use transitionend in the alert element.
Upvotes: 1