How to optimize this javascript duplicates - javascript

I wrote this code, but since I'm just starting to learn JS, can't figure out the best way to optimize this code. So made a duplicates for every if statement.
$(function() {
var lang = $(".lang input[type='checkbox']");
var gender = $(".gender input[type='checkbox']");
if(lang.length == lang.filter(":checked").length){
$('.lang').hide();
$('.lang-all').click(function(){
$('.lang-all').hide();
$('.lang').slideToggle(200);
});
} else {
$('.lang').show();
$('.lang-all').hide();
}
if(gender.length == gender.filter(":checked").length){
$('.gender').hide();
$('.gender-all').click(function(){
$('.gender-all').hide();
$('.gender').slideToggle(200);
});
} else {
$('.gender').show();
$('.gender-all').hide();
}
});
So this is my code, as you can see on line 15 if(gender... I have a duplicate of previous code, just changed variable from "lang" to "gender". Since I have more that two variables, I don't want to make duplicate of code for every each of them, so I hope there is a solution to optimize it.

You can write a function to let your code more abstract, see:
function isChecked(obj, jq1, jq2){
if(obj.length == obj.filter(":checked").length){
jq1.hide();
jq2.click(function(){
jq2.hide();
jq1.slideToggle(200);
});
} else {
jq1.show();
jq2.hide();
}
}
//Your jQuery code, more abstract
$(function() {
var lang = $(".lang input[type='checkbox']");
var gender = $(".gender input[type='checkbox']");
isChecked(lang, $('.lang'), $('.lang-all'));
isChecked(gender, $('.gender'), $('.gender-all'));
});

make a function which had similar functionality, then pass a parameter as a class or id
$(function() {
call('.lang');
call('.gender');
function call(langp){
var lang = $(langp+" input[type='checkbox']");
if(lang.length == lang.filter(":checked").length){
$(langp).hide();
$(langp+'-all').click(function(){
$(langp+'-all').hide();
$(langp).slideToggle(200);
});
} else {
$(langp).show();
$(langp+'-all').hide();
}
}
});

Related

use if statement to check if an element is display: block jquery

I'm trying to check if an element is display block, and if it is then i want to execute some code. Below is my code, its a large function but where I'm trying to check if a div is display block is at the bottom, and if it is display block then i want to execute the blur method.
As you can see near the bottom, I started writing if ($suggestionsWrapper === and my intention was to write if suggestions wrapper is display none, then do this. I just can't figure out how to execute this, what I've written doesn't work. Also I am new to all of this so sorry if this is really messy or doesn't make sense, still very much learning.
//Header Search Handler
function headerSearchHandler(){
var $searchInput = $(".header-search input[type=text]"),
$searchSubmit = $(".header-search input[type=submit]"),
$mobSearchBtn = $(".mobile-search-btn"),
$myAccountText = $(".menu-utility-user .account-text"),
$miniCart = $("#header #mini-cart"),
$searchForm = $(".header-search form"),
$headerPromo = $(".header-promo-area");
$suggestionsWrapper = $('#suggestions-wrapper');
//
$mobSearchBtn.on("click touchend", function(e) {
$(this).hide();
//$myAccountText.hide();
$searchInput.show();
$searchInput.addClass('grey-line');
$searchSubmit.show();
$miniCart.addClass("search-open");
$searchForm.addClass("search-open");
setTimeout(function() {
$searchInput.addClass("active").focus();
}, 100);
e.stopPropogation();
});
$searchInput.on("click touchend", function(e) {
$searchInput.addClass('grey-line');
e.stopPropogation();
}).blur(function(e) {
var $this = $(this);
if($this.hasClass("active")){
$this.removeClass("active");
$searchSubmit.hide();
$mobSearchBtn.show();
$miniCart.removeClass("search-open");
$searchForm.removeClass("search-open");
}
});
$searchInput.focus(function(e){
$(this).css('width', '145px');
})
if ($suggestionsWrapper.css('display') == 'none') {
$searchInput.blur(function(e){
$(this).removeClass('grey-line');
$(this).css('width', '145px');
}
})
}//End Header Search Handler
You can create a helper method to check if display is block or not :
function checkDisplay(element) {
return $(element).css('display') == 'block';
}
Then you can check it like :
if(checkDisplay("#myElement")){
console.log("Display is Block")
}
else {
console.log("Display is NOT Block")
}
here is an example : https://jsfiddle.net/fafgqv7v/
You can do something like this I think:
if ($suggestionsWrapper.css('display') == 'block')
{
// true
} else {
// false
}
Based off of your code I think you have the }) wrong, it should be:
if ($suggestionsWrapper.css('display') == 'none') {
$searchInput.blur(function(e){
$(this).removeClass('grey-line');
$(this).css('width', '145px');
})
}
I hope this helps!

