I'm having the strangest problem with jQuery's hide() and show() functions.
The site I'm working on (development build) is here
On the page, you'll see a product under Featured Products called Hydrate. This product has some flavor options so what I want to do is make it so that when the user clicks the Add to Cart button it shows a layer that is by default hidden. See the two screen shots here:
However, when I click the Add To Cart button, the layer does not appear. The Firebug screenshot below shows what the elements look like after I've clicked the Add To Cart button.
Notice that the element style is "display: block" as per the jQuery norm, which then should override the CSS element style for "display: none". I've done this hundreds of times, if not more and this is the first time it hasn't worked. Now look at the Firebug screenshot below. If I click the red slash-circle next to display:none in the debug console, the layer appears exactly as it should.
Below are the snippets of what I believe are relevant code, but I can't see where the problem is.
CSS Code:
.carouselProduct {float:left; border:2px solid #e9e9e9; width:223px; min-height:242px; margin:18px 2px 0 2px; position:relative; overflow:hidden;}
.productOptions{
position:absolute;
bottom:0px;
left:0px;
width:211px;
background: url('../images/black_background_75.png');
z-index:99999;
padding: 6px;
height:170px;
display:none;
}
JS Code:
$(document).ready(function(){
$.noConflict();
jQuery('.add_to_cart_btn').live('click',function(e){
e.preventDefault();
$(this).getForm().sendRequest( 'shop:on_addToCart', {update: {'mini_cart': 'mini:cart'} });
});
jQuery('.choose_options').live('click',function(e){
e.preventDefault();
jQuery('#options_'+jQuery(this).attr('rel')).show();
});
});
Note: I thought maybe there was some way that something was interfering so I implemented noConflict but it didn't make any difference. Also note that I'm not getting ANY JS errors in Firebug.
HTML Code:
<article class="carouselProduct">
<!--productContent starts here-->
<article class="productContent">
<img class='productImage' src="/uploaded/thumbnails/db_file_img_33_autox126.png" style="margin: 3px;">
<hgroup>
<h4>Hydrate</h4>
<h3>$25.00</h3>
<h3 class="orange">$15.00</h3>
</hgroup>
<strong>Key Benefits:</strong>
<ul>
<li>Proper electrolyte balance</li>
<li>Reduce muscle fatigue & cramping</li>
</ul>
</article>
<!--productContent ends here-->
<!--productOptions layer starts here -->
<div class="productOptions" id="options_1">
<div class='selectbox1'>
<label>Flavor</label>
<select class='my-dropdown' name='product_options[4448804864d703e8b696c3fa7713aa23]'>
<option value='Fruit Punch'>Fruit Punch</option>
<option value='Orange'>Orange</option>
</select>
</div><br>
<article class="product_btn">
<a class="yellow_btn" rel="1" title="Add To Cart" href="#" onclick="return $(this).getForm().sendRequest( 'shop:on_addToCart', {update: {'mini_cart': 'mini:cart'},onSuccess: function(){ close_layer(1) } })">Add To Cart</a>
<a class="gray_btn" title="View More" href="#" onclick="close_layer(1)">Cancel</a>
</article>
</div>
<!--productOptions layer ends here -->
<!--product_btn starts here-->
<article class="product_btn">
<a class="yellow_btn choose_options" title="Add To Cart" href="#" rel="1">Add To Cart</a>
<a class="gray_btn" title="View More" href="/shop/product/intensity-hydrate">View More</a>
</article>
<!--product_btn ends here-->
</article>
Note that there are two Add To Cart buttons. Only the last one in the code here (the one that shows up initially) has the "choose_options" class on it. Also, on the Cancel button inside the overlay, I have call to a function called close_layer that passes the id in and then runs the jQuery hide() function which also doesn't work.
I've tried everything I can think of. I've disabled other JS and CSS and still it doesn't work. I've console logged everything and added alerts. It IS running the function because it adds the element display style to the hidden div but something isn't letting it override the CSS file.
Any help would be greatly appreciated.
On your page, there are more than one divs has the same ID - 'options_1'. So your code only change one of them. If you do want to show all of them, then you can do it as below:
jQuery('div[id=options_'+jQuery(this).attr('rel')+']').show();
The issue i feel is being cause by specificity
element.style has higher specificity compared to .productoptions because the property is part of the style attribute
Even if you apply the class to the element element.style will be given preference. .
The better option for you is to Remove the style attribute from your HTML..
Add the display:block inside a class..
.block
{
display : block;
}
<div id="options_1" style="display:block">
should now look like
<div id="options_1" class="block">
Now use .addClass() and .removeClass() to specify your logic.
It seems your DOM is messed up. Perhaps you have a missing tag somewhere or something?
Anyway I visited your page and when I change:
jQuery('#options_'+jQuery(this).attr('rel')).show();
to
jQuery('#options_'+jQuery(this).attr('rel')).show().appendTo(jQuery(this).parent())
everything is fine.
I had a similar problem and after debugging found that I had forced 'display: inline-block !important' in one of the places which was overriding my hide(). Could you check if the !important is used anywhere in the CSS that can be related?
Related
I am developing a web application using AngularJS.
I have a problem: in an HTML page I needed to show a table that dynamically show the number of rows based on a user's choice. I achieved this effect using a script and bootstrap rules.
I won't go into details, but I just show you the high-level code and a screenshot of the result:
HTML code:
<script type="text/ng-template" id="custom/pager">
<ul class="pager ng-cloak">
<!-- Code of the element drop down menu.....-->
</ul>
</script>
<div>
<ng-form >
<div class="panel panel-default table-panel noborder">
<div class="table-responsive">
<table ng-table-dynamic="$ctrl.tableParams with $ctrl.cols" class="table" template-pagination="custom/pager">
<!-- Code of the table.......-->
</table>
</div>
</div>
</ng-form>
</div>
The result is something like that:
My problem is that no type of CSS code seems to work to move the dropdown menu position to this position:
I tried to use position (relative, absolute, fixed) and also to encapsulate the <script> element inside <div> or <span> and refer it with CSS rules. But nothing seems to work! The dropdown menu always remains at the bottom and center of the page. I guess it's bootstrap's fault. Can you tell me how I can resolve this issue?
The pagination buttons are working. If the css should also work. You can place the below code into the codepen to see the effect.
Codepen
.table{
position:relative;
}
.ng-table-counts{
position:absolute;
top:0;
right:0;
}
I want to hover over the "My Account" button and the click the "Login" button opened popup. I have tried the below code but it did not work. Does anyone know a way to handle this situation?
Cypress.Commands.add('loginol', (email, password) => {
cy.get('#myAccount').click()
cy.get('#myAccount').trigger('mouseover')
cy.wait(3000)
cy.get('#login').click()
cy.get('#email').type(email)
cy.get('#password').type(password)
cy.get('.btn.full.btn-login-submit').click()
})
I have uploaded the pictures in case it helps:
"Giriş Yap (My Account)" Button
After it is hovered below "Giriş Yap (Login)" Button
Website I'm working on: https://www.hepsiburada.com/
//cypress doesn't know how to hover so 'invoke' call JQuery 'show' method which force menu to become visible
cy.get('#myAccount').invoke('show');
that worked for me.
You don't have unique id's, assign unique id's to your elements
From the source code of your website:
So what happens is you are triggering the mouseover on the widget, the first myAccount item, the widget container. On this item you don't have any events bound, they are bound on the second item tagged with id="myAccount"
ID needs to be unique
To resolve make the id of your button something like id="myAccount_button" and target that in your test script.
Below is a snippet that simulates your website. It doesn't show the menu.
$('#myAccount').trigger('onmouseover');
#menu {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="myAccount">
<div id="myAccount" onmouseover="$('#menu').show()" onmouseout="$('#menu').hide()">
my account
</div>
</div>
<div id="menu">
a<BR/>
c<BR/>
d<BR/>
e<BR/>
</div>
This is the snippet with the fix. As you can see, the menu shows here, because the ID is unique and can be targeted.
$('#myAccount_button').trigger('onmouseover');
#menu {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="myAccount_wrap">
<div id="myAccount_button" onmouseover="$('#menu').show()" onmouseout="$('#menu').hide()">
my account
</div>
</div>
<div id="menu">
a<BR/>
c<BR/>
d<BR/>
e<BR/>
</div>
For a workaround and from the official cypress website they're mentioning cypress-real-events plugin which can be helpful for a real events that require event.isTrusted to be true, it provide hover and more real events, so you can use it as a real user and test your elements such as a tool-tip messages, expendable lists,... etc.
Note: for current time it support only chromium's based web browsers
My knowledge of javascript is close to none and I'm trying to have a div be replaced on click by another div.
<div class='replace-on-click'>
<h1>Click to Insert Coin</h1>
<div class='replaced-with'>
<div class='info-text'>
<h1>Title</h1>
<h2>Subtitles</h2>
</div>
<ul class='info-buttons'>
<li><a href='#' class='b1'>Buy Tickets</a></li>
<li><a href='#' class='b2'>Find Hotels</a></li>
</ul>
</div>
</div>
I'd like it so when you click "Click to Insert Coin", that will disappear and make the .replaced-with div take its place, hopefully with some kind of fade transition if possible. How do I go about doing this?
We will make use of jQuery because it helps us to get you desired behavior done in a few statements. So first include jQuery from somewhere in your head part of your HTML document.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
Then somewhere include this Javascript code (e.g. create index.js and include it the way like the library code).
$(document).ready(function() {
$('h1').click(function() {
$(this).fadeOut(function() {
$('.replaced-with').fadeIn();
});
});
});
It does the following: When your document is ready, it adds an event handler on h1 waiting for clicks. On click, it first fades out the h1 and when it's done, it fades the other element in.
In your HTML document, include the hidden attribute to the object that should be hidden initially.
<div class='replaced-with' hidden>
Here you can find it working as well: http://jsbin.com/cuqoquyeli/edit?html,js,console,output
When page loads my code reads LocalStorage and retrieves saved value. Then it appends that value to DIV element within page.
Thus far it works, but clicking on sort-link-css elements won't trigger script. If I remove appended DIV and use original code, then all scripts work perfectly.
HTML in beginning:
<div id="thisclone">
// Lot of code
</div>
Setting variable in LocalStorage:
$('.region-checkboxes').click(function(e) {
var menu = $("#thisclone").html();
localStorage.menu = menu
});
HTML that is saved in LocalStorage:
<div class="row select-row" style="margin-bottom:5px !important;">
<div class="sort-link-css" id="to-hide" style="background: url("/assets/blue-up.png") 93px 11px no-repeat;">
<a class="sort_link desc" data-method="get" data-remote="true" href="http://www..eu/lv?q%5Bs%5D=height+asc">AUGUMS</a>
<span class="num">1</span>
</div>
<div class="sort-link-css" style="background: url("/assets/down.png") 93px 11px no-repeat;">
<a class="sort_link" data-method="get" data-remote="true" href="/lv?q%5Bs%5D=age+desc">VECUMS</a>
<span class="num">0</span>
</div>
<div class="sort-link-css" style="background: url("/assets/down.png") 93px 11px no-repeat;">
<a class="sort_link" data-method="get" data-remote="true" href="/lv?q%5Bs%5D=votes_for.size+desc">PATĪK</a>
<span class="num">0</span>
</div>
</div>
Then at the top of page I am reading localStorage and appending it to DIV:
<script>
var fromstorage = localStorage.getItem('menu');
$(fromstorage).appendTo(".menu-dupl");
</script>
Visually, newly appended div looks exactly like the starting one. But functionally, simple scripts doesn't work anymore.
Script example:
$('.sort-link-css > a').click(function(e) {
alert("Test");
});
This is just one script that doesn't work.But basically, every script associated to newly appended div doesn't work anymore. Script start to working again if I remove newly appended div and use original div.
I tried:
var fromstorage = localStorage.getItem('menu');
$(fromstorage).clone().appendTo( ".menu-dupl" );
But still the same problem.
Thanks in advance for any help.
After briefly reviewing your question, I've noticed the following:
$(fromStorage).appendTo(".menu-dupl");
I'm not overly concerned about this particular line because you stated that the menu renders correctly but I didn't notice this class while inspecting your code snippets
Potential issue with your script
$('.sort-link-css > a').click(function() { alert("Test") })
It is possible that jQuery is not able to find the right elements on the DOM
When you do this $('sort-link-css > a), you're stating that you want to bind this event on <a></a> elements that are direct children of .sort-link-css
Now the potential issue might come into play when you append the menu on to another element. It is possible that this operation is making it difficult for jQuery to correctly identify the correct selectors
Debugging
Could you try to log out the jQuery expression after you append the menu?
In chrome debugger console, enter the following after the page loads: $(".sort-link-css > a")
This should log out all of the matched elements. If it is undefined, try to rework your jQuery selector to correctly identify those elements
So I'm trying to add a print button to an html page. Most of the page is not supposed to appear in print, so I hide everything in print and then reveal only the one div that is supposed to be printed (or this is what I'm trying to do). But when I try the print button out, the resulting page is completely empty. The html structure of the page looks like this:
<body>
<div id="fullpage">
<div class="section">
some stuff that should not be printed
</div>
<div class="section">
even more stuff that should not be printed
</div>
<div class="section" id="results_page">
<img id="result_image" class="archiv" src="./images/heumarkt/APDC0013.JPG">
<div class="content_wrapper" id="result_text">
<h1 id="result_h1">some stuff</h1>
<h2 id="result_h2">more headlines</h2>
<p id="result_p1">some text</p>
<button class="print_trigger" onclick="javascript:print_stadtarchiv(true)">print</button>
<button class="print_trigger" onclick="javascript:print_stadtarchiv(false)">print without picture</button>
</div>
</div>
</div>
</body>
And here is the CSS that is supposed to hide everything except the div with the id "results_page" (of course the buttons in that div are also supposed to be hidden in print).
#media print {
*{
background-color:transparent;
}
div#fullpage .section, .print_trigger, .unprintable{
display:none;
}
div#fullpage #results_page{
display:block;
}
#result_image,
#result_text {
float: none;
margin: 50px;
}
}
The javascript function is pretty simple, depending on what button the user clicks it adds the "unprintable" class to the picture element and then prints the document (I'm not sure if the html, the css or the js are the culprit here, this is why I include all of this in the question):
function print_stadtarchiv(print_picture){
if(!print_picture) $('#result_image').addClass = 'unprintable';
window.print();
}
So, given all of this, what could be causing the empty page my printer spits out?
For anyone who is having this problem(especially if using bootstrap), it may be a CSS issue and NOT a javascript issue.
My dilemma was that we had a print button towards the top of the page that called "window.print()" function. And it resulted in a blank print preview page. The weird part was that is was working completely fine several weeks ago.
So first, like many threads have mentioned, check that this is not a javascript issue indeed. My call to window.print() did truly bring up the print preview window(meaning we weren't accidentally overriding the print function with another variable somewhere.)
The issue was with Bootstrap's container and container-fluids classes not displaying for print modes. Apparently these classes are being told to be not displayable on print styles(presumably from bootstrap style sheet).
All I had to do was add the following CSS print rules:
.container, .container-fluid {
width: auto;
display: block!important;
}
and it displayed again! This is also hinted at through bootstrap documentation here: http://getbootstrap.com/getting-started/#support-printing
So in a nutshell, check if the CSS is the issue, and stop blaming that poor Javascript.
Here you go:
function print_stadtarchiv(print_picture) {
if(!print_picture) $('#result_image').addClass('unprintable');
return window.print();
}
It also looks like you have no DOCTYPE or html tags... This is likely to cause all sorts of rendering/not-rendering based issues.
<!DOCTYPE html>
<html>
<body>
<div id="fullpage">
<div class="section">
some stuff that should not be printed
</div>
<div class="section">
even more stuff that should not be printed
</div>
<div class="section" id="results_page">
<img id="result_image" class="archiv" src="./images/heumarkt/APDC0013.JPG">
<div class="content_wrapper" id="result_text">
<h1 id="result_h1">some stuff</h1>
<h2 id="result_h2">more headlines</h2>
<p id="result_p1">some text</p>
<button class="print_trigger" onclick="javascript:print_stadtarchiv(true)">print</button>
<button class="print_trigger" onclick="javascript:print_stadtarchiv(false)">print without picture</button>
</div>
</div>
</div>
</body>
</html>
To anyone having the same problem: I couldn't figure out what was causing it, but I could get it done using the window.frame approach elaborated in this answer.