jQuery notification with actions - javascript

I am using a jQuery plugin for showing notifications.
so i can use something like this
show_notification("Successfully Saved your data","success");
we can use html content as message.
Now i want to perform some actions
ex.
show_notification("Do you want to save your data","success");
so this is a question to the user and user need to reply by clicking yes or no [both will be passed as html message]
what i need to do is when user clicks on yes/no i need to perform some actions.
i can use id or class to attach a click event,but i have many types of actions,and need to use very different id or class.
can i use a call back function or something like that ?
Please help me or give me your valuable suggestions .
Thank you.
Note : I know that it is not possible with current plugin and not talking about its functionalities ,i am just trying to modify the plugin.

In case there is no way to send a callback to your plugin, you would have to manually add the Yes/No-buttons to your message, and target them either by live delegates or by assigning a listener after the notification has been shown.
$(function() {
$('body').on('click', '.notification-yes', function() {
// yes-callback
});
$('body').on('click', '.notification-no', function() {
// no-callback
});
});
show_notification('Do you want to proceed? <button class="notification-yes">Yes</button> <button class="notification-no">No</button>', 'success');
If it is this plugin that you're using, you'll want your listeners to call closeNotification(). I realize that the syntax is not exactly the same, but that could be a versioning issue. It'd be easier to help you with the specifics if we knew the details of the plugin you're using.
You'll also need a way of knowing which notification was showing when the button was clicked. You could of course have unique button class names for different notifications. Another approach, if there is always just one notification showing at any given time, would be to have a small state object for the callback of interest. For instance:
var myNotifications = {
onYes: function() { },
onNo: function() { }
};
$(function() {
$('body').on('click', '.notification-yes', function() {
myNotifications.onYes();
closeNotification();
});
$('body').on('click', '.notification-no', function() {
myNotifications.onNo();
closeNotification();
});
});
function showCertainNotification() {
myNotifications.onYes = function() {
// specific callback for this notification.
};
show_notification('Confirm? <button class="notification-yes">Yes</button> <button class="notification-no">No</button>', 'success');
}
If there could be several notifications showing at any one time, a simple variable like that won't do. In that case you'd have to wrap your message in a container, the ID of which you could extract from your listener, and call a specific callback based on that, or passing that as a parameter. I won't go into detail here, seeing as the simple nature of show_notification implies an equally simple manner of close_notification. Since no ID's seems to be anywhere to be found, I'll assume that multiple active notifications are not supported.
A more appealing solution might have been to modify the plugin itself, rather than to work around it, so that you could pass callback functions directly to the plugin. Something like this:
show_notification({
message: 'Confirm',
type: 'success',
buttons: [
{ caption: 'Yes', click: function() { } },
{ caption: 'No', click: function() { } }
]
});
But of course, this is no way near possible to help you with, without first having a chance to look at what the plugin you're currently using looks like.

Related

Bind Clicked Object to Callback

I'm using the Modaal library and want to dynamically load the content of the modal via Ajax, which requires sending the ID for each clicked item through to the callback.
I think I need to bind the clicked element to the modaal function, but am not sure how. I think that jQuery's on method.
Without binding, the popup works (but data is not updated for each item):
var info_popup = $('.info-popup');
info_popup.modaal({
after_open: function(ev){
console.log(info_popup.data('unique_id'));
}
});
When I bind the function, it returns the data, but a second click is required to launch the modal:
$('.info-popup').on('click', function() {
var unique_id = $(this).data('unique_id');
return $(this).modaal({
after_open: function(ev){
console.log(unique_id);
}
});
});
So I'm thinking I need to somehow forward the clicked status to Modaal, but not sure how.
Update
I can achieve this by setting the start_open parameter in Modaal to true, but not sure if this is an elegant approach, and would like to see how it would be done from outside of Modaal.

From Bootstrap 4 collapse events, is it possible to extract which elements have been hidden/shown?

