How to have two separate functions not interfere with another? - javascript

I have an alert message that appears on the page for the first time creating a cookie on Dismiss. I created a function on page load to check if the cookie exists, do not display alert and if it does not exist display alert message. I also have another function in place to check if the pageTitle is "Test" display the alert message.
At the moment my alert message is showing even after clicking dismiss and a cookie is generated because of the second function check on pageTitle. If I remove the check on pageTitle I do get the desired result I want but the message appears on all pages when I only want it to appear with the pageTitle = Test
I am attempting to have both checks work properly with one another for example, if cookie exists do not show an alert, if it doesn't exist and the pageTitle = test show alert message
First function
$(window).on("load", function (e) {
$('.preloader').fadeOut('slow');
if (document.cookie.includes("isDismissed=true")) {
document.body.classList.add("alert.container");
} else {
document.body.classList.add("show-alert");
}
});
Second function
if("#pageTitle".indexOf("Test") !== -1) {
document.body.classList.add("show-alert");
}

Put the second code as an else if in the first function.
$(window).on("load", function(e) {
$('.preloader').fadeOut('slow');
if (document.cookie.includes("isDismissed=true")) {
document.body.classList.add("alert.container");
} else if ("#pageTitle".indexOf("Test") !== -1) {
document.body.classList.add("show-alert");
}
});

You have 2 options:
Check if the cookie exists in the second function.
if("#pageTitle".indexOf("Test") !== -1 && !document.cookie.includes("isDismissed=true")) {
document.body.classList.add("show-alert");
}
Check if if the page title includes test on the first function.
$(window).on("load", function (e) {
$('.preloader').fadeOut('slow');
if (document.cookie.includes("isDismissed=true")) {
document.body.classList.add("alert.container");
} else if ("#pageTitle".indexOf("Test") !== -1) {
document.body.classList.add("show-alert");
}
});
If both of these functions are ran on load, this is the only way to do it.

you forgot to remove the class from the class list, it will keep on adding
$(window).on("load", function (e) {
$('.preloader').fadeOut('slow');
if (document.cookie.includes("isDismissed=true")) {
$("body").removeClass("show-alert").addClass("alert.container");
} else {
$("body").removeClass("alert.container").addClass("show-alert");
}
});

Related

Multiple Javascript Event Listener Issues

