javascript div not expanding to match dynamic form fields - javascript

I have two divs that have been coded using javascript so that the "lightpole" div will expand to match the height of the "LayoutColumn2" div. It seems to be working fine everywhere except on the checkout page. This page has some dynamic form elements that expand once one section is completed. The lightpole div does not expand to match the expanded divs that container forms, even though they are within the larger LayoutColumn2 div.
Site: https://store-e262c.mybigcommerce.com/checkout.php?tk=eceb5394b7c03ae4a283b2eabff8f9f6
If that doesnt work add something to the cart>proceed to checkout>Select I'm a new Customer, Continue button. The lightpole break is visible near the footer and very apparent if you continue through the checkout process. I can delete users if someone wanted to create a test user.
<!--make lightPole expand to height of tallest column-->
<script type="text/javascript">
$(window).load(function(){
var ht=($('#LayoutColumn2').height() > $('#LayoutColumn3').height()) ?
$('#LayoutColumn2').height() : $('#LayoutColumn3').height(); $('#lightPole').height(ht); }); </script>
The html is lengthy and changes depending on the stage in the checkout process but I can still post it if someone wants it.
CSS
#lightPole {
background:url(../images/lightPole8aSlice.png);
margin: 0 0 0 19.9px;
padding: 0;
position: absolute;
width: 15px;
z-index: -100;
display: inline-block;
float: left;
}
#LayoutColumn2{
float: left;
height: auto;
margin: 0;
padding: 0;
width: 641px;
}
.Content {
background: url("../images/contentMiddleBackground.png") repeat scroll 0 0 transparent;
float: left;
font-size: 0.95em;
margin: 0;
min-height: 266.5px;
padding: 0 5px 0 28px;
width: 609px;
}
It's nested pretty deeply and there are several other script blocks in there so maybe one of those is causing the problem...?

Your issue is imho to resize the div(#lighPole) when the other div(#LayoutColumn2) changes its height. This can be archived e.g. using the jquery resize plugin.
<script type="text/javascript" src="/content/jquery.ba-resize.min.js"></script>
<script type="text/javascript">
$(function() {
$('#LayoutColumn2').resize(function() {
var ht = Math.max($('#LayoutColumn2').height(), $('#LayoutColumn3').height());
$('#lightPole').height(ht);
}).resize();
});
</script>

Related

Counting li elements --> Then applying CSS = Loading Problem

I am working with a CMS. In order to show some list content I need a count on the list items to spread them evenly over the page. I did this function:
$(document).ready(function() {
$("button").click(function() {
var count = $("#page_menu ul li").length;
var breit = 945 / count;
$("#page_menu li").css("width", breit);
})
})
#page_menu ul {
margin: 0px;
top: 0px;
}
#page_menu li {
border: 1px solid #fff;
margin: 0 -1px 0 0;
display: flex;
justify-content: center;
text-align: center;
align-items: center;
}
#page_menu ul li {
height: 50px;
float: left;
list-style: none;
font-size: 13px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="page_menu">
<ul class="nav menu mod-list">
<li class="item-121"><a href="/index.php/about/querfloete" >Querflöte</li><li class="item-123"><a href="/index.php/about/autor" >Autor</li></ul>
</div>
<button>change</button>
This does exactly what it is supposed to do - TOO LATE!
To be precise: The page loads and builds the list. The javascript afterwards performs its counting function and releases it to the CSS. However, by then the CSS relating to the list doesn't get the information anymore. The button stays blank and without function regardless if it was placed before the javascript section or after. And it stays that way until I go a level down in the submenu with the same menu. Then it works fine.
And the other thing is, that I would like to load it by itself and not via clicking a button. How can I achieve this?
Sorry, I haven't been working this kind of stuff for the past 10 yrs. I am completely somewhat lost.

How to anchor a fixed-height <div> to the bottom right of a <td> without intruding into content above?