I'd like to add some additional functionality to a Bootstrap 4 accordion, and am considering using their events (https://getbootstrap.com/docs/4.0/components/collapse/#events). However, from their example,
$('#myCollapsible').on('hidden.bs.collapse', function () {
// do something…
})
It seems that no information is passed into the callback function.
I would like to know which element(s) were shown or hidden. Do I understand correctly that this is not possible using the .bs.collapse events?
It seems from http://api.jquery.com/Types/#Event that the shown/hidden element is simply accessible as this in the callback function. A little experiment with the debugger shows that this is indeed the case:
This is way late in the game but maybe someone will have benefit. For any of the 4 events you should be able to do something similar (in this case I want the id of the element that is being shown:
$('#accordionProperty').on('shown.bs.collapse', function (e) {
CallingSomeFunctionOfMineWithId(e.target.id);
})
And for hidden:
$('#accordionProperty').on('hidden.bs.collapse', function (e) {
CallingSomeFunctionOfMineWithId(e.target.id);
})
Hope this helps.

Event Listener Best Practices for web app

I'm making a web app, and my javascript is collecting quite a few $(document).on event listeners. It is working well enough for me, but it feels like there is must be a better way to organize it. Here's a sample:
// send quiz info via Ajax, then load form for the first question.
$(document).on('click', '#create-new-quiz', function(){
createNewQuiz();
$('#forms').load("dash/workspace.php", {
action : 'get-new-question'
});
});
// load the form to create the first question
$(document).on('click', '#finish-quiz', function(){
addQuestion();
$('#forms').load("dash/workspace.php",{
action : 'finish-quiz'
});
});
//call function to add a new question via ajax when the button is clicked.
$(document).on('click', '#add-question', function(){
nextAction = "add-question";
addQuestion();
});
That shows that I have a variety of buttons that are dynamically added and removed form the DOM. When they are clicked, a function is called.
Any suggestions? Am I already on the right path, or is there a better way to organize this?
I find the $('#button').click(function(){}) shortcut to be tidier.
Also, your first two event handlers are fairly similar and could be made a bit more generic i.e. passed an action as a variable:
$('.quizButton').click(function(e){
createNewQuiz();
$('#forms').load("dash/workspace.php", {
action : $('this').data('action');
});
});

Unbind one of two jQuery functions with same trigger?

I've written the following jQuery script, and I'm trying to make a 'cool transition', lol. When you start typing in #post-area-input input type=text-box, the page should switch to the 'compose.php' page (a form), while you type, and if you type over 19 characters, the textbox should expand to 80% width on keyup, if it's less than 30 characters, the box reverts to 300px.
Though, the problem is, if you blur out of the #post-area-input textbox, and then focus again, the load function reloads, and the other (possibly inputted) data in the compose.php file will be gone.
The question is: How do I make it so I prevent the last function from occurring again once it's already occurred? I've looked at .unbind(), but seeing as though there's another function being simultaneously on the same ID, that would disable the expanding function as well.
Thanks a lot! Very grateful for any answers :) (The script is below)
$('#post-area-input').keyup(function(){
if($('#post-area-input').val().length > 19){
$('#post-area-input').animate({width: '80%',}, 80, function(){});
}
else {
$('#post-area-input').animate({width: '300',}, 80, function(){});
}
});
$('#post-area-input').blur(function(){
if($('#post-area-input').val().length < 19){
$('#post-area-input').animate({width: '300',}, 80, function(){});
}
});
$('#post-area-input').keyup(function(){
$('#pcontent').load('compose.php').hide().fadeIn('slow');
});
I'd recommend against binding multiple anonymous functions to an event handler. Unbinding them can get ambiguous. Instead, declare the functions and bind/unbind them as such:
function keyUpFuncA(e) {
//code
}
function keyUpFuncB(e) {
//code
}
$(document).keyup(keyUpFuncA);
$(document).keyup(keyUpFuncB);
//then later when unbinding:
$(document).unbind("keyup", keyUpFuncA);
What may be tempting, but what you do not want to do, is resort to a global variable to track when load.php has been loaded.
You should name your keyup functions:
$('#post-area-input').bind("keyup.firstnameoffunction", function() { /* .. */ });
$('#post-area-input').bind("keyup.secondnameoffunction", function() { /* .. */ });
$('#post-area-input').unbind("keyup.firstnameoffunction");
you can also check what's currently binded to an object with this:
$('#post-area-input').data("events");
I'm a bit hazy on what is actually occurring, so please forgive me if I'm being obtuse, but one way to achieve event 'negation' could be to use a bool flag. For example:
var run_load_function = true;
...
$('#post-area-input').blur(function(){
run_load_function = false;
...
});
...
$('#post-area-input').keyup(function(){
if (run_load_function)
$('#pcontent').load('compose.php').hide().fadeIn('slow');
});
Then you also have the opportunity to reset the bool whenever you need it, providing some fine-grain control. Good question, and I'm looking forward to other answers! Hope this helps! :)

