Postmessage in jQuery - javascript

I send data using Postmessage, but to get them right is not obtained.
My attempts:
Variant 1:
window.addEventListener("message", function(event) {
console.log(event.data);
}, false);
Variant 2:
$.bind("message", function (data) {
console.log(data);
}, false);
First variant works, but is not used jQuery. Show you how to use jQuery in this situation?
if needed sending code::
$(function() {
var iframe = $('iframe#someFrame');
setTimeout(function() {
iframe[0].contentWindow.postMessage('message to localhost', '*');
}, 1000);
});

You need to grab the originalEvent from jQuery:
$(window).on("message", function(e) {
var data = e.originalEvent.data;
});

Related

How to check if ajax request comes from a button

Im disabling all buttons when an ajax request is processing and enable them when ajax process is done and succeded. Now my question is... how do I check that the ajax request is comming from an specific element, in this case a button?
here is my code so far:
$(document).ajaxSend(function(){
if(ajax request comes from a button) {
$(':button').prop('disabled', true);
}
});
$(document).ajaxComplete(function () {
errorCount = 0;
$(':button').prop('disabled', false);
});
Any advice will be very appriciated :) Thanks all!
You can try like this :
$(document).ajaxSend(function(sender){
if(sender.tagName == 'button') {
$(sender).prop('disabled', true);
}
});
After lite research and use of the provided advices here I came up with the solution, here is my code now and working:
$(document).on('click', 'button', function () {
var $this = $(this);
$(document).ajaxSend(function(){
$this.prop('disabled', true);
});
$(document).ajaxComplete(function () {
$this.prop('disabled', false);
});

How to call a function in javascript?

I want to call a function every time my update was successful. The update is working my only concern is the alert pop-up every successful update.
$.post(
{
url: 'update_question.php',
data:
{
id: id,
new_question: newText,
},
success: function()
{
that.replaceWith("<section>"+newText+"</section>");
if(text != newText)
{
popup();
}
}
});
var popup = function () {
$(document).ready (function(){
$("#myWish").click(function showAlert() {
$("#success-alert").alert();
$("#success-alert").fadeTo(2000, 500).slideUp(500, function(){
$("#success-alert").alert('close');
});
});
});
};
var popup = function () {
$("#success-alert").alert();
$("#success-alert").fadeTo(2000, 500).slideUp(500, function(){
$("#success-alert").alert('close');
});
};
On the first update, pop-up showed but it doesn't show on the 2nd update
I think it'll solve your issue
$.post(
{
url: 'update_question.php',
data:
{
id: id,
new_question: newText,
},
success: function()
{
that.replaceWith("<section>"+newText+"</section>");
if(text != newText){
popup();
}
}
});
function popup() {
$("#success-alert").alert();
$("#success-alert").fadeTo(2000, 500).slideUp(500, function(){
$("#success-alert").alert('close');
});
};
The $(document).ready jquery function waits until the DOM is loaded into your browser before it executes the javascript code contained within it's function scope {}.
So remove $(document).ready from your code.
Also note that single page applications only need to list $(document).ready once and all the listener events you setup are defined within it's body.
So you should have it listed somewhere at least once and then you define all your initial event listeners within its body.

How to make pushState/onpopstate and jQuery events (e.g. on click) work nicely?

I am able to successfully use pushState and onpopstate to use the back/forward buttons on my AJAX enabled page.
One aspects of the AJAX feature is to automatically refresh a dropdown list when a link in clicked. This is my code this feature.
<a class="type" href="#Chr(35)#" data-type="B">B</a>
| <a class="type" href="#Chr(35)#" data-type="H">H</a>
window.addEventListener("popstate", function(event) {
if (event.state) {
document.getElementById("content").innerHTML = event.state.html;
}
});
$(".type").on("click", function (event) {
console.log("im here");
event.preventDefault();
getCourses({ type:$(this).data("type") });
try {
window.history.pushState({ "html": document.getElementById("content").innerHTML }, "", globalvars.baseurl+"/my/main?type="+$(this).data("type"));
} catch(exception) {
}
});
The problem happens when I press the back button and it renders a saved copy of the content section. When I try to click the links above, it wouldn't trigger (i.e. "im here" won't display now in my console where it used to work before I pressed the back button)
It seems the solution is to copy the link's on-click function inside my event listener particularly after "if (event.state)...".
window.addEventListener("popstate", function(event) {
if (event.state) {
document.getElementById("content").innerHTML = event.state.html;
$(".type").on("click", function (event) { console.log("im here") });
}
});
$(".type").on("click", function (event) {
console.log("im here");
event.preventDefault();
getCourses({ type:$(this).data("type") });
try {
window.history.pushState({ "html": document.getElementById("content").innerHTML }, "", globalvars.baseurl+"/my/main?type="+$(this).data("type"));
} catch(exception) {
}
});
That means I need to write the same code in 2 places. The only alternative I can think of is to remove the contents of the on-click function and put it inside a custom function.
window.addEventListener("popstate", function(event) {
if (event.state) {
document.getElementById("content").innerHTML = event.state.html;
$(".type").on("click", function (event) { test($(this).data("type")); });
}
});
$(".type").on("click", function (event) { test($(this).data("type")); });
function test(type) {
console.log("im here");
event.preventDefault();
getCourses({ type:type });
try {
window.history.pushState({ "html": document.getElementById("content").innerHTML }, "", globalvars.baseurl+"/my/main?type="+type);
} catch(exception) {
}
}
Is there any other way to do this?
Thanks a lot
Couple of ways... one is storing the inside function in a variable:
var typeClickHandler = function (event) {
test($(this).data("type"));
};
and then using that handler when you need it, in both places:
$(".type").on("click", typeClickHandler);
Other way is to use event delegation... this means that the listener is on document or some parent of this element that you want to listen to:
$(document).on('click', '.type', function (event) {
// note that we use event.target instead of this here
test($(event.target).data("type"));
});
and of course, you can combine those two solutions:
var typeClickHandler = function (event) {
test($(event.target).data("type"));
};
$(document).on('click', '.type', typeClickHandler);

JQuery Prevent Function .click Firing On Every Click

When I click a chat on my site I want the messages to be grabbed from the server so I use an $.post request like so :
$("#friendsDiv").on("click", "#aFriend", function(event){
retrieveMessages();
}
and this is what is in the retrieveMessages function
$.post("PHP/chat.php",
{
action:'retrieveMessages',
last_message: last_message,
conversation_id:conversation_id
},
function(data){
$("#messages").append(data);
last_message = $("#messages").find(".aMessage:last").attr("id");
$("#messages").animate({ scrollTop: $("#messages")[0].scrollHeight}, 1000);
}
);
The issue is that if the button is clicked very quickly multiple post requests will begin before the last_message is updated, this results in many copies of the same messages being displayed. Is there a way to prevent the button being clicked quickly or stop the post request being processed if another of the same request is already being processed?
EDIT
The #aFreind element is a DIV not a button
Typically in such situation you just disable a button until request is complete. For this you will need to provide a callback function. For example:
$("#friendsDiv").on("click", "#aFriend", function (event) {
// reference the button
var button = this;
// disable the button
this.disabled = true;
// provide a callback to be invoked when post is done
retrieveMessages(function() {
button.disabled = false;
});
});
function retrieveMessages(callback) {
$.post("PHP/chat.php", {
action: 'retrieveMessages',
last_message: last_message,
conversation_id: conversation_id
}, function (data) {
$("#messages").append(data);
last_message = $("#messages").find(".aMessage:last").attr("id");
$("#messages").animate({
scrollTop: $("#messages")[0].scrollHeight
}, 1000);
// execute callback which enables button again
callback();
});
}
Demo: http://jsfiddle.net/9t8fLdjn/
Your best bet would be to disable the button and then enable it after $.post
$("#friendsDiv").on("click", "#aFriend", function(event) {
$(this).prop('disabled', true); // disable
retrieveMessages();
});
and the retrieveMessage function
$.post("PHP/chat.php", {
action: 'retrieveMessages',
last_message: last_message,
conversation_id: conversation_id
}, function(data) {
$("#messages").append(data);
last_message = $("#messages").find(".aMessage:last").attr("id");
$("#messages").animate({
scrollTop: $("#messages")[0].scrollHeight
}, 1000);
$(this).prop('disabled', false); // enable it again
});
Instead of using on you could use the one jQuery function and bind the button again in the callback. Se http://api.jquery.com/one/
$("#friendsDiv").one("click", "#aFriend", retrieveMessages });
var retrieveMessages = function(){
$.post("PHP/chat.php", {
...
}).done(function(){
$("#friendsDiv").one("click", "#aFriend", retrieveMessages });
});
};

