I have gone insane trying to figure out how to make this work. Code looks roughly like:
function onDropDownChanged() {
$("#updatePanel").load(
"myUrl",
{ id: $("#myDropDown option:selected").val() },
onPanelLoaded
);
}
function onPanelLoaded() {
$("#theTextInput").focus();
}
$(document).ready(function() {
$("#myDropDown").change(onDropDownChanged);
}
The first time the change handler is fired, it does the ajax update, and the text box is focused.
However, on subsequent changes, it continues to do the ajax update, but the text box is never focused again.
I found that if in onDropDownChanged, I added $("#updatePanel").empty() before the ajax call, the text box would always get focused. The problem with that is the entire form disappears for a second, causing an ugly flash. Given ajax is supposed to make things like this nice, it's not a workaround I want to use.
It seems like it should work, but I wonder if the DOM isn't updated by the time the callback is invoked. You might want to see if introducing a delay helps.
function onPanelLoaded() {
setTimeout( function() { $("#theTextInput").focus(); }, 500 );
}
Including the HTML on the page and what is returned via load() would be helpful if this doesn't work.
I had a similar problem with IE6 and IE7, but setTimeout() was not a reliable solution. Sometimes it worked, sometimes it did not. It didn't work on some machines at all, and the 500ms value was completely arbitrary anyway. The focus() function worked exactly as expected without any timeout in both Firefox and Chrome, of course.
My solution was to call focus() twice for IE:
function onPanelLoaded() {
var panel = $('#theTextInput');
panel.focus();
panel.focus();
}
Now THAT did what I intended in the first place.
Related
Hey I'm making a custom backend for Wordpress, it's a bit 'ghetto' but it turned out to be bigger than expected so I'm running with it. Works perfectly fine stylistically and functionally but for some reason if I submit a new post with it, I get "Are you sure you want to navigate away from this page?" or whichever browser equivalent.
I've tried a shitton of variations of onbeforeunload = null, returning blank functions, etc, none of the solutions have worked on any browser, so I assume it's something to do with Wordpress backend constantly updating...?, I read that it might be a factor that you can't bind onbeforeunload like a normal event as well, so a combination of these two makes me wonder, how can I permanently silence "are you sure" notices on a page, no questions asked?
It seems everywhere on the web is a variation of this question and/or setting the onbeforeunload null worked for them, it does not in any sense for me, even in inline JS onthe form. I have no idea why it's even triggering, I assume I moved something when reconstructing the WP submit form that causes it to ungroup data... or something, but I just need to silence all dialog from this page that is "save changes", that's all, seems like it's easy enough with a bind/event handler but they haven't worked and I don't quite get how the event works.
I've tried this and some other binds thus far, as well as putting return onbeforeunload null function inline the form
window.onbeforeunload = function() {
return null;
}
window.onbeforeunload = null;
jQuery('a, input').click(function(){
window.onbeforeunload = null;
});
If the events were registered using jquery with $(window).on('beforeunload' you can remove them using $(window).off('beforeunload'
This example demonstrates the click event, but it works the same with the beforeunload event:
$(function() {
$(window).on('click', function() {
alert(1);
});
$(window).on('click', function() {
alert(2);
});
$(window).off('click')
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I've edited the default alert() function like this:
window.alert = function(str){
//custom alert
}
Essentially, the new function will show an HTML <div> modal.
Backstory:
I want to answer to this question because I am having a problem. The alert is hidden and will show when the custom alert function is called. So the custom alert is basically showing the element and changing it's text. Therefore, when I have multiple alert() calls, only the last message is displayed! :(
But, unlike the default alert box. It of course won't pause the webpage until the alert goes away like the default alert() function.
Is it possible to imitate this "pause the webpage" behavior?
Also, is there another way other then using setTimeout() to check if isCustomAlertOpen == true to delay another custom alert from triggering until the current one is dismissed?
Edit:
Is there a way to queue up the custom alerts?
I don't mind jQuery, but I thought it might be overpowered here.
My question title is bad. Can someone think of a better title for me please?
There is no way to block the execution because JavaScript is asynchronous (except obviously 3 modal functions and XmlHttpRequest).
For the same reason, you can't wait for a previous alert to be closed, but you can use events to create a stack of alerts using this pattern:
window.alert = (function() {
var stack = [];
var showNextAlert = function() {
var div = document.createElement("div");
/* Here, configure the div, show the string from stack[0] and add it to the document ... */
var okButton = /* ... */;
okButton.addEventListener("click", function() {
div.parentNode.removeChild(div);
stack = stack.slice(1);
if(stack.length > 0) {
showNextAlert();
}
});
}
return function(msg) {
stack.push(msg);
if(stack.length == 1) {
// Show it immediately if the stack is empty
showNextAlert();
}
};
})();
You should also use another name for this function instead of changing native properties (here window.alert).
Is it possible to imitate this "pause the webpage" behavior?
The answer to this is no. There are ways to block the ui (sync ajax call, long loop etc). But you wouldn't be able to stop these when the user has click the ok button.
A better approach would be to restructure the code so that it didn't run synchronously. Ie you wouldn't need to block the ui while waiting for the user.
Also, is there another way other then using setTimeout() to check if isCustomAlertOpen == true to delay another custom alert from triggering until the current one is dismissed?
One way to do this is: instead of setting a flag in one place and checking it repeatedly in another. You can use the concept of events. One part of code is waiting for an event to be triggered and another part triggers it. There is a library in jQuery which can do this for you or you could read up on it and write your own.
I have a console on my website which shows a log file, and i've set it up so it refreshes every 500 ms.
jQuery(document).bind("ready", function() {
$("#console").animate({ scrollTop: $(document).height() }, 1000);
function doStuff() {
$( "#console" ).load("console/getlog.php");
$('#console').scrollTop($('#console')[0].scrollHeight);
}
setInterval(doStuff, 500);
});
that works fine, but the problem arrives when i try to select some text in the console. Every time it updates, my selection is cancelled
what can i do to solve this?
Instead of using $( "#console" ).load("console/getlog.php"); to update your console, consider using $( "#console" ).append();. This should prevent the whole thing from reloading and removing your selection.
You can do something like append(getLog()); where getLog() is a function that returns the content of the log. Append can be used with hard coded content (text/html) or the results from a function.
More information on .append() here
Also here - jQuery API doc
Like MelanciaUK suggested, pause the doStuff() when the console is in focus.
You may detect that focus via mouseover/mouseout (so the console stops updating when you hover it), or on mousedown/mouseup, which isn't that usable since you have hardly time to press Cmd + C to save your selection.
Some dirty example: http://jsfiddle.net/ZEW5s/ (updated with pause after mouseup: http://jsfiddle.net/ZEW5s/1/)
tymeJV suggestion to use setTimeout instead of setInterval is a good one, though.
The only way i can think of solving it is by making the delay long so you got time to select the text.
Not much of an answer, but I can't comment, so here it goes.
There are some methods for accessing and manipulating the selection, although they depend on the browser if I remember correctly. Check this out:
https://developer.mozilla.org/en-US/docs/Web/API/Selection
I'd recommend changing the doStuff() to save the current selection, and try to apply it after the loading.
So I have the weirdest problem, in my company's CMS we have a newsletter system that does an AJAX call to send an e-mail. Now this works perfectly in all modern browsers on all operating systems, however it does not for one client.
This client is using Windows 7 and IE9, I have Windows 7 myself and tried IE9 (even with all compatibility modes) but it would always work.
I don't know why it doesn't work for them, however I was able to "fix" it by placing an alert before and inside the AJAX call.
I am thinking it must be something with their hardware or connection, and was hoping somebody might have an explanation. Here is the AJAX call (with the alerts) so you can see there is nothing wrong (right?):
$('#send_single').unbind().click(function(event) {
event.preventDefault();
processing();
alert('one');
$.post(
'newsletter/ajax.php',
{
action: 'send_single',
email: $('#single_email').val(),
template: $('#select_template').val(),
id: $('#select_newsletter').val()
},
function(data) {
alert('two');
finished_processing();
cmsalert(data);
}
);
});
processing() fades in a processing box, which finished_processing() then removes. Without the alert boxes the finished_processing() never happens, with the alertboxes it runs as expected.
processing() and finished_processing()
function processing(){
$('#full_overlay').fadeIn();
$('#processing').fadeIn();
}
function finished_processing(){
$('#full_overlay').fadeOut();
$('#processing').fadeOut();
}
#full_overlay is a fullscreen fixed div with a white overlay. #processing is a centered div containing a loading gif and a "Please wait..." string.
finished_processing() doesn't happen, so I don't think cmsalert() is in any way related. (cmsalert slides in a div at the bottom of the page containing a - usually success - message)
Try something like the example show in the jquery docs, changing your finished_processing function like:
function finished_processing(){
$('#full_overlay').promise().done(function() { this.fadeOut(); });
$('#processing').promise().done(function() { this.fadeOut(); });
}
You may also face problems if the client clicks several consecutive times, keep that in mind. I believe the return of $.post() can also be used in the same lines ($.post().promise() or $.post().done) in case you could store in a variable and use that. You may also like to have a look at Deferred Object.
I am trying to redirect the user to a different page after 1 second via javascript:
setTimout("document.location.href='new_page.html'", 1000);
however, in Internet Explorer, this happens immediately, not 1 second later. Any thoughts?
What you've quoted should work, except for a couple of minor errors:
You're missing the "e" in setTimeout
You're using document.location; it should be window.location.
Just tested it on IE8 and it waited as expected. Are you doing this from within some event that would make the page reload anyway, like a form's submit event? If so, you'll need to cancel the form submission to avoid that superceding your setTimeout code. How you do that will depend on how you're hooking the event (e.g., if you're using a DOM0 onsubmit="..." handler, use return false;; if you're using something more modern, you want event.preventDefault(); if you're using jQuery, Prototype, or some other library, check their docs for the right way to prevent the default action of the event).
Now, although it works the way you did it, it's typically better to do this with a function rather than code within a string, e.g.:
setTimeout(function() {
window.location.href = 'new_page.html';
}, 1000);
But either way should work.
Wrap it in a function.
setTimeout( function() { location.href = 'new_page.html'; }, 1000 );
Note that, if you are always doing this on page load, you should really use the meta refresh tag instead.
<meta http-equiv="refresh" content="1;url=new_page.html">