Background info: I'm using WooCommerce and Gravity Forms, and trying to make it so the Add to Cart button is inactive according to two conditions - either there are no attendees registered, or the date hasn't been selected from the product variation dropdown. The user should only be able to move forward if both sections are completed.
The Gravity Forms component of this has a popup module to sign up those attendees, but the summary is displayed outside the module and on the main product page. The class .gpnf-no-entries lives on the "outside" of the Gravity Forms module, since it's always visible on the page. .gpnf-nested-entries and .gpnf-row-actions are also outside the module, but rely on information from within the module. .tingle-btn is a class used on multiple buttons inside the module - to add an attendee, cancel editing, or delete that attendee (unsure if I need a loop on here - alerts were working without one, and it seems like there's something else causing issues regardless).
Issues: It was working at one point, but only after the second click (anywhere on the page). There's also a second issue - on this form, if you've added an attendee but not added the product to the cart, the page retains any info you've put in. So what happens is, if you refresh the page and have old attendee info already there, the Add to Cart never gets clickable after selecting a date, even though both areas are filled out.
Screenshots:
I'm still somewhat of a beginner here so it's quite possibly something silly.
<script>
var modalButtons = document.querySelectorAll('.tingle-btn');
var noEntries = document.querySelector('.gform_body .gpnf-no-entries');
var entryField = document.querySelectorAll(".gpnf-nested-entries .entry-field[style='display: block;']");
var nestedEntriesDelete = document.querySelector('.gpnf-row-actions .delete');
var addToCart = document.querySelector('.single_add_to_cart_button');
var wcVariation = document.querySelector('.woocommerce-variation-add-to-cart');
var selectCheck = document.querySelector('#select-date-option');
//When date selection dropdown is changed, check value and check for "no entries" message
document.addEventListener('change', function (event) {
if (!event.target.matches('selectCheck')) {
if ((noEntries.style.display !== 'none') || (selectCheck.value === '')) {
addToCart.classList.add('disabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-disabled');
}
else {
addToCart.classList.remove('disabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-disabled');
}
}
}, false);
// When attendee is deleted, check to see if there are any entry fields left
document.addEventListener('click', function (event) {
if (!event.target.matches('nestedEntriesDelete')) {
if (entryField.length <= 3) {
addToCart.classList.add('disabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-disabled');
}
}
}, false);
// Check for "no entries" and no date selection value when buttons to add or remove attendees are clicked
document.addEventListener('click', function (event) {
if (!event.target.matches('modalButtons')) {
if ((noEntries.style.display !== 'none') || (selectCheck.value === '')) {
addToCart.classList.add('disabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-disabled');
}
else {
addToCart.classList.remove('disabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-disabled');
}
}
}, false);
</script>
I ended up doing this a much simpler way by adding classes:
<script>
var noEntries = document.querySelector('.gform_body .gpnf-no-entries');
var entriesContainer = document.querySelector('.gpnf-nested-entries-container');
var addToCart = document.querySelector('.single_add_to_cart_button');
//When page is fully loaded, check for cached entries
window.addEventListener('load', function () {
//if there are entries, show the add to cart button
if (noEntries.style.display === 'none'){
entriesContainer.classList.add('has-entries');
addToCart.classList.add('do-add');
addToCart.classList.remove('dont-add');
}
//if there are no entries, disable the add to cart button
else if (noEntries.style.display === ''){
entriesContainer.classList.remove('has-entries');
addToCart.classList.add('dont-add');
addToCart.classList.remove('do-add');
}
//if the form isn't present, don't do any of this
else if (noEntries = 'null'){
//do nothing
}
});
//When the container with the form and the entries is clicked, check for entries
document.addEventListener('click', function (event) {
if (!event.target.matches('#gform_wrapper_41')) {
setInterval(function() {
//if an entry is added, show the add to cart button
if (noEntries.style.display === 'none'){
entriesContainer.classList.add('has-entries');
addToCart.classList.add('do-add');
addToCart.classList.remove('dont-add');
}
//if all entries are removed, disable the add to cart button
else if (noEntries.style.display === ''){
entriesContainer.classList.remove('has-entries');
addToCart.classList.add('dont-add');
addToCart.classList.remove('do-add');
}
},2000);
}
}, false);
</script>

Show/Hide part of the page based on dropdown choice in MVC 5

