Can not get <div> to open page using javascript - javascript

I am trying to find out why my button will not load the page correctly using the javascript. I can't figure out if its CSS or a Javascript error and I've been staring at it to long for my mind to get round it. Any help would be very much appreciated.
Below is the Javascript code:-
<script language="JavaScript" type="text/javascript">
function show_details(thisId) {
var deets = (thisId.id);
el = document.getElementById("overlay");
el.style.display = (el.style.display == "block") ? "none" : "block";
el = document.getElementById("events");
el.style.display = (el.style.display == "block") ? "none" : "block";
var hr = new XMLHttpRequest();
var url "Scripts/bookings.php";
var vars = "deets="+deets;
hr.open("POST", url, true);
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
hr.onreadystatechange = function() {
if(hr.readyState == 4 && hr.status == 200) {
var return_data = hr.responseText;
document.getElementById("events").innerHTML = return_data;
}
}
hr.send(vars)
document.getElementById("events").innerHTML = "processing...";
}
</script>
The CSS Sets:
body
{
height:100%;
margin:0;
padding:0;
}
#overlay
{
display:none;
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height:100%;
z-index:2000;
background: #000;
opacity: .9;
}
#events
{
display: none;
width:500px;
border:4px solid #9C9;
padding: 15 px;
z-index:3000;
margin-top: 100px;
margin-right: auto;
margin-left:auto;
background-color: #FFF;
height:400px;
overflow:scroll;
}
#eventControl
{
display: block;
width: 100%;
height: 30px;
z-index: 3000;
}
#eventBody
{
display: block;
width: 100%;
z-index:3000;
}
The Call to Action Button:
<input name='$date' type='submit' value='Details' id='$date' onClick='javascript:show_details(this);'>
$date variable is set from the users choice selection. I can post more code but I think the fault lies in the code provided. Please do ask if you think otherwise.

Change
var url "Scripts/bookings.php";
to
var url = "Scripts/bookings.php";
Also, your el variable is defined as a property of the function, i'd recommend using var el. Also use separate variables for your document.getElementById. Just to keep the next developer sane.
And you're calling document.getElementById("events"); twice, just use the same variable the second time (in the callback function)

Related

Replacing HTML contents with AJAX