Returning true on Link Click Event isn't working

I am trying to execute some code that has a callback when clicking on specific links. The callback is to click the link again, but on the second pass, the method returns true to follow normal behavior. But for some reason, it's not working? I use clickedLink for proper scope. In the event callback, this was referring to window.
UPDATE
For a little more clarity, I agree normally this wouldn't be an optimal solution, but I am using Google's Tag Manager to monitor eCommerce traffic. I am trying to make sure product clicks get pushed to their dataLayer, and using their event callback to resume normal behavior. More info here: https://developers.google.com/tag-manager/enhanced-ecommerce#product-clicks
This is my updated method based on the answers below, but it still doesn't work.
var shopCartBtnClicked = false;
var clickedLink;
jQuery('#pdp_add_cart, .add_to_cart_button').click(function(e) {
if (shopCartBtnClicked === true) {
shopCartBtnClicked = false; //I make it here just fine
} else {
e.preventDefault();
clickedLink = this;
var pdp = false;
if (mmProduct) {
//On detail page
mmProduct.qty = jQuery('input[name="quantity"]').val();
pdp = true;
} else {
//on a shopping page
mmProduct = findProductClicked(this);
mmProduct.qty = 1;
}
dataLayer.push({
'event': 'addToCart',
'ecommerce': {
'currencyCode': 'USD',
'add': {
'products': [{
'name': mmProduct.name,
'id': mmProduct.id,
'price': mmProduct.price,
'quantity': mmProduct.qty
}]
}
},
'eventCallback': function () {
//Are we on a product detail page with a form, or just a shopping page with a link?
if (pdp) {
jQuery('form.cart').submit(); //This part works just fine
} else {
mmProduct = null;
shopCartBtnClicked = true;
$(clickedLink).trigger('click'); //This doesn't
}
}
});
}
});
Its not very well done, but this should work:
var shopCartBtnClicked = false;
var clickedLink;
jQuery('.add_to_cart_button').click(function(e) {
if (shopCartBtnClicked === true) {
shopCartBtnClicked = false;
// dont return, just let javascript handle this one
} else {
// only execute when you have not set it to true
e.preventDefault();
clickedLink = this;
shopCartBtnClicked = true;
$(clickedLink).trigger('click');
}
});
I do have to wonder why you don't just execute your other logic first and then not prevent default anyway.
Taking #somethinghere's answer, your code can further be simplified to improve readability:
var shopCartBtnClicked = false;
jQuery('.add_to_cart_button').click(function(e) {
if( shopCartBtnClicked ) {
shopCartBtnClicked = false;
// dont return, just let javascript handle this one
} else {
// only execute when you have set it to true
e.preventDefault();
shopCartBtnClicked = true;
this.click();
}
});
Or, as suggested by #Regent:
var shopCartBtnClicked = false;
jQuery('.add_to_cart_button').click(function(e) {
shopCartBtnClicked = !shopCartBtnClicked;
if( shopCartBtnClicked ) {
e.preventDefault();
this.click();
}
});
OK guys, thank you for helping me get there. Normally, all of the other answers would work great, but for this specific tag manager instance, it appears (for some unknown reason), document.location works in the event callback fine here. This works.
It's weird because I used $(this).('form.cart').submit(); in a callback earlier in the code.
'eventCallback': function () {
//Are we on a product detail page with a form, or just a shopping page with a link?
if (pdp) {
jQuery('form.cart').submit();
} else {
mmProduct = null;
document.location = $(clickedLink).attr('href');
//$(clickedLink).trigger('click');
}
}

Using $_GET with Jquery