How to elegantly disable/enable all jQuery UI buttons?

I currently have several action buttons in different pages, and each button performs some AJAX call when clicked. In another word, I have code like this all over the places:-
$("#searchButton")
.button()
.click(function() {
...
$.get(url, { data: ...}, function(data) { ... });
...
});
After doing some testing, it seems like some AJAX calls take at least more than a few seconds to process before the callback function is being called.
My plan is to disable the button when the AJAX call is made and enable it back when the AJAX call is completed. This is to prevent user from clicking the button too many times when the request is being processed. One solution I found is to utilize the unbind() and bind() functions. After modifying my code, it looks like this now:-
var searchButtonClickHandler = function() {
...
$.get(url, { data: ...}, function(data) { ... });
...
};
$("#searchButton")
.button()
.ajaxStart(function() {
$(this).button("disable").unbind("click");
})
.ajaxStop(function() {
$(this).button("enable").bind("click", searchButtonClickHandler);
})
.click(searchButtonClickHandler);
This code works fine. Basically, it removes the click handler when the AJAX call is made and addes the click handler back when the AJAX call is completed.
My question is... is it possible to generalize the button disabling/enabling so that I don't have to implement ajaxStart() and ajaxStop on all UI buttons?
Ideally, I would like to use my earlier code snippet to register only the click event handler on the button, and then enable/disable all buttons using the .ui-button selector, something like this...
$(".ui-button")
.ajaxStart(function() {
$(this).button("disable").unbind("click");
})
.ajaxStop(function() {
// not sure how to bind the handler here
$(this).button("enable").bind("click", ?? );
});
... but, this doesn't work and I run into trouble in binding the click handler here.
The more I think about it, it almost seems like I need to create a button builder function to do this, for example:-
var createButton = function(selectorName, clickHandler) {
$(selectorName)
.button()
.ajaxStart(function() {
$(this).button("disable").unbind("click");
})
.ajaxStop(function() {
$(this).button("enable").bind("click", clickHandler);
})
.click(clickHandler);
};
// create button like this
createButton("#searchButton", function() {
...
$.get(url, { data: ...}, function(data) { ... });
...
});
... but this approach will only disable/enable the selected button, and I want to apply that to all UI buttons.
Do anyone has a better approach in disabling/enabling all the buttons in the page?
Thanks.
Different approach, according to this answer you should be able to get a reference to your previous event handler via .data("events");
Putting that together with your sample it should look like this:
$(".ui-button")
.ajaxStart(function() {
var events = $(this).data("events");
$(this).data("oldEvent", events.click[0]);
$(this).button("disable").unbind("click", events.click[0]);
})
.ajaxStop(function() {
var oldClick = $(this).data("oldEvent");
$(this).button("enable").bind("click", oldClick.handler);
});
Not sure if this will work completely yet, still messing around on jsfiddle.
Update
This should work, example on jsfiddle.
you can use $('input[type=button]').attr('disabled','disable'); to disable all buttons instead of binding and unbinding click event to the buttons... also you can use deferred jquery object, here is an example
Maybe you could attach your handler to the parent element of your buttons with delegate? That way there's only one handler function to bind/unbind.
Yahoo hosts a getElementByClass function, and you could assign a class such as "disableMe" to all your UI buttons. Then use getElementByClass('disableMe') to return an array of all the elements you want to disable.
The link: http://developer.yahoo.com/yui/dom/
You can use
$("button").each(function(){
//your code here
});

Categories

Resources