I'm relatively new to Javascript, so I've pieced together the code I have by looking through the forums on here. However, I cannot get this to work, and I am needing help.
The desired end result I am trying to achieve is that whenever a user calls the moreInfo(ID) function, a modal pops up on the screen with the contents of the modal being populated from an external file that is built using PHP.
Right now, whenever I call the function, the modal pops up but does not display the external file. Instead, the modal displays the current page (??). A live version can be found here: http://classcolonies.com/app/test.php/
What am I doing wrong? How do I need to go about doing this instead? An explanation along with a solution would be ideal so I can learn and grow in my journey to understand javascript.
Launch Page (used to launch the modal)
<h1>Test Screen</h1><button onclick='moreInfo("12");'>Test</button>
<div id="infoModal" class="modal">
<div class="modal-window">
<span id="moreInfo"></span>
</div>
</div>
<script> /* AJAX name selector */
var infoModal = document.getElementById("infoModal");
function moreInfo(str){
if (window.XMLHttpRequest) {xmlhttp=new XMLHttpRequest();}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
document.getElementById("moreInfo").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","moreinfo.tem.php?assID=" + str, true);
xmlhttp.send();
infoModal.style.display = "block"; /* After fetching request, make modal appear */
}
window.onclick = function(event) { /* Make modal disappear when you click "X" */
if (event.target == infoModal) {infoModal.style.display = "none";}
}
</script>
<style>
.modal {
display: none;
position: fixed;
z-index: 20;
right: 0; top: 0;
width: 100%; height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.4);
-webkit-animation-name: fadeIn;
-webkit-animation-duration: 0.4s;
animation-name: fadeIn;
animation-duration: 0.4s}
/* Customized part listed below */
.modal-window{
display: grid;
position: fixed;
padding: 10px;
width: 600px; height: 350px;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
transition: height 0.5s;
grid-template-rows: 90px 1fr 60px;
grid-template-areas:
"top"
"content"
"controls";}
/* --------[TOP] -------- */
.modal-top {
display: grid;
grid-area: top;
border-bottom: 2px solid #5B7042;
grid-template-columns: 100px 1fr 80px;}
.pic{
display: inline-block;
width: 65px;
clip-path: circle();
margin-left: 10px;}
.modal-top .title {
display: flex;
align-items: center;
font-weight: 800;
font-size: 26px}
.due {
display: flex;
align-items: center;
font-size: 18px;
color: gray;}
/* --------[CONTENT] -------- */
.modal-content {
display: block;
grid-area: content;
overflow-y: scroll;
padding: 12px;}
.directions {
font-size: 18px;
line-height: 1.7}
textarea {
display: none;
width: 100%; height: 100px;
box-sizing: border-box;
font-size: 18px !important;
margin-top: 20px;}
/* --------[CONTROLS] -------- */
.modal-controls {
display: flex;
align-items: center;
grid-area: controls}
#askforhelp {margin-right: 10px;}
#sendmsg {display: none; margin-right: 10px}
#cancelmsg {display: none}
</style>
External file, used to replace the <span id="moreInfo"> with actual content
<div class='modal-top'>
<img class='pic' src='../resources/pics/1.png'>
<span class='title'> Reading Homework </span>
<span class='due'> Due 3d </span>
</div>
<div class="modal-content">
<div class='directions'>
<b>Directions:</b> You must complete the assignment to continue to the next section. Please type complete sentences and capitalization. Let me know if you need help.
</div>
<textarea placeholder='Type Question..'></textarea>
</div>
<div class="modal-controls">
<button id='askforhelp' class='button green-btn' onclick='askHelp("showform")'>Ask for Help</button>
<button id='markdone' class='button green-btn'>Mark as Done</button>
<button id='sendmsg' class='button green-btn'>Send Message</button>
<button id='cancelmsg' class='button grey-btn' onclick='askHelp("hideform")'>Cancel Message</button>
</div>
<script>
function askHelp(arg) {
var window = document.getElementsByClassName('modal-window')[0];
var textbox = document.getElementsByTagName("textarea")[0];
var helpBtn = document.getElementById('askforhelp');
var doneBtn = document.getElementById('markdone');
var sendBtn = document.getElementById('sendmsg');
var cancelBtn = document.getElementById('cancelmsg');
if (arg == "showform") {
window.style.height = '400px';
textbox.style.display = 'block';
helpBtn.style.display = 'none';
doneBtn.style.display = 'none';
sendBtn.style.display = 'block';
cancelBtn.style.display = 'block';
}
if (arg == "hideform") {
window.style.height = '350px';
textbox.style.display = 'none';
helpBtn.style.display = 'block';
doneBtn.style.display = 'block';
sendBtn.style.display = 'none';
cancelBtn.style.display = 'none';
}
}
</script>
Based on the answer by #Gil, Update your moreInfo function as below:
function moreInfo(str){
fetch("moreinfo.tem.php?assID=" + str).then((res) => res.text()).then(response=>{
document.getElementById("moreInfo").innerHTML=response;
infoModal.style.display = "block";
});
}
fetch returns a promise. From that promise, return the evaluated text from the response. This yields another promise which would contain the html or whatever.
It would be worth mentioning that the script in the returned html won't execute, so your askHelp function won't be defined. You can parse the html response and inject any script contents into the page as follow:
function moreInfo(str){
infoModal.style.display = "block";
fetch("moreinfo.tem.php?assID=" + str).then((response) =>response.text()).then((text) => {
var parser = new DOMParser();
var doc = parser.parseFromString(text, "text/html");
var ele = doc.documentElement;
var scripts = ele.getElementsByTagName('script');
for(var script of scripts){
var head = document.getElementsByTagName('head')[0];
var scriptElement = document.createElement('script');
scriptElement.setAttribute('type', 'text/javascript');
scriptElement.innerText = script.innerText;
head.appendChild(scriptElement);
head.removeChild(scriptElement);
}
document.getElementById("moreInfo").innerHTML=text;
});
}
fetch('xxx/com/api')
.then(responese=>responese.json())
.then(data=>{ do something..}
remember to add json() within first .then
Try using fetch instead.
Something like:
function moreInfo(str){
fetch("moreinfo.tem.php?assID=" + str).then((response) => {
response.text().then((text) => {
document.getElementById("moreInfo").innerHTML=text;
infoModal.style.display = "block";
});
})
}
Some explanation about the syntax here:
fetch makes an HTTP request to the URL provided (default is GET request, unless specified otherwise)
.then means, do something after the request is done.
(response) => {} is an arrow notation in JavaScript.
it's the same as writing function(response) {...}

Javascript overlay function [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to do the overlay function.
function toggleOverlay(){
var overlay = document.getElementById('overlay');
var specialBox = document.getElementById('specialBox');
overlay.style.opacity = .8;
if(overlay.style.display == "block"){
overlay.style.display = "none";
specialBox.style.display = "none";
} else {
overlay.style.display = "block";
specialBox.style.display = "block";
}
}
div#overlay {
display: none;
z-index: 2;
background: #000;
position: fixed;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
text-align: center;
}
div#specialBox {
display: none;
position: relative;
z-index: 3;
margin: 150px auto 0px auto;
width: 500px;
height: 300px;
background: #FFF;
color: #000;
}
div#wrapper {
position:absolute;
top: 0px;
left: 0px;
padding-left:24px;
}
<div id="overlay"></div>
<div id="specialBox">
<p>Special box content ...</p>
<button onmousedown="toggleOverlay()">Close Overlay</button>
</div>
<div id="wrapper">
<button onmousedown="toggleOverlay()">Apply Overlay</button>
</div>
In the current function, when i click the Apply overlay button the pop up is coming. But as per my requirement the pop up has to come when i execute the script i.e. without invoking the apply overlay button.
Please suggest me on this.
Thanks in advance.
Add this to your javascript AFTER the function
window.onload = function(){
toggleOverlay()
}
This invokes the functions when the page is loaded
Alternate option can be use self-invokling function
var publicObj = {};
(
publicObj.toggle = function togglefunction() {
var overlay = document.getElementById('overlay');
var specialBox = document.getElementById('specialBox');
overlay.style.opacity = .8;
if (overlay.style.display == "block") {
overlay.style.display = "none";
specialBox.style.display = "none";
} else {
overlay.style.display = "block";
specialBox.style.display = "block";
}
})(publicObj);
function toggleOverlay(){
publicObj.toggle();
}
Fiddle