I currently have the following code on my website:
$(document).ready(function() {
$("#contact").on("click", function(e)
{
e.preventDefault();
$("#contactform").toggle('fast');
});
});
I would like to have an if(isset($_GET['email')); trigger this function as well, so have it open on page load if the $_GET variable is set.
I'm rather new with Jquery and not sure if this is possible, I also have another somewhat related question, I'm not sure if I should make a new question for this as I'm fairly new to stackoverflow as well, but here it is.
Say I have two of these:
$(document).ready(function() {
$("#contact").on("click", function(e)
{
e.preventDefault();
$("#contactform").toggle('fast');
});
});
$(document).ready(function() {
$("#archivestop").on("click", function(e)
{
e.preventDefault();
$("#archives").toggle('fast');
});
});
I want one to close if the other one is opened, how would I go about this?
Thanks!
Here's the Javascript-solution:
function getParam(key) {
var paramsStr = window.location.search.substr(1, window.location.search.length),
paramsArr = paramsStr.split("&"),
items = [];
for (var i = 0; i < paramsArr.length; i++) {
items[paramsArr[i].split("=")[0]] = paramsArr[i].split("=")[1];
}
if (key != "" && key != undefined) {
// return single
if (items[key] != undefined) {
return items[key];
} else {
return null;
}
} else {
// return all (array)
return items;
}
};
if (getParam("email")) {
// ...
}
Regarding your second question you can use the following to determine if an element is visible:
var bool = $('.foo').is(":visible");
So to hide an element if it is visible you would do something like this:
if ($('.foo').is(":visible")) {
$('.foo').hide();
}
I'm silly and have answered my first question. I still have yet to have my coffee.
The following works, just insert it into the div that is to be displayed:
<div id="contactform" style="<?php if(isset($_POST['email'])) echo "display:block;" ?>">
content
</div>

Shaking effect in my javascript code

I was just trying to use a function of jQuery in my JavaScript code for styling. I want that whenever the required text field is empty, the textfield should shake, but I can't do it. Please help me out I just wasted my whole night on it. Finally asking for your help. I hope that you people get my question.
The code is given below
function validate() {
var em = document.getElementById("email_value").value;
var pass = document.getElementById("password_value").value;
if(em == "") {
shakeIt();
}
}
$(document).ready(function() {
function shakeIt() {
$("input").effect("shake", { times:5}, 50);
}
});
function validate()
{
var em = document.getElementById("email_value").value;
var pass = document.getElementById("password_value").value;
if(em == "")
{
shakeIt();
}
}
function shakeIt()
{
$("input").effect("shake",
{
times: 5
}, 50);
}
Don't wrap it in $(document).ready() function, because your shakeIt function is not longer in global scope, if you do so.

Preserve a value of an element after change using jQuery

For internationalization support, I wrote code that changes the URL from #lang-select dropdown .The code is
$(document).ready(function(){
var sel = document.getElementById('lang-select');
sel.onchange = function(){window.location.replace($('#lang-select').val());};
});
the above code works fine and it changes the URL from http://0.0.0.0:3000/fr to http://0.0.0.0:3000/en.
Now I want to preserve the changed value, but without success. I have written the code below. I don't know why it is wrong/not working .
function langSelect(){
var available_languages = {
"en":"English",
"de":"Deutsch",
"ru" :"Россию",
"fr" : "Française"
};
var languageInUrl= document.URL.split("/")[3];
for(var shortLanguage in available_languages){
if(shortLanguage === languageInUrl) {
var langaugeOptionArray = $("#lang-select>option");
for(var i = 0 ; langaugeOptionArray.length > i ; i++){
if(langaugeOptionArray[i].label === available_languages[shortLanguage]){
langaugeOptionArray[i].selected = true;
return;
}
}
}
}
}
Please tell me what's wrong in above code and since what I am doing is not a new thing, please share what is the best practice to overcome this scenario.
Currently, I am using backend to accomplish this.
$(function() {
$('#lang-select').on("change",function(){
window.location.replace($(this).val());
});
});
function langSelect(){
var available_languages = {
"en":"English",
"de":"Deutsch",
"ru" :"Россию",
"fr" : "Française"
};
var languageInUrl= document.URL.split("/")[3];
var lang = available_languages[languageInUrl];
if (lang) {
var langaugeOptionArray = $("#lang-select>option");
langaugeOptionArray.each(function() {
if($(this).text() === lang){
$("#lang-select").val(lang);
return false;
}
});
}
}
I believe we can even do
if (lang) {
var opt = $("#lang-select").find('option[text="'+lang+'"]').val();
if (opt) $("#lang-select").val(opt);
}
Good luck

Categories

Resources