Modal External Url improperly redirecting - javascript

I am trying to modally open an external url. This external location enables the user to input a payment. After the user has sucessfully paid, the user should be directed back to the site that I am working on. In order to accomplish this, I am currently styling an iframe as a modal window. When the user clicks the 'next' button, a form action posts the external url to my iframe. Then, the css creates a modal-like effect in order to prevent the user from clicking buttons on the previous screen until the payment is input. The external url requires a return url and a cancel url as input parameters. When the user is done with the website, they will click either submit or cancel and the external site will navigate the user to the appropriate location. The problem that I am having is when the user clicks cancel or submit on the external site, the modal window remains open and navigates to the new location. What I want to happen is for the modal window to close and for the user to be navigated to the necessary url in the main browser. Does anyone have an idea for how to accomplish this or a method of coding this that would avoid this problem? Thanks!
Code:
<style>
.modalDialog {
position: fixed;
font-family: Arial, Helvetica, sans-serif;
top: -60;
right: 0;
bottom: 0;
left: 0;
background: #EAC5C5;
z-index: 99999;
opacity:0;
-webkit-transition: opacity 400ms ease-in;
-moz-transition: opacity 400ms ease-in;
transition: opacity 400ms ease-in;
pointer-events: none;
}
.modalDialog:target {
opacity:1;
pointer-events: auto;
}
.modalDialog > div {
width: 850px;
height: 700px;
position: relative;
margin: 10% auto;
padding: 5px 20px 13px 20px;
background: #fff;
}
.close {
background: #606061;
color: #FFFFFF;
line-height: 25px;
position: absolute;
right: -12px;
text-align: center;
top: -10px;
width: 24px;
text-decoration: none;
font-weight: bold;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
-moz-box-shadow: 1px 1px 3px #000;
-webkit-box-shadow: 1px 1px 3px #000;
box-shadow: 1px 1px 3px #000;
}
.close:hover { background: #00d9ff; }
</style>
<script type="text/javascript">
function openModal() {
window.location.assign("#openModal")
}
function cancelUrl() {
window.location.assign("#close")
}
</script>
<body>
<form action="https://hostedpage" target="my-iframe" method="post" id="testForm" runat="server">
<label for "Hidden4">Amount: </label>
<input type="text" name="Amount" id="Hidden4" value="" />
<input type="hidden" name="RURL" id="Hidden7" value="https://testurl.com" />
<input type="hidden" name="CURL" id="Hidden8" value="http://testurl2.aspx#close" />
<asp:Button ID="Submit" runat="server" Text="Next" UseSubmitBehavior="true" OnClientClick="openModal()" />
</form>
<div id="openModal" class="modalDialog" >
<div id="div1">
X
<iframe id="iframe" name="my-iframe" style="width: 850px; height: 700px;" frameborder="0" ></iframe>
</div>
</div>
</body>

So the code is more complicated than when I first asked this question, but the overall idea remains. So, I changed the RURL to be "testurl.com&type=submit" and the CURL to be "testurl2.aspx&type=cancel". I am using c# .net and in the Page_Load function, I am detecting if the type parameter exists. If it does, I change the iframe to a different view. This view has only two hidden buttons and a hidden string (I want to pass this info to the parent. The value is set in the Page_Load function).
<asp:View ID="newView" runat="server" >
<form id="frm" runat="server" style="display:none">
<asp:TextBox ID="Label25" runat="server" CssClass="NoDisplay" />
<input type="button" id="hiddenButton" onclick="parent.submit(this.form.Label25.value);" style="display:none" />
<input type="button" id="hiddenCancel" onclick="parent.cancel();" style="display:none" />
</form>
</asp:View>
Even though the iframe is a different view, it still goes through all the motions of loading the page. I capture the page load and determine if the type parameter is in the url. If it is, I click one of the buttons on the view. This triggers the parent functions that either submit or cancel the modal window. I know this seems a little roundabout, but it has to be because of the fact that the buttons the user is clicking to close the modal are on the hosted site. Also, doing this allows me to do more complicated things in the process, such as capture the response from the hosted site and throw it into our database.
<script type="text/javascript">
function testFunction() {
var urlParms = new Array();
urlParms = document.URL;.split("?");
if (typeof thisNVP[1] !== "undefined") {
var parmArray = urlParms[1].split("&");
var thisfrag = new Array();
for (i = 0; i < parmArray.length; i++) {
thisfrag = parmArray[i].split("=");
if (thisfrag[0] == "type") {
if(thisfrag[1] == "cancel") {
document.getElementById("hiddenCancel").click();
} else {
document.getElementById("hiddenButton").click();
}
}
}
}
}
</script>
<body onload="testFunction()">
</body>

Related

How to stop spinner after operation is finished

I am building my first web app using Flask. I'm new to html/ JavaScript/ CSS - please bear with me.
The app does the following: The user uploads an Excel file as follows:
<form method="POST" enctype="multipart/form-data">
<input type="file" name="file" id="file" />
Then they select certain parameters using dropdown lists. When the user clicks "Submit", the data is manipulated using pandas and a new file is exported in Excel.
I managed to add a spinner to the "submit" button using html and CSS. I added an event listener to my JavaScript so the spinner is activated when the button is clicked. At the moment, the spinner runs indefinitely, however I would like the spinner to stop and the button text to revert to "submit" once the operation is finished, i.e. the export is complete. Does anybody know how I can accomplish this?
Here is my html:
<button type="submit" id="submit" class="button">
<span class="button__text">Submit</span>
</button>
Here is my CSS:
<style>
.button {
position: relative;
padding: 8px 16px;
background: #009579;
border: none;
outline: none;
border-radius: 2px;
cursor: pointer;
}
.button:active {
background: #007a63;
}
.button__text {
font: bold 20px "Quicksand", san-serif;
color: #ffffff;
transition: all 0.2s;
}
.button--loading .button__text {
visibility: hidden;
opacity: 0;
}
.button--loading::after {
content: "";
position: absolute;
width: 16px;
height: 16px;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
border: 4px solid transparent;
border-top-color: #ffffff;
border-radius: 50%;
animation: button-loading-spinner 1s ease infinite;
}
/*animate spinner - spin from 0 to 1 turn*/
#keyframes button-loading-spinner {
from {
transform: rotate(0turn);
}
to {
transform: rotate(1turn);
}
</style>
Here is my JavaScript:
<script type="text/javascript">
(() => {
const elem = document.getElementById('submit');
elem.disabled = false;
elem.addEventListener('click', e=> {
elem.classList.add('button--loading');
});
})();
</script>
Basically, your frontend (the HTML/Javascript) needs some way of knowing when "the export is complete". Depending on your definition of "export" and "complete".
At the most rudimentary level, you could have the frontend poll the server every second after the upload starts, and have the server return some kind of status as to what the state of the process is. This could be as simple as:
GET /status/1234
> {"status": "IN_PROGRESS"}
which, when the "export is complete" switches to:
> {"status": "COMPLETE"}
And when the frontend receives the COMPLETE status, it removes the spinner. Notice the 1234. You will need some way of identifying the upload in progress. One way to do this would be to assign it a random id when you first accept the form, so the initial POST /upload returns > {'id': 1234} which the client can then use for the subsequent polling.
If "export is complete" actually only means that the file is finished uploading, you could still use a polling method, but a much slicker way is to use the client (web browser) method of determining how many bytes have been sent (see this SO answer).

localStorage causes infinite refreshing the page?

I'm doing localStorage for a simple form. When user open up the form, all the saved data will be displayed in the corresponding input filed, and after user fills out the form, all the info will be saved.
Now I can save the data and also display the data, just that when I reopen the page, data is displayed while the page's being infinite refreshed. Does anybody know how did that happen?
Here is the code:
HTML:
<form id="formData">
<fieldset>
<legend>Please fill in</legend>
<label for="name">Name:</label>
<input name="name" type="text"><br/>
<label for="txt">Introduction:</label>
<input name="txt" type="textarea"><br/>
<label for="someCheck">Checkbox:</label>
<input name="someCheck" type="checkbox"><br/>
<label for="someRadio">Radio:</label>
<input name="someRadio" type="radio"><br/>
<input type="submit">
</fieldset>
CSS:
fieldset{
width: 50%;
margin: 0 auto;
padding: 5px 20px;
box-sizing: border-box;
}
label{
width: 18%;
display: inline-block;
}
input{
margin: 0;
padding: 0;
}
input[type=submit]{
padding: 2px 10px;
outline: none;
border-radius: 4px;
margin: 6px 0;
cursor: pointer;
}
Jquery:
if(Modernizr.localstorage){
var form=document.querySelector('#formData');
if(localStorage.formData){
//step one:
//display the stored value, title=my+title&...&
var fd;
fd=localStorage.formData.split('&'); //['title=my+title']
$.each(fd,function(index,pair){
pair=pair.split('=');//title,my+title
console.log(pair[0]+":"+pair[1]);
if(pair[1]==="on"){
form[pair[0]].checked=true;
}else{
form[pair[0]].value=unescape(pair[1]).replace(/\+/g," ");
}
});
}
//step two:
//save form to storage when filled outline
form.submit(function(e){
//serialize form data to url
localStorage.formData=$(this).serialize();
alert('Okay, refresh the page now.');
e.preventDefault();
});
}
The infinite reload is caused by form.submit(). That is triggering the HTML submit action. Part of which is to reload the page.
I suspect what you really want is to listen for the submit event and do the local storage save:
document.querySelector("#formData").addEventListener("submit", function(e){
localStorage.formData=$(this).serialize();
alert('Okay, refresh the page now.');
e.preventDefault();
});

Show element based on URL

I am working on one task where I need to hide an element and redirect it to another URL when user click on a div.
If user directly go to that URL then it should not hide element as it has not clicked yet.
I have manage to do FIRST point.
Element will be on both pages.
My logic is here but it is not working:
flag = false;
$(document).ready(function() {
$("div.main").click(function() {
flag==true;
$(".notired").hide();
});
if ((document.location.href.indexOf("xyz") > 0) && (flag==true))
$(".notired").hide();
});
HTML:
<div class="main">
<a href="xyz.com" title="Click here">
<img src="../images/notif.png">
</a>
<span class="notired">';
echo $count;
echo '
</span>
</div>
CSS:
.notired
{
display: inline-block;
background: #E43C03;
text-align: center;
color: #FFF;
font-size: 12px;
font-weight: bold;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
border-radius: 6px;
width: 14px;
z-index: 1;
margin-left:-9px;
}
.main
{
width:50px;
}
Looking for the solution.
Make sure your element is hidden by default, then:
check if the current URL matches the one you need
if it does, then do nothing as you want to keep it hidden
if it doesn't then show it
and if i understood correctly you need always to hide on the click function, then simply put the .hide() inside the event handler
$(document).ready(function() {
if(window.location.hash) {
// The URL contains the hash sent when clicked on button
$(".notired").hide();
}
});
and here
<a href="xyz.com#clicked" title="Click here">

Problems with jQuery Image Slideshow / Rotating Banner using timeout / interval

I am trying to build a simple web page for my website using HTML, CSS, JavaScript and JQuery. What I want is to display a slideshow of a few of my images at the top of the page. I just want the pictures to fade out and fade in after one another forever until the user closes the browser. I want each picture to be displayed for a certain amount of time, after which it will fade out and another picture would fade in.
I referred to this as well as this post on SO but couldn't find a solution. I got some idea from this page and tried to develop some code.
The overall layout of the website is as follows:
For this, my index.html page looks like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Home Page</title>
<link rel="stylesheet" href="css/style.css" />
<script language="javascript" src="js/jquery-1.10.2.min.js"></script>
<script language="javascript" src="js/common.js"></script>
<script language="javascript" src="js/banner_rotator.js"></script>
</head>
<body onload="loadBody();">
<div id="wrapper">
<img id="headerlogo" />
<div id="nav">
Home
About
Weddings
Portraiture
Landscapes
Products
Miscellaneous
Services
Contact
</div>
<div id="container">
<div id="content">
<!-- Main content starts here -->
<p>
Welcome to the world of The Siblings' photography.
</p>
imgpos = <span id="imgposspan"></span>
<!-- Main content ends here -->
</div>
</div>
</div>
</body>
</html>
The CSS is like this:
body {
background-color: transparent; color: #d0d0d0;
font: normal normal 11px verdana; margin: 0 auto;
}
#wrapper {
background-color: transparent; width: 960px; margin: 0 auto;
}
#headerlogo {
border-radius: 0px 0px 5px 5px; display: block;
width: 960px; height: 350px;
background-color: #d0d0d0;
}
#container {
width: 100%; margin-top: -35px;
}
#nav {
background-color: transparent;
color: #888888; border-radius: 5px; padding: 10px;
width: 100%; position: relative; top: -40px;
}
#nav>a {
border-radius: 5px; display: inline-block; padding: 5px 19px;
font-weight: bold; border: 1px solid transparent;
color: #888888; background: none none transparent no-repeat;
}
#nav>a:link {
text-decoration: none; border-color: transparent; background-image: none;
}
#nav>a:visited {
text-decoration: none; border-color: transparent; background-image: none;
}
#nav>a:hover{
text-decoration: none; border-color: #ffa500; background-image: url("/img/1x30_ffa500.gif");
background-repeat: repeat-x; box-shadow: 0px 0px 5px #ffd700;
}
#nav>a:active {
text-decoration: underline; border-color: transparent;
background-image: none;
}
#content {
background-color: #f0f0f0; color: #202020;
padding: 5px; border-radius: 5px;
}
The common.js file is like this:
$(document).ready(function (){
var images = new Array();
images[0] = new Image();
images[0].src = "img/coverpics/sea_link.jpg";
images[1] = new Image();
images[1].src = "img/coverpics/marine_drive.jpg";
images[2] = new Image();
images[2].src = "img/coverpics/backbay.jpg"
banner_rotator("headerlogo", images, 0);
});
And, the banner_rotator.js file is like this:
function banner_rotator(imgid, imgarray, imgpos) {
setInterval(function() {
if (imgpos >= imgarray.length || imgpos == undefined)
imgpos = 0;
$("#"+imgid).attr({ "src" : imgarray[imgpos].src });
$("#"+imgid).fadeIn(1000, "linear");
$("#"+imgid).delay(6500);
$("#"+imgid).fadeOut(500);
// $("#imgposspan").html(imgpos);
imgpos++;
}, 8000);
}
Now, my problem description is as follows:
For the first few seconds the top portion is blank. The image is not showed, even though I am developing and having all the files on my local machine itself.
This first image directly pops up on the screen, instead of fading in.
After this image fades out, the image block vanishes, as if it is set to display: none; for a second. The entire page that follows the image shifts up. Then, the next image fades in and so forth everything runs normal.
Hence, in short, I have problems with the starting of this slideshow. Can anybody please help?
Also please tell me where can I put my code so everybody here can access and see for themselves how it runs?
JSFIDDLE
<img id="headerlogo" />
Don't do that (an image tag with no src attribute)
Put a div that will hold the space (set position:relative with width & height in css)
Then the problem is that you are changing your src attribute in your time loop, this ain't smooth
In your CSS, suppose you name your slider wrapper headerlogo_wrapper
div.headerlogo_wrapper > img {position:absolute;display:none;left:0;top:0}
Then you append your images to the space holder you have created (they will not show obviously)
Then you fadeIn your first image then you launch your setInterval :
//after having appended the images to the slider wrapper :
var $img = $("div.headerlogo_wrapper > img");
$img.eq(0).fadeIn(1000, "linear");
var ivisible = 0;
setInterval( function() {
$img.eq(ivisible).fadeOut(500);
++ivisible;
if (ivisible>$img.length-1) ivisible = 0;
$img.eq(ivisible).stop().fadeIn(1000, "linear");
}, 8000);
(If you want an image to be shown during load, some simple changes shall do; also if the first interval start immediately you obviously don't need to fadeIn "manually" the first image)
Try this: http://jsfiddle.net/3XV5M/
Your problem is the first time you run the timer function it won't run straight away. It will be run after 8000ms. The way this fiddle works is it will execute the function immediately and the run itself again after 8 seconds. Note I'm using setTimeout instead of setInterval.
function banner_rotator(imgid, imgarray, imgpos) {
if (imgpos >= imgarray.length || imgpos == undefined) imgpos = 0;
$("#"+imgid).attr({ "src" : imgarray[imgpos].src })
.fadeIn(1000, "linear")
.delay(6500)
.fadeOut(500);
imgpos++;
setTimeout(function() {banner_rotator(imgid, imgarray, imgpos) }, 8000);
}
The other problem is you need to hide the images first, so they can fade in. They wont fade in if they are already visible.
#headerlogo {
border-radius: 0px 0px 5px 5px;
width: 960px; height: 350px;
background-color: #d0d0d0;
display: none; /* Add this */
}
Then to prevent the other elements jumping up when you fade the images out, wrap the image element inside a div and set it's height. I used a div with a class of banner and added this style:
.banner {
height: 350px;
}
Hope that helps.
The problem is that you are fading out at the end of your interval. So replace this:
$("#"+imgid).attr({ "src" : imgarray[imgpos].src });
$("#"+imgid).fadeIn(1000, "linear");
$("#"+imgid).delay(6500);
$("#"+imgid).fadeOut(500);
with this:
$("#"+imgid).fadeOut(500)
$("#"+imgid).queue(function(){
$("#"+imgid).attr({ "src" : imgarray[imgpos].src });
$("#"+imgid).fadeIn(1000);
$("#imgposspan").html(imgpos);
imgpos++;
$(this).dequeue();
});
JSFIDDLE demo