Server request for audio file times out before returning any data

When running the code to retrieve an audio file I recieve this error:
Failed to load resource: net::ERR_CONNECTION_TIMED_OUT
I am pretty sure this means that it took to long to load the resource that it timed out. But I am not sure why that would happen. I checked to make sure that it was loading the right file, and it was.
Here is the html code
<html>
<head>
<style>
.titletext {
color: white;
display: block;
position: absolute;
font-size: 50px;
width: 1000px;
margin-left: 150px;
margin-right: 200px;
}
.nametext {
color: white;
display: block;
position: absolute;
font-size: 30px;
width: 600px;
margin-left: 500px;
margin-right: 200px;
margin-top: 600px;
}
.earthphoto {
display: block;
position: absolute;
margin-left: 400px;
margin-top: 150px;
}
</style>
</head>
<body onresize="changeWidth()" onload="changeWidth()">
<script type="text/javascript">
document.body.style.background = "black";
var changeWidth = function() {
screenwidth = window.innerWidth;
screenheight = window.innerHeight;
};
var changescene = function() {
var allvariables = Object.keys(window);
if (page === 1) {
allvariables.splice(9, 4);
}
page++;
};
var page = 1;
document.body.addEventListener("click", function() {
changescene()
});
var update = function() {
if (page === 1) {
document.body.innerHTML = "";
var text = document.createElement("p");
var textclass = document.createAttribute("class");
textclass.value = "titletext";
text.setAttributeNode(textclass);
text.appendChild(document.createTextNode("Welcome to Mikey's Google Earth Presentation!"));
document.body.appendChild(text);
var text2 = document.createElement("p");
text2class = document.createAttribute("class");
text2class.value = "nametext";
text2.setAttributeNode(text2class);
text2.appendChild(document.createTextNode("By Mikey Richards"));
document.body.appendChild(text2);
googleearthimage = document.createElement("img");
googleearthimage.setAttribute("src", "EARTH.png");
googleearthimage.setAttribute("class", "earthphoto");
document.body.appendChild(googleearthimage);
var music = document.createElement("audio");
var musiclink = document.createElement("source");
musiclink.src = "Test.mp3";
music.appendChild(musiclink);
document.body.appendChild(music);
} else if (page === 2) {
document.body.innerHTML = "";
}
}
setInterval(function() {
update();
}, 1000);
</script>
</body>
</html>
The website for this code can be found here.
OK. I figured out that he problem was that I was not calling the play function on the audio. Thanks for putting up with my bad programming skills.

Caption text over an image: not working anymore