1) The Basic Problem.
I know this is a long statement of a problem, but please bear with me. The problem's kind of simple, but it takes me a bit to set it up for you.
I have a 5x7 table representing 5 time slots in the day with 7 classrooms in each slot. The <td>s have a complex inner HTML structure housing the class title, and instructor's name, together with a class desrciption and instructor bio that populate modal dialogs that popup when the title or name are clicked.
I need to add a <div> (a real-time registration counter) anchored to the <td>'s bottom right without it intruding upward into content above it.
2) The Problem Setup.
The HTML for a typical <td> looks like this.
<td id="x0900A"> <!-- 0900 room A -->
<div class="classTitle"></div>
<div class="classDescrip"></div>
<div class="instructor"></div>
<div class="gender"></div>
<div class="instructorBio"></div>
<div class="instructorImg"></div>
<div id="x0900A-roomCount" class="roomCount">
<div class="regis">registered</div>
<div class="cap">capacity</div>
</div>
</td>
The title, instrucrtor name, and room count show in the cell. The other <div>s are display {hidden;}. Their content populates modal dialogs that popup on a click on title or name.
With this CSS, I can lock .roomCount to the bottom right.
td {
position: relative;
}
.roomCount{
position: absolute;
right: 0;
bottom: 0;
tex-align: right;
}
But, in some cells, its text directly abuts the instructor name above it. In others, not. When it does, the name is illegible.
The table data is on an Amazon Web Services server. With JavaScript, on each page load, I dynamically retrieve it and build the table.
You can see it all at work at this pen on CodePen.
3) I Need A Solution That Doesn't Restructure The HTML.
I need to keep .roomCount from abutting the instructor name as it does in some cells.
I wouldn't mind restructuring the HTML but that I stupidly wrote the JavaScript dependent upon the elements' positions in the <td>. (It was my first time. What can I say?) I'd have to rewrite the JS, which I also wouldn't mind doing, but that I haven't time before I have to take the site live.
So, I need a solution without restructuring the HTML elements in the <td>s.
4) Any Help?
Any help?
Thanks ever so much for reading this far. Your help will be greatly appreciated. In fact, if you can solve it, I'll polish your shoes for six months. (I hope you wear sneakers.)
A brutally hacky way is to increase the size of the bottom padding or margin on the instructor's name.
.schedule p {
line-height: 1.2em;
padding: 10px 5px 0px 5px;
margin: 0 0 25px 0;
}
That will put more room under the course title though. If you want it under only the instructor, change the instructor css block to
.schedule p.instructor {
margin: 0 0 25px 0;
padding: 10px 5px 0px 5px;
font-size: .85em;
text-align: right;
color: #00b8b8;
}
The margin and padding properties on your .instructor rule are currently being ignored because .schedule p has higher specificity.
The problem is caused by .classTitle having different height because the length of content is different. Height of all td in a same row are the same. When .classTitle takes up more space, .roomCount is left with less space at the bottom. And with position: absolute, it 'overlaps with .instructor
You can try adding fixed height to .classTitle and .instructor. This way, you can remove the position: absolute from .roomCount.
.classTitle {
padding: 5px;
font-size: 1.05em;
text-align: left;
color: #00b8b8;
height: 4em; /* Added Sample Height */
}
.instructor {
margin: 0 0 10px 0;
padding: 0 3px 0 3px;
font-size: .85em;
text-align: right;
color: #00b8b8;
height: 1.2em; /* Added Sample Height */
}
.roomCount {
/* position: absolute; */
/* bottom: 0; */
/* right: 0; */
text-align: right;
}

How to position two elements centered on top of each other?

