In most browsers (including older versions of Safari), the Javascript prompt
function returns null
when the user clicks \"Cancel\", and the empty s
I've managed to come up with a real workaround, since Safari added support for showModalDialog() in 5.1. Awfully convenient, that.
First, create a file with this content:
<html>
<head>
<title>Prompt</title>
<script type="text/javascript">
function a(){
if(window.dialogArguments.length > 0)
document.getElementById('a').textContent = window.dialogArguments[0]+'\n\n';
if(window.dialogArguments.length > 1)
document.getElementById('b').value = window.dialogArguments[1];
document.getElementById('b').focus();
}
function s(b){
window.returnValue=b?document.getElementById('b').value:null;
window.close();
}
function kp(e){
if(!e.DOM_VK_ENTER) e.DOM_VK_ENTER=13;
if(!e.DOM_VK_RETURN) e.DOM_VK_RETURN=13;
if(!e.DOM_VK_ESCAPE) e.DOM_VK_ESCAPE=27;
switch(e.keyCode){
case e.DOM_VK_ENTER:
case e.DOM_VK_RETURN:
if(e.preventDefault) e.preventDefault();
if(e.stopPropagation) e.stopPropagation();
e.returnValue = false;
e.cancelBubble = true;
s(1);
return false;
case e.DOM_VK_ESCAPE:
if(e.preventDefault) e.preventDefault();
if(e.stopPropagation) e.stopPropagation();
e.returnValue = false;
e.cancelBubble = true;
s(0);
return false;
default:
return true;
}
}
</script>
<body style="text-align:center;white-space:pre-wrap" onload="a()">
<span id="a"></span>
<input type="text" id="b" onkeydown="return kp(event)" /><input type="button" value="Ok" onclick="s(1)" /><input type="button" value="Cancel" onclick="s(0)" />
</body>
</html>
Then, for broken versions of Safari (there seems to be no way to feature-detect this without popping up a prompt and asking the user to hit "Cancel", so you'll probably have to do a User-Agent check), execute the following Javascript to replace window.prompt
:
(function(){
if(window.console && window.console.log)
window.console.log('Applying bugfix for Safari 5.1\'s prompt()');
var oldprompt = window.prompt;
window.prompt = function() {
return showModalDialog(location.protocol+'//'+location.host+'/js/safari-5.1-bugfix.html', arguments);
};
window.prompt.$orig = oldprompt;
})();
Of course, change the path /js/safari-5.1-bugfix.html
to the correct path to the above-created HTML file on your server. Unfortunately, we cannot use a data: URI as Safari apparently has another bug where it loses window.dialogArguments
and ignores window.returnValue
for dialogs with data:
URIs.
You can then use prompt()
as you normally would.
I tryed and this worked for me
var location="";
var p=prompt("type your location",location );
if(p!==null) { location = p; alert("ok do query"); }
var res = prompt('hello?', '')
if (res === null || res === '' && isSafari && confirm('was that cancel?'))
cancel
Sure, two in fact.
First the obvious one, redesign your system so an empty string is not a valid response. Think about it, when in a conversation is it acceptable for one guy to stare at you blankly in actual answer to your question?
The second one is to use modal dialogs, like jQuery ones, to ask for this information. You'll get complete control over it and the application won't look like it was made in 1996.
I appreciate the heads up- I hadn't noticed the behavior, but now I see that you are correct. Safari 5 behaves normally, 5.1 returns an empty string for either button click, if there is an empty string in the prompt field.
My only suggestion is to put a space character in the field to start with. Only the 'OK' button will return the space, cancel will return null or the empty string.
var p=prompt('what dya say?',' ');
if(!p)// cancel was *probably* clicked
else if(p===' ')//ok was clicked with no input
else// there is user input
The user could start to enter something, delete it, and then hit 'ok' instead of cancel, but that kind of case may as well be a cancel.