Adding a jQuery delay on autocomplete

I'm trying to create a jQuery autocomplete for an application:
$("#search-input").on('keyup', function() {
search = $(this).val();
autocomplete_div = $(".autocomplete")
$.get('/ajax/search/', {'search': search,}, function(response){
autocomplete_div.html(response)
});
});
What would I need to add to the above code to add a 400ms delay?
Use
setTimeout(function() {
// your code here
}, 400);
setTimeout is a method provided by the browser's window object.
A more complete example that cancels a timer if already set using clearTimeout would be:
var myTimer = 0;
$("#search-input").on('keydown', function() {
search = $(this).val();
// cancel any previously-set timer
if (myTimer) {
clearTimeout(myTimer);
}
myTimer = setTimeout(function() {
autocomplete_div = $(".autocomplete")
$.get('/ajax/search/', {'search': search,}, function(response){
autocomplete_div.html(response)
});
}, 400);
});
Also note use of on instead of the deprecated live.
Your code should look like this: (for jQuery 1.7+)
$(document).on('keyup', "#search-input", function () {
clearTimeout($(this).data('timeout'));
var _self = this;
$(this).data('timeout', setTimeout(function () {
$.get('/ajax/search/', {
search: _self.value
}, function (response) {
$(".autocomplete").html(response);
});
}, 400));
});
If using older jQuery version, use live() or better delegate(). BTW, you should bind it to closest static container, not document.
You can use the setTimeout() function to delay the start of the expression, in this case, your function. Beware that this does not delay processing beyond this code. It will only delay the start of this function, while continuing to process code after the function.
$("#search-input").live('keydown', setTimeout(function() {
search = $(this).val();
autocomplete_div = $(".autocomplete")
$.get('/ajax/search/', {'search': search,}, function(response){
autocomplete_div.html(response)
})
},400));
EDITED: to correct misplaced parentheses.

Categories

Resources