This question is related to a previous post where the problem was temporarily solved: Caption text over an image.
I had to move my website to a new server where the script doesn't work anymore. The purpose is to load a random image from a folder on my website and to display over the image a related paired text (image1.jpg & text1.txt).
After the migration of the site, nor the images or the text would display. I could get the image displayed again by changing this line of code:
xmlhttp.open("GET", caption, false);
->
xmlhttp.open("GET", caption, true);
This has fixed the problem of the images but the attached text is still not displayed.
The updated JSfiddle is there: http://jsfiddle.net/Totoleheros/ES22a/7/.
html:
<img class="fullSize" onload="fixImage(this)" />
<div class="HOLDER">
<div class="theCaption"></div>
<img id="showImage" alt="random image" />
</div>
javascript:
function fixImage( image )
{
// change calculations to match your needs
var show = document.getElementById("showImage");
if ( image.height > image.width )
{
show.style.height = "331px";
show.style.width = Math.round( (image.width / image.height) * 331 ) + "px";
} else {
show.style.width = "200px";
show.style.height = Math.round( (image.height / image.width) * 200 ) + "px";
}
show.src = image.src;
show.style.visibility = "visible";
}
var MAXPICTURENUMBER = 166; // or whatever you choose
var rn = 1 + Math.floor( MAXPICTURENUMBER * Math.random() );
var url ="http://www.lvts.fr/Images/RandomPictures/" + rn + ".jpg";
var caption ="http://www.lvts.fr/Images/RandomPictures/" + rn + ".txt";
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET", caption, true);
xmlhttp.send();
window.onload = function() { jq('.theCaption').html(xmlhttp.responseText); jq('.fullSize').prop('src',url); };
$mirage(document).ready(function(){
$mirage('body').unbind('mouseenter');
var mirageMenuConfig = { sensitivity: 3, interval: 30, over: revealMainMenuChildren, timeout: 500, out: hideMainMenuChildren };
function revealMainMenuChildren(){ $mirage(this).children("ul").css('opacity','1').slideDown(300); }
function hideMainMenuChildren(){ $mirage(this).children("ul").fadeTo(300, 0).slideUp(300); }
$mirage("#nav ul ul").parent().addClass("ddarrow");
$mirage("#nav ul ul").parent().append("<span></span>");
$mirage("#nav ul ul").css({ display: "none" });
$mirage("#nav ul li").hoverIntent(mirageMenuConfig);
});
CSS:
#showImage {
display: block;
height: 331px; width: 200px;
visibility: hidden;
z-index: 1;
}
.HOLDER {
position: relative;
width:200px;
margin:0 auto;
}
.theCaption {
position: absolute;
width: 196px; height: 40px;
background-color: #eeeeee; color: #000000;
overflow: hidden;
font-family: arial; font-weight: normal;
filter:alpha(opacity=80);
-moz-opacity:0.8;
-khtml-opacity: 0.8;
opacity: 0.8;
z-index: 2;
font-size: 10px;
line-height: 0.9em;
padding-top: 2px;
padding-right: 2px;
padding-bottom: 1px;
padding-left: 2px;
display: none;
}
.HOLDER:hover .theCaption {display:block;}
.fullSize {
position: absolute;
top: 0px; left: 0px;
visibility: hidden;
}
I don't understand why moving the website has generated this issue. Any help would be very much appreciated...
That's because the speed of the connection to the server changed - it got slower.
AJAX request are asynchronous. What happens is that you send the request, read the result and then the response from the server comes in. Use this code instead:
var caption ="http://www.lvts.fr/Images/RandomPictures/" + rn + ".txt";
$( document ).ready(function() {
$.ajax(caption, {
dataType: 'html',
success: function(data, textStatus, jqXHR) {
console.log('data', data);
$('.theCaption').html(data);
}
});
$('.fullSize').prop('src',url);
});
jQuery will prepare everything to call the success callback when the server response comes in. See http://learn.jquery.com/ajax/
And you should use $( document ).ready(); instead of window.onload
Note: For this to work, the document must be served from www.lvts.fr as well or you'll get this error:
XMLHttpRequest cannot load http://www.lvts.fr/Images/RandomPictures/79.txt. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://fiddle.jshell.net' is therefore not allowed access.

vertical jquery accordion that will fill empty percentage when siblings collapse