The problem:
I have a form with a button underneath it to submit (post) from data with jQuery ajax(). I want for the button to be replaced with a spinner (animated png) for the duration of server ajax call. But such a trivial task is impossible in css to do right.
What i have tried:
I have placed button and image inside a bootstrap row. Ox ajax call I have set button display to none and img display to block. But because this two are not of the same size makes the whole page flicker, breaks the positioning of other elements and so on.
Another idea was to try to place both elements on top of each other with absolute positioning. But, stupid as css is I cannot center it on the middle of the row.
Is there a way to position both elements on top of each other so I can control their visibility?
Please bear in mind that I cannot used absolute position in pixel, because this is a web page and I do not not how wide the browser will be, image can change in the future, text in the button can change in the future, all this things affect absolute size.
If there is another solution to my problem which would prevent the page from jumping up and down it would also be great.
EDIT
Link to one of fiddle experiments:
https://jsfiddle.net/ofb2qdt8/
.button {
position: relative;
margin: auto;
height: 50px;
width: 30px;
background: blue;
z-index: 1;
display: block;
}
.spinner {
position: relative;
margin: auto;
height: 30px;
width: 50px;
background:red;
z-index: 2;
}
This renders second element underneath on screen. Not on different z layer.
Experiment 2:
https://jsfiddle.net/ofb2qdt8/
.button {
position: absolute;
margin: auto;
height: 50px;
width: 30px;
background: blue;
z-index: 1;
display: block;
}
.spinner {
position: absolute;
margin: auto;
height: 30px;
width: 50px;
background:red;
z-index: 2;
}
This does not center both elements, and they are pushed to the top of the containing div. The element with less height should be centered.
Check this working demo: https://jsfiddle.net/ofb2qdt8/3/
Add in a few lines of jquery and update your css.
Position your loading div according to button div's position, width, height using jquery.
*Click the button to see loading div, and try to play the margin of the button to any pixel.
###JQUERY
$(document).ready(function () {
$('.c2').each(function () {
$(this).css({
'width': $(this).siblings('.c1').outerWidth(),
'height': $(this).siblings('.c1').outerHeight(),
'top': $(this).siblings('.c1').offset().top,
'left': $(this).siblings('.c1').offset().left
});
});
$('.c2').on('click', function () {
$(this).hide(0);
});
});
###CSS
.c1 {
margin: 100px auto;
width: 100px;
text-align: center;
padding: 5px 10px;
background: blue;
z-index: 1;
}
.c2 {
position: fixed;
text-align: center;
background: red;
z-index: 2;
cursor: pointer;
}
Rough, ready and untested:
HTML
<div>
<input type='submit' />
<img src="spinneyIMage.gif" />
</div>
CSS
div{ text-align: center; }
div img{ display: none; }
jQuery
$('submit').click(function(e){
e.preventDefault();
$(this).hide().next().show();
});
After the Ajax call completes reverse the above jQuery.
As I haven't been able to find a working solution I have reverted to my first idea which I discarded at first. Albeit with a little twist.
HTML
<div class="row>
<div id="container-button" class="col-xs-12>
<button id="button" onclick="button_OnClick(e)">submit form via ajax</button>
<img src="img/spinner.png" sytle="display: none" />
</div>
</div>
JS
function btnContact_OnClick() {
// show the soinner and hide the button
showSpinner();
$.ajax(
{
type: 'POST',
url: "someurl.com/target",
data: $("#form").serialize(),
dataType: "json",
complete: function() { hideSpinner();},
success: onAjaxSuccess,
error : onAjaxError
});
}
function hideSpinner() {
$("#spinner").hide();
$("#button").show();
// make container height non-fixed and content adjustable again
$("#container-button").height('auto');
}
function showSpinner() {
// THis is the trick !!!
// Make the container fixed height as it was before displaying spinner, so it does not change with content (spinner is not the same height as button
$("#container-button").height($("#container-button").height());
$("#button").hide();
$("#spinner").show();
}
This is not the perfect solution but the best I could make.
Drawbacks:
it is not clean, you have to use javasript to fix what is css layout
problem
it still causes a little flicker
the height of container while displaying spinner is dependant on button, this may cause clipping if spinner is too big

How to make this working Java-script more efficient