Create a popup window in plain javascript

In a specific page a user will press a button but on button press before the actual processing, I need occasionally to present to the user a list of options to select the appropriate one and use that selection in order to be able to proceed the processing.
So essentially I need to display a pop-up window that shows a select box with available options and get the user's selection and then continue processing.
So to do this I found that I need a combination of window->open/prompt/showModalDialog
I found a way to present a pop-up window to the user with the options via
var newWindow = window.open("", null, "height=200,width=400,status=yes,toolbar=no,menubar=no,location=no");
newWindow.document.write("<select>");
newWindow.document.write("<option>");
newWindow.document.write(obj);
newWindow.document.write("</option>");
newWindow.document.write("</select>");
Example for passing just one option.
But I can not seem to find how to get back the selection.
The prompt on the other hand returns the selection, but I don't think I can make it display my select.
The showModalDialog returns the selection, but seems to expect another web page as a parameter. So it is not suitable for me.
How can I create my pop-up using plain javascript?
Here is a simple solution that will allow you to fetch value from opened window. All you need is to inject JavaScript code into opened window that will interact with the parent window using window.opener:
HTML
<input id="value" />
<button onclick="openWindow();">Open</button>
JavaScript
function openWindow() {
var i, l, options = [{
value: 'first',
text: 'First'
}, {
value: 'second',
text: 'Second'
}],
newWindow = window.open("", null, "height=200,width=400,status=yes,toolbar=no,menubar=no,location=no");
newWindow.document.write("<select onchange='window.opener.setValue(this.value);'>");
for(i=0,l=options.length; i<l; i++) {
newWindow.document.write("<option value='"+options[i].value+"'>");
newWindow.document.write(options[i].text);
newWindow.document.write("</option>");
}
newWindow.document.write("</select>");
}
function setValue(value) {
document.getElementById('value').value = value;
}
Working example here: http://jsbin.com/uqamiz/1/edit
The easiest way is to have a superimposed div with a a high z-index, with transparent background acting as an overlay. You could then have another div which is centered above the overlay(with higher z-index) and containing the list markup
CSS
#shim {
opacity: .75;
filter: alpha(opacity=75);
-ms-filter: "alpha(opacity=75)";
-khtml-opacity: .75;
-moz-opacity: .75;
background: #B8B8B8;
position: absolute;
left: 0px;
top: 0px;
height: 100%;
width: 100%;
z-index:990
}
#msgbx {
position: absolute;
left: 50%;
top: 50%;
height: 150px;
width: 350px;
margin-top: -75px;
margin-left: -175px;
background: #fff;
border: 1px solid #ccc;
box-shadow: 3px 3px 7px #777;
-webkit-box-shadow: 3px 3px 7px #777;
-moz-border-radius: 22px;
-webkit-border-radius: 22px;
z-index:999
}
HTML
<div id="shim"></div>
<div id="msgbx">inject list markup here</div>
To show popup
document.getElementById('shim').style.display=document.getElementById('msgbx').style.display ="block";
To Hide
document.getElementById('shim').style.display=document.getElementById('msgbx').style.display ="none";

Categories