I don't speak English very well.
My company has developed a web application for internet explorer that very strenuously uses the function showModalDialog and waits for the result.
We are planning to extend the use of the application to other browsers (Firefox, Chrome), and I need to replace "showModalDialog logic" with a logic that will work well on all browsers.
I originally tried using an ajaxcontroltoolkit modalpopup with an iframe inside.
My problem is that, after I have showed the modalpopup, I cannot wait for the user to close the popup window without freezing the web interface.
function OpenDialog() {
var result = window.showModalDialog("page1.html", "input_parameter", "width:100px; height:100px");
//When the popup went closed
alert("result: " + result);
}
//Override showModalDialog function for compatibility with other browser
function myShowModalDialog(url, pars, options) {
//show a jquery modalpopup or ajaxcontroltoolkit modalpopup with an iframe ....
iframe.src = url;
//I need to wait here until the modal popup closed
//HOW?
//get the value from popup
var res = ???????;
return res;
}
window.showModalDialog = myShowModalDialog;
I cannot change the logic for every page in the webapp.
I searched for a method to override the showModalDialog function and recreate the same logic (wait until the popup is closed and get the result that the popup provides for the caller).
Any ideas? Thanks to all
You've discovered the reason why JavaScript relies heavily on asynchronicity, event handlers, and callback functions.
The best solution would be to restructure your code so that your events trigger on event handlers, using jQuery or somesuch to bind the event handlers to the event. Alternatively, you could always use a function in a timeout loop to check periodically if the modal is closed yet, and execute the continuation of your code when it is. That's pretty hacky though, and I don't recommend it. In general, trying to force asynchronous code to fit a synchronous model gets really messy.
Unless I'm not following you, what you need is a callback when the user closes the dialog, right?
Whatever method is executed when the user closes the dialog, monkey patch it to call your function. (A monkey patch is code that adds functionality to existing code, but keeps the old code also).
So if your close method/function looks like:
myCloseDialog = function(){
// do important closing stuff
}
Then you can monkey patch like so:
myNewCloseDialog = function(){
// do important callback stuff, or call your callback function
myCloseDialog(arguments);
}
By the way, your English is very fine :)
I've created a short demo of my suggestion in the comment:
<!DOCTYPE html>
<html>
<head>
<title>modal overlay</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.overlay
{
background-color: rgba(0, 0, 0, 0.1);
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
z-index: 100;
margin:0;
display:none;
}
.box
{
position:absolute;
top:0;
left:0;
bottom:0;
right:0;
width:400px;
height:300px;
background:white;
margin:auto;
padding:10px;
}
</style>
<!--
prepare a style to show/hide overlay and
prevent lost focus when clicking outside the box
-->
<template id="template1">
<style id="style-modal">
*
{ pointer-events: none;
}
.overlay *
{pointer-events: auto;
}
.overlay
{ display:block!important;
}
</style>
</template>
</head>
<body>
<input id="some-input1" type="text">
<button class="modal-open" type="button">open modal dialog</button>
<div id="overlay1" class="overlay">
<div class="box">
<input id="modal-input1" type="text">
<button type="button" class="modal-close">close</button>
</div>
</div>
<script>
document.addEventListener
( 'DOMContentLoaded',
function(ev)
{
var
template1 = document.getElementById('template1'),
styleModal = template1.content.getElementById('style-modal'),
overlay1 = document.getElementById('overlay1'),
box = overlay1.querySelector('.box'),
head = document.querySelector('head')
;
//TODO: could iterate over querySelectorAll
document.querySelector('button.modal-open').addEventListener
( 'click',
function(ev) { head.appendChild(styleModal); },
false
)
overlay1.querySelector('button.modal-close').addEventListener
( 'click',
function(ev)
{ template1.content.appendChild(styleModal);
document.dispatchEvent(new CustomEvent('closemodal', {detail:{relatedTarget:box}}));
},
false
)
},
false
);
document.addEventListener
( 'closemodal',
function(ev){ alert(ev.detail.relatedTarget.querySelector('input').value); },
false
);
</script>
</body>
</html>
Note that this example makes use of <template> element which isn't implemented by IE yet. You can easily generate the style-element in the script, hold it in a variable and add/remove it to/from the head.
Have a look at my showModalDialog polyfill using a modal element and ECMAScript 6 generators, so it does not need an explicit callback function. Statements after showModalDialog() will run after closing the modal.
Related
I write a simple userscript because I need to log in again when I do not operate some sites for a long time.
But now the script is not what I expected. I wanted to regularly open and then close a window after clicking "startrefresh".
(function() {
'use strict';
const CustomInterval=1000*60*6;
function loop(){
setTimeout(function() {
var RefreshTimeWindow=window.open(window.location.href);
setTimeout(() => RefreshTimeWindow.close(),3000);
loop();
}, CustomInterval);
}
var startrefresh=document.createElement("div");
startrefresh.id="startrefresh";
startrefresh.innerHTML=`<a id='start' href='javascript:void(0);'>---startrefresh---</a>`;
startrefresh.style="z-index:9999; width:200px; height:50px; position:fixed; right:150px; top:200px; display:block; background-color:#FFFF9E; font-size:24px;";
document.body.appendChild(startrefresh);
document.getElementById ("start").addEventListener ("click", loop, false);
})();
It seems that settimeout will be ineffective when I switch to another page in the same tab.
The browser will also block the popup. How can I do it without disabling popup blocking?
How to improve it?
How i can append attach on iframe with src adress?
How i can manipulate div attaching on it iframe object with content?!
(Included into Wordpress page) by using brackets for testing....
I want to make custom js included into wordpress page without use jquery
(if u have any ideas cause i read the wordpress does support jquery libraries) could be good. I accept and jquery too as idea. I choose to do not use jquery cause i think wordpress does not support it.
javascript
<script async="" type="text/javascript">
var Divfrm = document.getElementById('#frame');
var ifrm = document.createElement('iframe');
function evtTrigger(){
document.addEventListener('click',function(e){
e.preventDefault();
Divfrm = document.appendChild(ifrm);
ifrm.setAttribute('src','http://google.com');
});
function close(){
ifrm = document.Detach(Divfrm);
};
return DivFrm = document.InnerHTML = ('');
</script>
html
<!--I'din't know why worpress cover field "script" tag?!-->
<h1 style="color: aqua; text-align: left;">Magic fountain mod example script</h1>
<p style="color: aqua; text-align: left; margin-left: 20px;">Can you ever saw glow fountain?, that was is available now</p>
<div id="frame" style="outline-color: mediumturquoise; background: rgba(0,128,128,0.2); overflow-y: scroll; height: 400px; margin-top: 20px; margin-bottom: 30px; color: mediumaquamarine;">
<!--here div was as role dialog ^^^>
<p>Explanation about code here text</p>
</div>
<div>
<button onclick="evtTrigger()">Show video</button>
<button onclick="close()">Hide this</button>
</div>
When the user clicks Show Video, it will call evtTrigger() -- but all that function does is attach the click listener to the document, it doesn't run that handler function. In fact, after clicking Show Video, after that every click on the page will run your handler function.
You're also appending the iframe to the entire document, not just your div (hence you're using document.appendChild instead of Divfrm.appendChild) -- that's probably not what you want.
So remove your addEventListener code, put the iframe appending code directly in the evtTrigger function, and change Divfrm = document.appendChild(ifrm) to just Divfrm.appendChild(ifrm). Then it should work.
Question is really unclear. I assume you want to add the ifrm inside Divfrm on clicking somewhere which fires the evtTrigger function. And then remove the ifrm when calling close()
If this is your goal, try this
var Divfrm = document.getElementById('#frame');
var ifrm = document.createElement('iframe');
function evtTrigger(){
Divfrm.appendChild(ifrm);
ifrm.setAttribute('src', 'http://google.com');
};
function close(){
Divfrm.removeChild(ifrm);
};
By the way, you can't load google.com inside your iframe because browser won't allow it. If this is just as an example, then it's fine.
I am trying to disable the Parent window as soon as the child window is opened. I would like to gray out the parent window whenever pop window is opened.
Below is my popup window code-
<html>
<head>
<title>Applying</title>
</head>
<body>
<script>
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi,
function(m,key,value) {
vars[key] = value;
});
return vars;
}
var variable1 = getUrlVars()["parameter1"];
var myScript = document.createElement('script');
myScript.setAttribute('type', 'text/javascript');
myScript.setAttribute('urlId', '420');
myScript.setAttribute('dataTitle', variable1);
myScript.setAttribute('dataemail', 'admin#domain.net');
document.body.appendChild(myScript);
</script>
<input name="Apply" type="button" id="Apply" value="Apply" ONCLICK="window.location.href='some_url'">
</body>
</html>
Below is my Parent window code-
<html>
<body>
<SCRIPT LANGUAGE="JavaScript">
<!--
function popUp(URL) {
day = new Date();
id = day.getTime();
eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=550,height=650,left = 570,top = 300');");
}
</script>
<input type=button value="Apply" onClick="javascript:popUp('popup_window_url')">
</body>
</html>
What's the best and easy way to disable the parent window here? Any example with my above code will help me a lot in understanding a simple example.
I saw various other post on the stackoverflow but I am not able to understand how to incorporate those things here in my code. I am trying to do something like this.
Any suggestions will be of great help.
Updated fiddle from answer in this question with iframe support http://jsfiddle.net/LT5JC/
Open function is rather simple
function open(url) {
$('#block').fadeIn(); // show grayed pane
$('#iframe').attr('src', url); // update src of iframe
$('#container').fadeIn(); // show container with iframe
}
The example you gave doesn't use a popup in the sense of a new browser window, but a div on the existing page onto which the new content is loaded. This method is possible, as you would use an Ajax call to populate your popup. By using an Ajax call to the second page, you are able to tell when the request has finished, and fade the background out as required. If you really want to, you could use an iFrame, and check when that's loaded, but in my opinion this method isn't as nice.
A simple implementation using jQuery:
var cover = $("<div id='cover'></div>");
var content = $("#content"),
popup_window = $("#popup-window"),
popup_launcher = $("#popup-launch");
// When we click a button, load our new content into our popup
// and fade the window in once the request has completed. Also,
// fade our cover in, thus restricting the user from clicking the content beneath
popup_launcher.on("click", function() {
popup_window.load(child_url, function() {
popup_window.fadeIn();
content.fadeIn(cover);
});
});
// When a close button is clicked inside the popup window, fade it out.
popup_window.on("click", ".close", function() {
popup_window.fadeOut();
cover.fadeOut();
});
CSS
#cover {
position:fixed;
top:0;
bottom:0;
left:0;
right:0;
z-index:2;
display:none;
background:RGBA(0,0,0,0.5);
}
#popup-window {
position:fixed;
left:30%;
right:30%;
top:30%;
bottom:30%;
z-index:3;
}
Very simple example, but our #cover has to be positioned beneath our #popup-window, so we use the z-index property to ensure this.
Edit - whilst the Ajax method would be nicer, bear in mind that due to HTTP access control, you'll only be able to request pages on the same domain (generally), so if you need to open external resources, you'll probably need to use an iFrame solution.
I have some code implementing a context menu on a textbox, the context menu is to have an Undo and Redo item that calls the browsers native methods by using document.execCommand('undo').
This code functions as I require on Chromium based browsers but on FireFox and Opera the results are not as expected.
My expectation is that undo and redo will function like the native browser context menu for an input element. The result is that the input elements do not undo and redo, however div elements with the contenteditable attribute set, do function as expected.
So I'm wondering if this is a bug in one of the browsers, either Chromium or FireFox/Opera, or if I am not implementing the code correctly?
The following code gives an example of the issue that I'm facing. All help is appreciated.
<input contenteditable id="input" type="text"></input>
<div contenteditable id="div" class="inputLike" type="text"></div>
<button id="button1" type="button">Undo</button>
<button id="button2" type="button">Redo</button>
var input = document.getElementById("input"),
button1 = document.getElementById("button1"),
button2 = document.getElementById("button2"),
div = document.getElementById("div");
console.log("Undo", document.queryCommandSupported("undo"));
console.log("Redo", document.queryCommandSupported("redo"));
function doUndo() {
document.execCommand('undo', false, null);
}
function doRedo() {
document.execCommand('redo', false, null);
}
button1.addEventListener("click", doUndo, false);
button2.addEventListener("click", doRedo, false);
On jsfiddle
If you want to look at the actual context menu code, then it is also available on jsfiddle.
I don't think it's possible with document.execCommand(), in Firefox at least. You could make your own undo stack, or in future use the new UndoManager API (implemented in Firefox 20 but disabled by default).
Here's an example of using your own undo stack by taking snapshots of the value and selection using the input event. You could improve this by merging consecutive typing events into a single undo item, for example. There is also some inconsistency between browsers with the caret position, but it's just a proof of concept.
http://jsfiddle.net/FMSsL/
Using the new DOM UndoManager API seems to be simple: if I understand it right and if the browser supports it, the <input> element will have an undoManager property, which is an object with undo() and redo() methods, so the task is as simple as
document.getElementById("input").undoManager.undo();
Unfortunately only Firefox 20 and above supports the UndoManager API and it's disabled by default. Even once it's enabled, the following demo does not work even though I think it should, so this option is some way off being viable.
http://jsfiddle.net/DULV4/2/
As I discovered from the question I asked, the undoManager API in Firefox DOES work. I looked at the jsFiddle link (http://jsfiddle.net/DULV4/1/) posted by Tim Down, and there appear to be a couple issues:
An undoScope attribute must be set to true (either in-line or programmatically). This enables the undoManager for that element.
Anything you undo has to first be created by the undoManager.transact() function (though I'm wondering if there is any way to incorporate the native undo stack into the current undoManager's transaction history).
I'm only a novice with this, so take what I say with a grain of salt and see https://dvcs.w3.org/hg/undomanager/raw-file/tip/undomanager.html for all the information on using it.
IT IS POSSIBLE TO GET HISTORY OF THE UNDO AND REDO
function check(){
if(document.queryCommandEnabled("undo"))
{
$('#undoResult').text("Undo is active");
}else{
$('#undoResult').text("Undo is not active");
}
if(document.queryCommandEnabled("redo"))
{
$('#redoResult').text("Redo is active");
}else{
$('#redoResult').text("Redo is not active");
}
}
$(document).on('keypress',function(e) {
if(e.which == 13) {
document.execCommand("insertLineBreak");
return false;
}
});
check();
div{
border:1px solid black;
height:100px;
}
button{
color:white;
background:black;
height:40px;
width:49%;
padding:1px;
text-align:center;
margin-top:10px;
}
p{
font-size:30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div contenteditable="true">
</div>
<button onclick="document.execCommand('undo',false,null);check()" >Undo</button>
<button onclick="document.execCommand('redo',false,null); check()" >Redo</button>
<p id='undoResult'></p>
<p id='redoResult'></p>
I am normally used to "window.open" to open a popup window into a new URL. How can open a window into a new URL, shadow out/grey out the current window, and on close remove the shadow background.
Is it best to use jQuery to do this? Could I use the default libraries without use jquery plugins?
I want to do something like this and then "disable" my shadow on unload. Hopefully that uses core jQuery libraries or standard javascript calls. I want to avoid using any plugins besides jQuery.
var popup = window.open('http://google.com', 'popup');
showShadow();
$(window).unload(function() {
if(!popup.closed) {
disableShadow();
}
});
Basically, you can open the popup and set that window the beforeunload. In short, something like this:
popup = window.open("", "name", "width=400, height=300")
popup.onbeforeunload = function() { $('#shadow').hide();}
I created a fiddle for you.
http://jsfiddle.net/DDksS/
So you want to build your own modal box using jQuery instead of using an existing plugin? ...OK, let's play (as it was already pointed out, using popups is not a user-friendly solution):
Your check list :
- the trigger
- the shadow layer
- the modal box size and position
- add content to modal and display it along the shadow
1) The trigger is a simple html link to open the content inside the modal
open url
... we will pass the size of the modal via data-width and data-height (HTML5) attributtes.
2) The shadow layer is the html structure that we will append to the body after the trigger. We can set the structure in a js variable
var shadow = "<div class='shadow'></div>";
3) As we mentioned, the size of the modal is set through some data-* attributes in the link. We would need to do some math
var modalWidth = $(this).data("width");
var modalHeight = $(this).data("height");
var modalX = (($(window).innerWidth()) - modalWidth) / 2; // left position
var modalY = (($(window).innerHeight()) - modalHeight) / 2; // top position
NOTE : $(this) is our trigger selector .myModal that we'll get inside an .on("click") method later on. BTW, the .on() method requires jQuery v1.7+
4) Now we need to create the modal's html structure and pass the content href. We'll create a function
function modal(url) {
return '<div id="modal"><a id="closeModal" title="close" href="javascript:;"><img src="http://findicons.com/files/icons/2212/carpelinx/64/fileclose.png" alt="close" /></a><iframe src="' + url + '"></iframe></div>';
}
... as you can see, our structure contains a close button to remove the modal and the shadow layer. The function also gets a parameter when is called (url) which allows to set the src attribute of the iframe tag.
NOTE : we have to use the iframe tag to open external urls, however we should always consider the same origin policy and other security restrictions when using iframes.
So now, we need to put together all the events after we click on our .myModal trigger, which are appending both the shadow and the modal box to the body and to remove them when we click on the close button so
$(".myModal").on("click", function(e) {
e.preventDefault();
// get size and position
modalWidth = $(this).data("width");
modalHeight = $(this).data("height");
modalX = (($(window).innerWidth()) - modalWidth) / 2;
modalY = (($(window).innerHeight()) - modalHeight) / 2;
// append shadow layer
$(shadow).prependTo("body").css({
"opacity": 0.7
});
// append modal (call modal() and pass url)
$(modal(this.href)).appendTo("body").css({
"top": modalY,
"left": modalX,
"width": modalWidth,
"height": modalHeight
});
// close and remove
$("#closeModal").on("click", function() {
$("#modal, .shadow").remove();
});
}); // on
STYLE : of course we will need some basic CSS style to make our modal elements work properly:
.shadow {width: 100%; height: 100%; position: fixed; background-color: #444; top: 0; left:0; z-index: 400}
#modal {z-index: 500; position: absolute; background: #fff; top: 50px;}
#modal iframe {width: 100%; height: 100%}
#closeModal {position: absolute; top: -15px; right: -15px; font-size: 0.8em; }
#closeModal img {width: 30px; height: 30px;}
* SEE DEMO *
BONUS : you could also bind a keyup event to close the modal using the escape key
$(document).keyup(function(event) {
if (event.keyCode === 27) {
$("#modal, .shadow").remove();
}
}); //keyup
LAST NOTE : the code is subject to many improvements and optimization but is a basic layout of what many lightboxes do. My last recommendation : use fancybox for more advanced functionality ... sometimes it doesn't worth the effort to re-invent the wheel ;)
Using Javascript to create new popup windows is so 1990's, not to mention not very user-friendly. What you're looking for, both UI-wise and looks-wise is a modal dialog; there's billions of examples and pre-packaged jquery snippets on how to create modal dialogs, and most client-side UI frameworks such as jQuery UI, YUI and Bootstrap have modal dialog functionality built-in. I'd recommend diving into those.
Try jquery plugins such as fancybox http://fancybox.net/
Basically, you need to attach an event listener to your new window to run the disableShadow() function in your webpage.
If you add this to your code I think it should work.
popup.unload(function() { disableShadow() });
Adapted From: Attach an onload handler on a window opened by Javascript
You should use the beforeUnload event of the window instance returned by the window.open() call, like this:
popup = window.open('relative_url', 'popup');
$(popup).bind('beforeunload', function() {
disableShadow();
});
Note that the URL must be on the same domain in order for the opener window to interact with the popup!
See the fiddle here: http://jsfiddle.net/hongaar/QCABh/
You can open a new window, and when it closes you can execute a function in the opener window.
I'll do a quick example by writing the script right into the new window, but you could also just include it in the HTML that is used for the new window if a link is supplied for the popup:
$("#popupBtn").on('click', openPopup); //using a button to open popup
function openPopup() {
$('#cover').fadeIn(400);
var left = ($(window).width()/2)-(200/2),
top = ($(window).height()/2)-(150/2),
pop = window.open ("", "popup", "width=400, height=300, top="+top+", left="+left),
html = '<!DOCTYPE html>';
html += '<head>';
html += '<title>My Popup</title>';
html += '<scr'+'ipt type="text/javascript">';
html += 'window.onbeforeunload = function() { window.opener.fadeoutBG(); }';
html += '</sc'+'ript>';
html += '</head>';
html += '<body bgcolor=black>';
html += '<center><b><h2 style="color: #fff;">Welcome to my most excellent popup!</h2></b></center><br><br>';
html += '<center><b><h2 style="color: #fff;">Now close me!</h2></b></center>';
html += '</body></html>';
pop.document.write(html);
}
window.fadeoutBG = function() { //function to call from popup
$('#cover').fadeOut(400);
}
Using a fixed cover that is faded in will also prevent any clicks on elements on the page, and you could even attach a click handler to the cover with pop.close() to close the popup if the cover is clicked, just like a modal would close if you clicked outside it.
One of the advantages of calling a function on the parent page from the popup is that values can be passed from the popup to the parent, and you can do a lot of stuff you otherwise could'nt.
FULLSCREEN_FIDDLE
FIDDLE
All you need is standard javascript function showModalDialog. Then your code will look like
var url = 'http://google.com';
showShadow();
var optionalReturnValue = showModalDialog(url);
//Following code will be executed AFTER you return (close) popup window/dialog
hideShadow();
UPDATE
As hongaar stated Opera does not like showModalDialog. And it does not fire on(before)unload when popup is closed either. To make workaround you need timer (window.setTimeout) to periodically check if window still exists. For further details look here
Why don't you just use jQuery UI? I know that you don't want another library but is rather extension of jQuery rather then another lib since it can live without it.
It have great deal of widget and every one of them can be changed,configured.
What is best that it can viewed with different themes, even you can create one with they're theme roller fast and easy, and it can be modularized. Just take what you need in current project.
Check this out:
http://jqueryui.com/dialog/#modal-form
It's really simple to use. With this you can open modal dialog with frame to different url. On close event you can do whatever you want.
Try ColorBox
its simple and easy to use
http://www.jacklmoore.com/colorbox
quick example:
<link rel="stylesheet" href="http://www.jacklmoore.com/colorbox/example1/colorbox.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://www.jacklmoore.com/colorbox/colorbox/jquery.colorbox.js"></script>
<script>
$(document).ready(function(){
//Examples of how to assign the ColorBox event to elements
$(".iframe").colorbox({iframe:true, width:"80%", height:"80%"});
});
</script>
<a class='iframe' href="http://google.com">Outside Webpage (Iframe)</a>
You can also try this out ...
http://fancyapps.com/fancybox/
Examples here
try http://thickbox.net/ in modal type, examples: http://thickbox.net/#examples
I've done this as well.
First off, some URLs simply WILL NOT WORK in an (iframe) modal window; I can't say if it'll work in the browser-supported native modal windows as I haven't tried this. Load google or facebook in an iframe, and see what happens.
Second, things like window onunload events don't always fire (as we've seen some people already).
The accepted answer version will also only work on a static page. Any reloading (even F5 on the page) will cause the shadow to hide. Since I can't comment on the accepted answer, I at least wanted this to be known for anyone else looking at these results.
I've taken a less technical approach to solving this problem in the past: polling.
http://jsfiddle.net/N8AqH/
<html>
<head>
<script type="text/javascript">
function openWindow(url)
{
var wnd = window.open(url);
var timer = null;
var poll = function()
{
if(wnd.closed) { alert('not opened'); clearInterval(timer); }
};
timer = setInterval(poll, 1000);
}
</script>
</head>
<body>
click me
</body>
</html>
See the link above for an example. I tested in IE, FF, and Chrome. My timer is every 1 second, but the effort on the browser is so low you could easily drop this down to 100 ms or so if you wanted it to feel more instant.
All you'd have to do in this example is, after calling window.open, call your "show shadow" function and instead of alerting when you close, call your "hide shadow" function and it should achieve what you're looking for.