I have a function that is triggered by "Calculate" button
I need this line to only run once per session (session could be 1 day or until browser is reloaded).
$('.popup-with-form').magnificPopup('open');
This opens a Magnific Popup. Once this function is executed (popup opens), if "calculate" button is pressed again, I don't want popup to open again.
JS / JQuery code:
function StateChanged() {
if (XmlHttp.readyState == 4 || XmlHttp.readyState == "complete") {
$('.popup-with-form').magnificPopup('open');
document.getElementById("CalcSum").innerHTML = XmlHttp.responseText;
document.getElementById("CalcSumPopup").innerHTML = XmlHttp.responseText;
}
}
PS I know many of these questions pop up, and I tried different ways of doing thing, but since I'm "code-challanged" and do not know JQuery or JS I can't figure it out. I know there is a .one "thing" in JQuery, but don't understand how to make it work.
If you want to execute this line only once per browser session you can use sessionStorage. When you set a variable on sessionStorage it keeps its value until the browser closes (e.g. until you close Google Chrome).
So you can do something like:
if (!sessionStorage.alreadyClicked) {
$('.popup-with-form').magnificPopup('open');
sessionStorage.alreadyClicked = 1;
}
Be careful with sessionStorage because it can only store string values.
If you want the line to be executed only once per page session (which means once every page refresh) then you can use any variable and set it to true to remember you already executed the line:
if (!window.alreadyClicked) {
$('.popup-with-form').magnificPopup('open');
alreadyClicked = true;
}
Try
Edit, v2
I read about .one but could not figure it out :( ... I actually need
it to run once ONLY when CALCULATE button is pressed. – Roofing
Calculator
html
<!-- removed `action="javascript:GetInfo();"
, accept-charset="UNKNOWN"
, enctype="application/x-www-form-urlencoded"
, method="post"`
from `form` attributes -->
<form id="formcalc" style="text-align: left;">
<!-- changed `input` `type` to `button` -->
<input name="calculate" type="button" value="Calculate" />
</form>
js
$("#formcalc > input[name='calculate']")
.one("click", function(e) {
e.stopPropagation();
GetInfo();
});
v1
$("a.popup-with-form").one("click", function(e) {
// do stuff, once
// i.e.g.,
// `XmlHttp.onreadystatechange = StateChanged;` at `ShowSum()`
$(e.target).remove(); // remove element when `click`ed once
});
jsfiddle http://jsfiddle.net/guest271314/7K3tn/
See http://api.jquery.com/one/
Please use below.
disableOn
null
If window width is less then number in this option - lightbox will not be opened and default behavior of element will be triggered. Set to 0 to disable behavior. Option works only when you initialize Magnific Popup from DOM element.
Can also accept Function as a parameter, which should return true if lightbox can be opened andfalse otherwise. For example:
disableOn: function() { if( $(condition) { return false; } return true; }
Related
What would be a viable way to accomplish the following:
A website has two pages; Parent page and Inside page. If user came to the Inside page directly by typing in the address or by following a link from a page other than Parent page, then show "foo". If user came to the Inside page from the parent page, then show "bar".
I would need this done in JS if possible. If not, PHP is a secondary choice.
You can get the page the user came from with document.referrer.
So you could implement your solution like this:
if (document.referrer === 'yoursite.com/parentpage') {
// do bar
} else {
// do foo
}
Please try this
This code in second page
jQuery(window).load(function() {
if (sessionStorage.getItem('dontLoad') == null) {
//show bar
}
else{
//show foo
}
});
This code in parent page
jQuery(window).load(function() {
sessionStorage.setItem('dontLoad','true')
});
with php:
There is a simple way is to create a mediator page which redirect to inner page after make a session / cookie.. then if you'll get session / cookie, you show foo & unset session.
if someone directly come from url, no session / cookie found & it show bar..
You can use the document.referrer but this is not always set. You could add a parameter to the URL on the parent page and then check for its existance in the child page
Link on the parent page:
<a href='myChildPage.html?fromParent=1'>My Child Page</a>
JS code on your child page:
var fromParent=false;
var Qs = location.search.substring(1);
var pairs = Qs.split("&");
for(var i = 0; i < pairs.length; i++){
var pos = pairs[i].indexOf('=');
if(pos!==-1){
var paramName = pairs[i].substring(0,pos);
if(paramName==='fromParent'){
fromParent=true;
break;
}
}
}
if(fromParent){
alert("From Parent");
}else{
alert("NOT From Parent");
}
This method isnt 100% foolproof either as users could type in the same URL as your parent page link. For better accuracy check the document.referrer first and if not set use the method i've outlined above
intelligent rendering with jQuery
After using #Rino Raj answer, i noticed it needed improvement.
In javascript, the load() or onload() event is most times much slower,
since it waits for all content and images to load before executing your attached functions.
While an event attached to jQuery’s ready() event is executed as soon as the DOM is fully loaded, or all markup content, JavaScript and CSS, but not images.
Let me explain this basing, on code.
When i used #Rino Raj's code, with load() event, it works but on the second/called page, the content appears before class="hide fade" is added (which I don't really want).
Then i refactored the code, using the ready() event, and yes,
the content that i intended to hide/fade doesn't appear at all.
Follow the code, below, to grasp the concept.
<!-- Parent/caller page -->
<script type="text/javascript">
$(document).ready(function() {
sessionStorage.setItem('dontLoad', 'true');
});
</script>
<!-- Second/called page -->
<script type="text/javascript">
$(document).ready(function() {
if(sessionStorage.getItem('dontLoad') == null) {
$("#more--content").removeClass("hide fade");
} else {
$("#more--content").addClass("hide fade");
}
});
</script>
I have created a server control for a login panel.
On this panel I have a textbox for the username and a textbox for the password.
Below that there is the button for login.
I want the button to be disabled if either or both textboxes are empty.
For that I created a function that checks the length of the contents of the textboxes.
function doCheck()
{
var lngth1 = document.getElementById('pnLogin_txtUserName').value.length;
var lngth2 = document.getElementById('pnLogin_txtPassword').value.length;
if (lngth1 > 0 && lngth2 > 0)
{
$('#pnLogin_btLogin').removeAttr('disabled');
} else {
$('#pnLogin_btLogin').attr('disabled','disabled');
}
}
I run this function at the start and on every keyup event.
That works great.
The problem is when the browser starts with the page. It fills in the username and password if they are stored.
When the function is then run, it still disables the button even though there is information in the textboxes.
I tried this:
setTimeout( function()
{
doCheck();
}, 2000);
But after 2 seconds I see the button disabling while seeing my credentials filled in.
If I inspect the element in Chrome, I don't see my credentials in the html code.
So where is it stored? How can I detect this?
You will not see the values in the html as they are not actually in the DOM.
You may access their values using $("#pnLogin_txtUserName").val() and
$("#pnLogin_txtPassword").val().
I would simplify your function and use jQuery specific syntax rather than native javascript.
function doCheck() {
var lngth1 = $("#pnLogin_txtUserName").val().length;
var lngth2 = $("#pnLogin_txtPassword").val().length;
if (lngth1 > 0 && lngth2 > 0) {
$('#pnLogin_btLogin').prop('disabled', false);
} else {
$('#pnLogin_btLogin').prop('disabled', true);
}
}
I also changed your code from .attr to .prop for disabling the input. Find more information with this stackoverflow question
The problem is when the browser starts with the page. It fills in the username and password if they are stored. When the function is then run, it still disables the button even though there is information in the textboxes.
Your code is being executed the moment it is loaded and parsed by the browser. The proper jQuery method is to use whats called .ready() which will execute after jQuery detects the page has finished loading.
$(document).ready( function() {
doCheck();
});
Or more simplified to:
$(function() {
doCheck();
});
detecting change
We can detect when the values get changed by bind an event listener:
$("pnLogin_txtUserName").change(function() {
console.log( 'pnLogin_txtUserName has changed', $(this).val() );
});
If we add a class to your inputs, say .loginElements, then we do things a bit easier and detect several different events:
$(".loginElements").on( 'change keypress', function() {
doCheck();
});
Can someone explain to me what i am doing wrong in this code?
http://jsfiddle.net/14njfqef/
var isLoggedIn = function(state){
if(state == true) {
$("#content-container").show();
$("#account2").show();
$("#account").hide();
}
else(state == false){
$("#content-container").hide();
$("#account2").hide();
$("#account").show();
}
}
onload=function() {
isLoggedIn(false);
}
On load i want the divs to hide but then when i click the button i want the divs to show?
Is the boolean function set out in the correct way?
Piece below tries to re-arrange piece at OP. onload not appear clearly defined , not addressed , though could be attached to an event , i.e.g., window.onload = onload . Wrapped blocks in jquery .ready() event . Removed js onclick markup from html , included at script element , or loaded from file at jquery .on("click") event . Added strict comparison operator === (an added =) to if / else if statements. Changed input type to button. Added if to else portion of composition (see link posted at comments by Felix Kling).
Try
$(function() {
var isLoggedIn = function(state){
if(state === true) {
$("#content-container").show();
$("#account2").show();
$("#account").hide();
}
else if(state === false){
$("#content-container").hide();
$("#account2").hide();
$("#account").show();
}
};
isLoggedIn(false);
$("input[type=button]").click(function() {
isLoggedIn(true)
})
});
jsfiddle http://jsfiddle.net/guest271314/14njfqef/3/
changed your html to
<input type="submit" value="Boolean" id="toggle"/>
rewrote your js as
// JQuery run at start effectivly
$(document).ready(function() {
function isLoggedIn(state) {
if(state == true) {
$("#content-container").show();
$("#account2").show();
$("#account").hide();
}
else {
$("#content-container").hide();
$("#account2").hide();
$("#account").show();
}
}
// JQuery attaching a click event using an anonymous function
// and hard coding your isLoggedIn to true, passing variables is a bit more complicated.
$('#toggle').click(function() {isLoggedIn(true)});
isLoggedIn(false);
})
Well there's a few things I am not sure if you are aware of so I feel there's some responsibility on my end to make sure they are mentioned. They are a number of syntactical errors in your post that are stopping this from working so instead of addressing them I feel its necessary to update your view on what JQuery you are using as well as your selector choice.
First I would add a class structure to all of the div's to target them all at once so you can save on some lines of code. In production it's always better to have less code for all of your visitors to download because even a little bit of code can get out of control after enough hits on a webpage. Having to serve it kills speed and so does having to process three separate jquery selections as opposed to one.
I would change the HTML to...
<body>
<div id='content-container' class='boxes'>
Content Container
</div>
<div id='account' class='boxes'>
account
</div>
<div id='account2' class='boxes'>
account2
</div>
<input id="validateButton" type="submit" value="Boolean">
</body>
This way you can simply target all divs with $(".boxes"); ... I wouldn't recommend getting into the habbit of using $("div");
Next I would change the JQuery to being more JQuery friendly code. Its not always useful to use an onload event from pure Javascript to handle JQuery driven functions in correct time to the loading of DOM objects. Therefore you should use $( document ).ready( handler ) to handle this load event properly just in case it causes you problems down the road. The more common shorthand of this ready event is a simple $(function() { }); wrapper.
The rest of the code can be re-arranged to this....
var isLoggedIn = false; //<--Instantiate to false, make global to window level scope
//Load event Corrected For JQuery
$(function() {
$(".boxes").hide(); //<--Hide on load
//Add A Proper Updated Click Event To Button
$("#validateButton").click(function() {
isLoggedIn = true; //<--Should include real functionality not hand coded to true
checkLoginAndRespond(); //<--Validate Login Status
});
});
function checkLoginAndRespond() {
//If Logged, Show
if(isLoggedIn) {
$(".boxes").show();
//Else Don't
} else { $(".boxes").hide(); }
} //end function
Lastly, the version. New versions of JQuery have not been released for some time and seem to not be in the making so its a safe bet to use their most recent versions as it has thousands of pages of help for its syntax and it's very stable. I would recommend anything in the 2.0 or higher series JQuery.
I am assuming you have JQuery library loaded. Try
if (state) {
$("#content-container").show();
$("#account2").show();
$("#account").hide();
}
else{
$("#content-container").hide();
$("#account2").hide();
$("#account").show();
}
to solve your problem.
Several problems:
1) I am trying to make this script run more efficiently.
2) When the user clicks either pop out button it opens a windows and hides the element. (Currently I am using .detach() to remove the embedded video player because in Firefox .toggle() just hides the player but keeps the audio playing. Is there a better way to do this?
3) In theory by clicking the button again or closing the window manually it should un hide or .toggle() the element but does not for the video player due to detach().
4) If a user pops out the window manually closes it and then pops it out again to only close it once more the element does not .toggle() back.
See it in action here, http://www.mst3k.tv/.
$(document).ready(function() {
$('#lights').click(function(){$('#darkness').fadeToggle(500);});
$("#lights").toggle(function(){$("#lights").attr('id','lightsoff');},function(){$("#lightsoff").attr('id','lights');});
/**VIDEO**/
var videoWin;
$('#video-toggle').click(function(){
$('#video').fadeToggle(500);
$('#video').detach();
});
$('#video-toggle').click(function(){
if (videoWin && !videoWin.closed) {
videoWin.close();
return false;
}
videoWin = window.open(
$(this).attr('rel'),
'videoWin',
'width=600,height=480,toolbar=0,top=0,left=0,menubar=0,location=0,status=0,scrollbars=0,resizable=1');
return false;
}
);
var watchVideo = setInterval(function() {
if (videoWin.closed) {clearTimeout(watchVideo);$('#video').show(500)}
return false;
}, 1);
/**CHAT**/
var chatWin;
$('#chat-toggle').click(function(){
$('#chat').fadeToggle(500);
/*$('#chat').detach();*/
});
$('#chat-toggle').click(function(){
if (chatWin && !chatWin.closed) {
chatWin.close();
return false;
}
chatWin = window.open(
$(this).attr('rel'),
'chatWin',
'width=320,height=480,toolbar=0,top=0,left=601,menubar=0,location=0,status=0,scrollbars=0,resizable=1');
return false;
}
);
var watchChat = setInterval(function() {
if (chatWin.closed) {clearTimeout(watchChat);$('#chat').show(500)}
return false;
}, 1);
/*$("a.btn").fitText(1.2, { minFontSize: "6px", maxFontSize: "14px" });*/
});
It would be better if you created a jQuery plugin for your code so you can re-use it and avoid DRY. Here are a couple of options:
Plugin 1: jQuery popupWindow
Plugin 2: jQuery winPop
Also note that the closed property is not part of any W3C specification, however it might be supported across Browsers.
You could also write a JS function that could be reused. According to the w3cschools website the window.closed property is supported in most major browsers and you can check for it prior to triggering the event.
instead of
if(videoWin && !videoWin.closed)
you could use
if (typeof videoWin!='undefined'){ /* it has been created */}
elseif(typeof videoWin='undefined') { /*it's okay to open the new window*/}
Make sure you're not creating the variable if you're using this as a check though until the window open event has been fired. Since you're creating the var a couple of lines above your function declaration it will always return as defined.
You'll need to specify a target object in your function to have it throw multiple windows correctly... meaning you can't declare one var for multiple windows. Maybe a class would be better.
Something I thought was odd earlier but forgot to mention before FB posted my response prematurely was that you're adding your href in the rel attribute and specifying the href as a js:void(0) which is also non-standard. The rel attribute is for specifying the relationship between the link and the page... (eg. rel=nofollow). That might also be why it's not firing and misfiring some of the time as well, and the differences between browser response.
I've 3 divs (#Mask #Intro #Container) so if you click on Mask, Intro gets hidden and Container appears.
The problem is that I just want to load this only one time, not every time I refresh the page or anytime I click on the menu or a link, etc.
How can I do this?
This is the script I'm using for now:
$(document).ready(function(){
$("div#mask").click(function() {
$("div#intro").fadeToggle('slow');
$("div#container").fadeToggle('slow');
$("div#mask").css("z-index", "-99");
});
});
Thank you!
You can try using a simple counter.
// count how many times click event is triggered
var eventsFired = 0;
$(document).ready(function(){
$("div#mask").click(function() {
if (eventsFired == 0) {
$("div#intro").fadeToggle('slow');
$("div#container").fadeToggle('slow');
$("div#mask").css("z-index", "-99");
eventsFired++; // <-- now equals 1, won't fire again until reload
}
});
});
To persist this you will need to set a cookie. (e.g. $.cookie() if you use that plugin).
// example using $.cookie plugin
var eventsFired = ($.cookie('eventsFired') != null)
? $.cookie('eventsFired')
: 0;
$(document).ready(function(){
$("div#mask").click(function() {
if (eventsFired == 0) {
$("div#intro").fadeToggle('slow');
$("div#container").fadeToggle('slow');
$("div#mask").css("z-index", "-99");
eventsFired++; // <-- now equals 1, won't fire again until reload
$.cookie('eventsFired', eventsFired);
}
});
});
To delete the cookie later on:
$.cookie('eventsFired', null);
Just point to an empty function once it has been called.
var myFunc = function(){
myFunc = function(){}; // kill it
console.log('Done once!'); // your stuff here
};
Web pages are stateless in that they don't hold states between page refreshes. When you reload the page it has no clue what has happened in the past.
Cookies to the rescue! You can use Javascript (and jQuery has some nice plugins to make it easier) to store variables on the client's browser. Store a cookie when the mask is clicked, so that when the page is next loaded it never shows.
this code with will work perfect for you and it is the standard way provided by jquery to bind events that you want to execute only once
$(document).ready(function(){
$("div#mask").one('click', function() {
$("div#intro").fadeToggle('slow');
$("div#container").fadeToggle('slow');
$("div#mask").css("z-index", "-99");
});
});