Trying to get a jQuery vertical accordion working with 3 separate panels, A, B and C, each currently 33.3% wide. What I am trying to accomplish is when you collapse A, B & C will fill up the other 33% of that new available space from A being collapsed. If you close A & B then C would fill up 100% of the empty space. Any help is much appreciated as I am sure I may be approaching this the complete wrong way?
http://jsfiddle.net/Mvr3P/
HTML
<div id="toggle"><div id="toggle-button"></div></div>
<div id="toggle2"><div id="toggle-button2"></div></div>
<div id="toggle3"><div id="toggle-button3"></div></div>
CSS
#toggle {
float: left;
height: 200px;
width:33.3%;
background:red;
}
#toggle2 {
float: left;
height: 200px;
width:33.3%;
background:blue;
}
#toggle3 {
float: left;
height: 200px;
width:33.3%;
background:green;
}
#toggle-button {
height: 20px;
width: 100%;
background:blue;
}
#toggle-button2 {
height:20px;
width: 100%;
background: purple;
}
#toggle-button3 {
height:20px;
width: 100%;
background:orange;
}
JQUERY
$(document).ready( function(){
$('#toggle-button').click( function() {
var toggleWidth = $("#toggle").width();
if (toggleWidth = "33.3%") {
toggleWidth ="100%";
}
else if (toggleWidth = "100%") {
toggleWidth = "10px";
}
else {
toggleWidth = "33.3%"
}
$('#toggle').animate({ width: toggleWidth });
});
$('#toggle-button2').click( function() {
var toggleWidth = $("#toggle2").width();
if (toggleWidth = "33.3%") {
toggleWidth ="100%";
}
else if (toggleWidth = "100%") {
toggleWidth = "10px";
}
else {
toggleWidth = "33.3%"
}
$('#toggle2').animate({ width: toggleWidth });
});
$('#toggle-button3').click( function() {
var toggleWidth = $("#toggle3").width();
if (toggleWidth = "33.3%") {
toggleWidth ="100%";
}
else if (toggleWidth = "100%") {
toggleWidth = "10px";
}
else {
toggleWidth = "33.3%"
}
$('#toggle3').animate({ width: toggleWidth });
});
});
So there's a few tricky things going on here - the biggest challenge being how to animate more than one thing at a time.
JSFiddle of the solution here: http://jsfiddle.net/vYzpB/1/
Firstly, using classes to generically label your elements will allow you to write less code. This is a hugely important thing especially when you're applying the same behavior to more than one element. As you seem to know, you should only have one ID, but you can have many elements with the same class name.
<div class="accordion">
<div id="toggle" class="toggle-item"><div id="toggle-button" class="toggle-button"></div></div>
<div id="toggle2" class="toggle-item"><div id="toggle-button2" class="toggle-button"></div></div>
<div id="toggle3" class="toggle-item expanded"><div id="toggle-button3" class="toggle-button"></div></div>
</div>
Additionally, wrap all of the elements in a parent div (which I called accordion). I'll explain why shortly.
With that change, we can apply a click event to the .toggle-button class that handles the event for each of the accordion items:
$(document).ready( function(){
$('.toggle-button').click( function() {
// capture the parent div with the class of 'toggle-item'
var $parentToggle = $(this).parent('.toggle-item');
// run this within setTimeout so that both animations
// run at the same time. This is called "running asynchronously"
window.setTimeout(function() {
$('.toggle-item').not($parentToggle).animate({
width: '10%'
});
}, 0);
$parentToggle.animate({
width: '80%'
});
});
});
The window.setTimeout is the secret sauce here. Without it, jQuery will wait until the first animation is finished, THEN move on to the next. By wrapping the first animation inside a setTimeout we essentially remove it from the top-to-bottom execution process and call it asynchronously. We set this to timeout at "0" because we actually want it to run right away (as opposed to waiting a certain amount of milliseconds).
The CSS
The CSS has a "default state" .expanded class we add to the element intended to take up the 2/3 (or whatever % you want) space.
Notice also how that new parent div has a set width. Without it, the elements will flop around while transitioning.
.accordion {
width: 600px;
overflow: hidden;
}
.toggle-item {
float: left;
height: 200px;
width: 10%;
}
.expanded {
width: 80%;
}
#toggle {
background:red;
}
#toggle2 {
background:blue;
}
#toggle3 {
background:green;
}
.toggle-button {
height: 20px;
width: 100%;
}
#toggle-button {
background:blue;
}
#toggle-button2 {
background: purple;
}
#toggle-button3 {
background:orange;
}

Categories

Resources