I have a dropdown in MVC5 "view" by changing the dropdown part of the page is going to show and hide. I like to call this function in page load but is not working properly it shows all the text boxes when page loads as I don't know how to send "e" to the page load and when I change the drop down it gave me this error:
Microsoft JScript runtime error: 'toggleDIvDisplay' is undefined
This is my code:
#Scripts.Render("~/bundles/jquery")
<script type="text/javascript">
$(document).ready(
function toggleDIvDisplay(e) {
if (e == 1) {
$('#divAppName').hide();
$('#divSSN').hide();
$('#divRemref').hide();
}
if (e == 2) {
$('#divAppName').show();
$('#divSSN').hide();
$('#divRemref').hide();
}
if (e == 3) {
$('#divSSN').show();
$('#divAppName').hide();
$('#divRemref').hide();
}
if (e == 4) {
$('#divRemref').show();
$('#divSSN').hide();
$('#divAppName').hide();
}
and this is dropdown:
Search By: #Html.DropDownList("ddl", (SelectList)ViewBag.DropDownValues, new { #onchange = "toggleDIvDisplay(this.value)" })
thanks everyone for the answer.
Solution is to add this lines:
$(document).ready(function () {
toggleDIvDisplay(1);
});
First I dont think you should create the function in document.ready,
From this link
defining it outside the document.ready will make it accessible to your jS after your page has loaded.
Right after you define the function in $(document).ready(), just call it:
toggleDIvDisplay(1);
The above assumes you want your page-load behavior to be when e is set to 1.
$(document).ready(
function toggleDIvDisplay(e) {
// ... your implementation, removed for brevity
}
toggleDIvDisplay(1);
);
You could write your function in a way that it gets the value of the dropdown inside the function itself:
function setDivVisibility() {
var e = $('#ddl').val();
if (e == 1) {
// Show/Hide elements
} else if (e == 2) {
// Show/Hide elements
}
// and so on...
}
Then call the function for the first time on document ready:
$(document).ready(function() {
setModeVisibility();
});
Bonus: For unobtrusive JavaScript, put this in the document ready as well so you don't need to the onchange behavior mixed in with the html.
$('#ddl').change(function () {
setModeVisibility();
});
assuming ddl is the id of your dropdown, you can try this.
EDIT: simplified your conditions.
$(function() {
$('#ddl').on('change', function() {
var value = $(this).val();
$('#divAppName, #divSSN, #divRemref').hide();
if (value == 2) {
$('#divAppName').show();
}
else if (value == 3) {
$('#divSSN').show();
}
else if (value == 4) {
$('#divRemref').show();
}
});
});

call different events based on user input style javascript

I have a div which contains an input element to enter some values. These values are added just above the div as a list element upon pressing enter or onFocusOut event. To this point it is fine. But if user types some value and does not press enter and directly clicks on save button, the onFocusOut function for that div should not be called. Instead it should take that typed value and call some save function. Do you have any suggestion on how to detect it?
My code snippet is here
JS:
divInput.onkeypress = function (event){
return someTestFunc();
}
divInput.tabIndex="-1";
$(divInput).focusout(function (e) {
if ($(this).find(e.relatedTarget).length == 0) {
addToList();
}
});
It is not a very delicate solution, but you could use a setTimeout before adding the item to the list and clear the setTimeout on save.button click.
Try this:
var $saveButton = $('#exampleButton')[0],
$divInput = $('#exampleInput')[0],
timedEvent = -1;
$($saveButton).on('click', function(event){
if(timedEvent) {
clearTimeout(timedEvent)
}
alert('not add to list & save');
})
$divInput.tabIndex="-1";
$($divInput).on('focusout', function(e) {
timedEvent = window.setTimeout(function() {
if ($(this).find(e.relatedTarget).length == 0) {
alert('add to list');
}
}, 200);
});
Check this working fiddle

Why is my .blur() code only working on second blur?

I have an input, when the user enters something, my script sends the info over to a php script, which returns whether or not the entered text can be used.
If the text can not be used, it disables the submit button and adds a class to the reult text.
The problem have is strange, the ajax works, the result is returned, but the button disabling and adding of the class doesn't happen unless you focus and blur the input a second time.
Here is my code:
$('#alias').blur(function() {
if ($('#alias').val()) {
var aliascheck = $('#alias').val();
$(".aliascheck").load('checkalias.php?alias='+aliascheck);
var result = $('.aliascheck').text();
if (result.indexOf("Taken") != -1) {
$('#shorten').attr("disabled","disabled");
$('.aliascheck').addClass('error');
} else {
$('#shorten').removeAttr("disabled");
$('.aliascheck').removeClass('error');
}
}
});
The code is live here: http://markhenderson.ws/dev/tmtmu/
To replicate the "taken" event, enter "taken" as the alias. Any thing else will return available.
Does anyone know why this is happening?
Thanks
You need to put the code after the .load call into a callback function of the async call.
Something like:
$('#alias').blur(function() {
if ($('#alias').val()) {
var aliascheck = $('#alias').val();
$(".aliascheck").load('checkalias.php?alias='+aliascheck, function() {
var result = $('.aliascheck').text();
if (result.indexOf("Taken") != -1) {
$('#shorten').attr("disabled","disabled");
$('.aliascheck').addClass('error');
} else {
$('#shorten').removeAttr("disabled");
$('.aliascheck').removeClass('error');
}
});
}
});

Problem with event.target in IE

I'm writing js for a status update system to be used on various pages throughout a app that I'm working. I am really just starting to get more comfortable with javascript so it has been somewhat of a challenge to get to the point where I have everything now.
The status system is basically a facebook clone. For the most part everything is supposed to function the way that facebook's status updates and status comments do. The intended behavior is that when the user clicks in the status textarea, the div under the status textarea slides out revealing the submit button as well as some other checkboxes.
If the user clicks anywhere else on the page except a link or any element that has the class prevent_slideup the div slides up hiding the submit button and any checkboxes.
I'm using a document.body click function to determine what the user clicked on so I know which form elements to hide if I should even hide them. I do not want this slideup to take place on a textarea if that textarea has focus or the user is selecting a checkbox that goes with that form. Hence the prevent_slideup class. I also do not want to bother running the slideup logic if the user has clicked on a link. I'd prefer they just leave the page without having to wait for the animation.
The code that I was using to accomplish this task can be found in the $(document.body).click(function (e) section below where I'm doing a .is('a') check on the event target.
This code works as expected in chrome and firefox, however in ie when a link is clicked for the first time it seems that the element stored in var target is actually a div instead of an anchor. What ends up happening is that the submit div slides up and the user is not taken to the link that they just clicked on. If a link is clicked a second time the user is taken to the page as you would expect.
It seems to me that there's some kind of a lag in ie as to what the current event being fired is.
The entire status module is working other than this one strange ie bug regarding the users click on the link not being carried out the first time that they click a link after opening the status textarea. Does anything jump out in this script that would explain this behavior or does anyone have any other advice?
Thanks in advance for your help.
$(document).ready(function(){
$("textarea.autoresize").autoResize();
});
$(document.body).click(function (e){
var target = e.target || e.srcElement;
console.log(target);
console.log($(target).is('a'));
if($(target).hasClass('prevent_slideup') || $(target).is('a'))
{
return true;
}
else
{
var active_element = document.activeElement;
var active_status_id = $(active_element).attr('data-status_id');
var active_has_data_status_id = (typeof active_status_id !== 'undefined' && active_status_id !== false) ? true : false;
$('textarea').each(function(){
if($(this).hasClass('status_comment_textarea'))
{
var status_id = $(this).attr('data-status_id');
if($('#comment_textarea_'+status_id).val() === '' && (!active_has_data_status_id || active_status_id !== status_id))
{
hide_status_comment_submit(status_id);
}
}
else if($(this).attr('id') === 'status_textarea')
{
if($('#status_textarea').val() === '' && $(active_element).attr('id') !== 'status_textarea')
{
$('#status_textarea').html($("#status_textarea").attr('placeholder'));
hide_status_submit();
}
}
});
return true;
}
});
$("#status_textarea").live('click', function(){
if($('#status_textarea').val() === $("#status_textarea").attr('placeholder'))
{
$('#status_textarea').html('');
}
show_status_submit();
return false;
});
$(".comment_toggle").live('click', function(){
var status_id = $(this).attr('data-status_id');
show_status_comment_submit(status_id);
return false;
});
$(".status_comment_submit").live('click', function(){
var status_id = $(this).attr('data-status_id');
$('#status_comment_submit_wrapper_'+status_id).addClass('status_comment_submit_successful');
return false;
});
$(".show_hidden_comments").live('click', function(){
var status_id = $(this).attr('data-status_id');
$('#status_hidden_comments_'+status_id).show();
$(this).hide();
return false;
});
function hide_status_submit()
{
$("#status_textarea").removeAttr('style');
$("#status_textarea").blur();
$("#status_block").removeClass('padding_b10');
$("#status_submit_wrapper").slideUp("fast");
return false;
}
function show_status_submit()
{
if ($("#status_submit_wrapper").is(":hidden"))
{
$("#status_block").addClass('padding_b10');
$("#status_submit_wrapper").slideDown('fast');
}
return false;
}
function hide_status_comment_submit(status_id)
{
if(!$('#status_comment_submit_wrapper_'+status_id).is(":hidden"))
{
$('#status_comment_submit_wrapper_'+status_id).hide();
$('#fake_comment_input_'+status_id).show();
$('#comment_textarea_'+status_id).removeAttr('style');
}
return false;
}
function show_status_comment_submit(status_id)
{
if($('#status_comment_submit_wrapper_'+status_id).is(":hidden"))
{
$('#fake_comment_input_'+status_id).hide();
$('#status_comment_submit_wrapper_'+status_id).show();
$('#comment_textarea_'+status_id).focus();
}
return false;
}
function status_comment_submit_successful()
{
hide_status_comment_submit($('.status_comment_submit_successful').attr('data-status_id'));
$('.status_comment_submit_successful').removeClass('status_comment_submit_successful');
return false;
}
I figured out that there were two main issues with my script...
1.) The document.body function and the #status_textarea live click funtioins were conflicting with each other.
2.) After adding the logic for the #status_textarea function into the document.body function I noticed that the script still didn't quite work as expected in internet explorer unless I had an alert in the function. The problem at this point was that the autoresize plugin that I'm using on the textarea was also conflicting with the document.body function.
I was able to rectify the situation by adding a dummy text input and hiding the status textarea. On click of the dummy text input the status textarea is shown and the the dummy text input is hidden. I have no idea why this worked, but it seems to have solved my problems.

Categories