I've got a working jQuery script that runs ok meaning it serves its purpose.
The question is: how to make this script more efficient?
Currently the script becomes active the moment a user places the mouse over (hover) a certain HTML5 section-tag with an ID. At this moment the script removes the existing class named 'noDisplay' from a subordinate nav-tag containing a submenu list, hence content becomes visible to the user. This submenu list may be three to four levels deep. The submenus are held in classes (subMenu1, subMenu2, subMenu3, subMenu4, etc.).
The script is written to serve individually each of the given section IDs and its sublevel classes.
Basically the script interacts with the DOM by removing the class 'noDisplay' upon mouse hover and restores the same class upon mouse leave.
(Tried to give a clear explanation. If not please ask.)
Here is a JSfiddle: enter link description here
I hope someone can suggest a way to do this much more efficiently.
Possibly with more sections (#ID's) and subMenu-levels (a class per level).
Using the CSS properties 'display: none;' and 'display:block;' would be the simplest solution but this is not desired because a search-bot my decide to skip content flagged as invisible to the user or a screenreader. The class 'NoDisplay' in use here keeps content invisible to users and keeps its readability to screen readers (and thus to most of the search bots).
So basically the script function remains as is to remove and add the class 'noDisplay' upon hover.
The goal is to obtain a script that is more efficient that could use for instance variables for each section, instead of writing code for each new section and hence extending the current script.
//section1$("#section1 .NavUL1 .subMenu1").hover(function(){
$(".NavUL2").removeClass("noDisplay"); //display
},function(){
$(".NavUL2").addClass("noDisplay"); //no display
});
$("#section1").hover(function(){
$("#section1 .NavUL1").removeClass("noDisplay"); //display
},function(){
$("#section1 .NavUL1").addClass("noDisplay"); //no display
});
$("#section1 .NavUL1 .subMenu1").hover(function(){
$(".NavUL2").removeClass("noDisplay"); //display
},function(){
$(".NavUL2").addClass("noDisplay"); //no display
});
//#section2
$("#section2").hover(function(){
$("#section2 .NavUL1").removeClass("noDisplay"); //display
},function(){
$("#section2 .NavUL1").addClass("noDisplay"); //no display
});
$("#section2 .subMenu1").hover(function(){
$(".subMenu1 .NavUL2").removeClass("noDisplay"); //display
},function(){
$(".subMenu1 .NavUL2").addClass("noDisplay"); //no display
});
$("#section2 .subMenu2").hover(function(){
$(".subMenu2 .NavUL2").removeClass("noDisplay"); //display
},function(){
$(".subMenu2 .NavUL2").addClass("noDisplay"); //no display
});
$("#section2 .subMenu3").hover(function(){
$(".subMenu3 .NavUL2").removeClass("noDisplay"); //display
},function(){
$(".subMenu3 .NavUL2").addClass("noDisplay"); //no display
});
$("#section2 .subMenu4").hover(function(){
$(".subMenu4 .NavUL2").removeClass("noDisplay"); //display
},function(){
$(".subMenu4 .NavUL2").addClass("noDisplay"); //no display
});
My suggestion would be to create a new class, call it whatever but for demonstrative purposes we'll call it hover-class
Then it becomes simple:
$('.hover-class').hover(
function() { $(this).addClass('noDisplay'); },
function() { $(this).removeClass('noDisplay'); }
);
I'd recommend just using CSS, there shouldn't be a need for JS:
nav ul{
position: absolute;
border: 1px solid #444444;
box-shadow: 8px 8px 11px #222222;
background: #888;
padding: 0.5em 0.5em 0.5em 0em;
list-style-type: none;
margin-left: 15%;
display: none;
}
.sectionBox:hover nav > ul, nav li:hover > ul {
display: block;
}
This does away with all the IDs and classes while keeping the same effect. You html looks like this now (just a snippet):
<ul>
<li><h2>various whatever1</h2></li>
<li>link11</li>
<li>link12</li>
<li>link13</li>
<li>link14</li>
<li><h2>sub1</h2>
<ul>
<li>sub1-link11</li>
<li>sub1-link12</li>
<li>sub1-link13</li>
<li>sub1-link14</li>
</ul>
</li>
</ul>
Here it is working: http://jsfiddle.net/VGXNz/1/
Update:
If you want to use your original noDisplay styles then this would be the CSS:
nav ul{
position:absolute;
border: 0;
clip: rect(0 0 0 0);
width: 1px;
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
}
.sectionBox:hover nav > ul, nav li:hover > ul{
height: auto;
width: auto;
margin: 0 0 0 15%;
border:1px solid #444444;
box-shadow:8px 8px 11px #222222;
background:#888;
padding:0.5em 0.5em 0.5em 0em;
list-style-type:none;
clip: auto;
overflow: visible;
}
Here's a fiddle: http://jsfiddle.net/KKmVU/1/
why would you use js in the first place? Css is perfectly capable of handling hover states, and IMO you should always go for the css solution if there is one.
I made some quick (and dirty) changes to your fiddle:http://jsfiddle.net/3epRN/1/
I removed a bunch of classes and id's from the markup, removed all js, and tweaked the css a bit. The relevant css looks like this:
.sectionBox nav {
display: none;
}
.sectionBox:hover nav {
display: block;
position: absolute;
top: 90%;
left: 50px;
background-color:#646464;
z-index: 5;
}
.sectionBox nav ul ul {
display: none;
}
.sectionBox nav ul li {
position: relative;
}
.sectionBox nav ul li:hover ul {
display: block;
position: absolute;
top: 0;
left: 80%;
background-color:#646464;
z-index: 5;
}
Obviously this needs some finetuning, but I'm sure you get the idea...
edit
I must admit I missed the part about the display:none beeing a problem for you. I do have to say I disagree with your arguments as to why (it is used al over the net, and crawlers and screen readers are smart enough nowadays).
That beeing said, nothing prevents you to use the css styling you now use to hide content (by adding the noDisplay class) directly in your css where I used the display:none;, and countering it when you want to display content by adding the following in stead of an ordinary display:block:
height: auto;
width: auto;
clip: auto;
overflow: visible;
The result would be identical to your js solution. I updated my fiddle to demonstrate:
http://jsfiddle.net/3epRN/2/

How to use Javascript to get a visitors monitor resolution?

I'm building a website for Advanced Web Design and I'm stuck on something. I want the content of the page (contained in a <div>) to be centered. Using CSS I tried this:
body {text-align: center; margin-left: auto; margin-right:auto;}
That didn't seem to work. I know you can detect a browsers resolution using Javascript, and I got to thinking. How would I detect the width, and use that to set the left and right margins of the body? It would be ((resolutionWidth - 800) / 2) to determine the margins that I need (the <div> is 800px wide).
margin: 0 auto is one of the easiest ways to center content on a website. Don't use JS to center the content unless you absolutely have to.
Check out this jsFiddle on how to use margin: 0 auto: http://jsfiddle.net/NfRtV/
Set your width in the same element as your auto margins. So something like this:
#page { width: 800px; margin: 0 auto; }
In some versions of IE, this doesn't work, so wrap a div around this element, giving it text-align: center, and reset in a child div.
Example markup:
<body>
<div id="ie-page-center">
<div id="page">
...
</div>
</div>
</body>
Example CSS:
#ie-page-center { text-align: center; }
#page { width: 800px; margin: 0 auto; text-align: left; }
margin: auto only works if the element has a width. Try specifying the width and retesting your code!
http://jsfiddle.net/ZQjVL/2
body {
width: 500px;
margin: auto;
border: 1px solid black;
text-align: center;
}
You can't detect their monitor resolution, but you can detect the screen width and height. Those are accessible via javascript. Although you obviously shouldn't do it that way because there is a CSS method to do so.
viewportwidth = window.innerWidth;
viewportheight = window.innerHeight;
use this code
<script language="javascript"> alert('Width:' + screen.width+ ' & Height: ' +screen.height); </script>

Categories