modular JavaScript to call modal window - javascript

I'm using a plugin in pure JavaScript.
Here's a syntax for creating one modal window.
var modalContent = new tingle.modal();
var btn = document.querySelector('.trigger-button-1');
var modalWindow = document.querySelector('.project1-modal');
btn.addEventListener('click', function () {
modalContent.open();
});
modalContent.setContent(modalWindow.innerHTML);
In all, I need to create 8 modal windows, it was achieved with the following code I've written myself:
myModalContent = new tingle.modal();
var myBtn = document.querySelectorAll('button.project__btn');
for (var i = 0; i < myBtn.length; i++){
myBtn[i].addEventListener("click", function(){
myModalContent.open();
// check if a btn has an attribute
if (this.hasAttribute('data-btn')) {
myModalContent.setContent(document.querySelector('.project' + this.getAttribute("data-btn") + '-modal').innerHTML);
// otherwise set it to display only the project 1 modal window
} else {
myModalContent.setContent(document.querySelector('.project1-modal').innerHTML);
}
});
}
HTML (for 8 list elements in all)
<li class="project">
...
<button type="button" class="project__btn" data-btn="1">More</button>
<div class="project4-modal">
...
</div>
</li>
The problem above is solved but since I'm not a very experienced in JavaScript, I'm looking forward to getting a feedback or even a suggestion on how to improve my code.

Related

Class model for html backend [duplicate]

I'm working on a flexible menu, that does not need to jump from page to page when clicking 'links'.
The JavaScript I use for that is as follows:
var inbox = document.getElementById("u-content-inbox");
var friends = document.getElementById("u-content-friends");
var agenda = document.getElementById("u-content-agenda");
var list = document.getElementById("u-content-list");
var news = document.getElementById("u-content-news");
var notes = document.getElementById("u-content-notes");
function Inbox() {
inbox.style.visibility='visible';
}
function Friends() {
friends.style.visibility='visible';
}
function Agenda() {
agenda.style.visibility='visible';
}
function List() {
list.style.visibility='visible';
}
function News() {
news.style.visibility='visible';
}
function Notes() {
notes.style.visibility='visible';
}
The div elements are like this:
<div id="u-content-inbox" style="visibility:hidden;">
Inbox
</div>
<div id="u-content-friends" style="visibility:hidden;">
Friends
</div>
Each div has a "u-content-x".
However, when I try to change the style attribute "visibility" to visible. It gives me the following error: Uncaught TypeError: Cannot read property 'style' of null
I'm not seeing what I'm doing wrong. Could somebody please bring clearance to me why exactly JavaScript, or rather, I fail to make it work?
Whenever I run a check on
if(!inbox) {
alert("Inbox div has not been found);
}
does not show the alert message.
Make sure you call your javascript after the document is loaded! I'm nearly certain you are trying to get element references before they exist in the dom. The best practices is to put all scripts just before the closing of the body tag.
<script src="some/path/to/file.js"></script>
</body>
If your scripts appear in the document before the elements do, you can put your code inside of this load event function:
window.addEventListener('load', function() {
//your code here
});
Just as a note on your code architecture, you could attach a class to each element and then do this:
var toMakeVisible = document.getElementsByClassName('some-class');
for (var i=0; i<toMakeVisible; ++i) {
var elem = toMakeVisible[i];
elem.style.visibility = 'visible';
}

window.alert not running when button clicked

I'm trying to have the message "Parents have been alerted" to display in a window alert screen when a button is clicked, but so far I'm not able to get the message to display.
JS:
var thirtyMinDelayButton = document.querySelector("30-minute-delayed-button");
var hourDelayButton = document.querySelector("hour-delayed-button");
var cancelledButton = document.querySelector("cancelled-button");
/*
* event listeners
*/
thirtyMinDelayButton.onclick = function() {
window.alert("Parents have been alerted");
};
HTML:
<article id="contentstart">
<h2>Football</h2>
<p>Click a button below to update the schedule.</p>
<div class="changes">
<p class="30-minute-delayed-button">30 Minute Delay</p>
<p class="hour-delayed-button">hour Delay</p>
<p class="cancelled-button">Cancelled</p>
</div>
</article>
Why is it that this message isn't displaying, because from what I understand so far of JS it should work.
var thirtyMinDelayButton = document.querySelector(".30-minute-delayed-button");
I had a quick look on the Document.queryselector Mozilla developer site and it looks good, only thing I could see was a period before the class name?
Mozilla Developer Site - QuerySelector
If you want to perform any kind of action on these elements:
var thirtyMinDelayButton = document.querySelector("30-minute-delayed-button");
var hourDelayButton = document.querySelector("hour-delayed-button");
var cancelledButton = document.querySelector("cancelled-button");
Then change them to this:
var thirtyMinDelayButton = document.querySelector(".30-minute-delayed-button");
var hourDelayButton = document.querySelector(".hour-delayed-button");
var cancelledButton = document.querySelector(".cancelled-button");
They are CSS selectors and thus need to have a period before the class name when using document.querySelector

Why won't my JavaScript work!? It's selecting the ID but won't apply display changes

Before I get in to this, I know I should learn jQuery but I haven't got to that yet, I want to learn raw JavaScript first! Well, mostly. Can someone help me without the use of jQuery please just for understanding, thank you!:
Hi, I'm new to JavaScript, not long started learning it as you can see by the first code (which works so I'm leaving it) for the navigation.
However, my problem comes on the 2nd piece of code I'm trying something from a different angle after watching videos on event listeners etc and everything I have written makes sense, to me, I'm going through it step by step, it's selecting all the right stuff, but it's still not showing the desired result!!
When you click CSS i want it to show the div with id "cs", and same for the HTML and JavaScript ones.
I really don't know JavaScript enough to solve this myself, I can not think of anything AT ALL to help with the problem!
Somebody save me, please, my mind is going crazy and I want to go to bed!
Here is the code, and here is the JS fiddle: https://jsfiddle.net/pmj26o9p/2/
var htm = document.getElementById('htm');
var css = document.getElementById('css');
var js = document.getElementById('js');
htm.addEventListener("click", contentShow);
css.addEventListener("click", contentShow);
js.addEventListener("click", contentShow);
function contentShow() {
var whichOne = this.attributes["data-id"].value;
var switcheroo = document.getElementById(whichOne);
switcheroo.onclick = function() {
if (switcheroo.style.display === "none") {
switcheroo.style.display = "";
} else {
switcheroo.style.display = "none";
}
}
EDIT: On reading through the code again I don't think it will achieve what I want even if it works. This will let me show and hide whichever I'm clicking right?
I want to show the clicked one but then hide / apply display:none to all others that aren't clicked.
My example below will show the chosen block and hide the others, as per your EDIT comment.
var htm = document.getElementById('htm');
var css = document.getElementById('css');
var js = document.getElementById('js');
function contentShow(el) {
var whichOne = el.attributes["data-id"].value;
var switcheroo = document.getElementById(whichOne);
// show selected block, hide the others
switch (switcheroo) {
case htm:
htm.style.display = "block";
css.style.display = "none";
js.style.display = "none";
break;
case js:
htm.style.display = "none";
css.style.display = "none";
js.style.display = "block";
break;
case css:
htm.style.display = "none";
css.style.display = "block";
js.style.display = "none";
break;
}
}
<span data-id="htm" onClick="contentShow(this)" style="margin-right:10px;color:red; cursor:pointer">Click to show the HTML Block</span>
<span data-id="css" onClick="contentShow(this)" style="margin-right:10px;color:green; cursor:pointer">Click to show the CSS Block</span>
<span data-id="js" onClick="contentShow(this)" style="margin-right:10px;color:blue; cursor:pointer">Click to show the JS Block</span>
<br/>
<br/>
<div id="htm">Some HTML info here</div>
<div id="css" style="display:none">Some CSS info here</div>
<div id="js" style="display:none">Some JavaScript info here</div>
you are binding a second event handler to the switcheroo element, but the click event is not triggered so nothing happens.
If you want to make a toggle function on the switcheroo variable, you should do this instead:
function contentShow() {
var whichOne = this.attributes["data-id"].value;
var switcheroo = document.getElementById(whichOne);
return toggleDisplay(switcheroo);
}
function toggleDisplay(elem) {
if (elem.style.display === "none") {
elem.style.display = "";
} else {
elem.style.display = "none";
}
}
Ignoring your other bad practices, change
var htm = document.getElementById('htm');
var css = document.getElementById('css');
var js = document.getElementById('js');
htm.addEventListener("click", contentShow);
css.addEventListener("click", contentShow);
js.addEventListener("click", contentShow);
function contentShow() {
var whichOne = this.attributes["data-id"].value;
var switcheroo = document.getElementById(whichOne);
switcheroo.onclick = function() {
if (switcheroo.style.display === "none") {
switcheroo.style.display = "";
} else {
switcheroo.style.display = "none";
}
}
to something more like:
var doc = document;
function E(id){
return doc.getElementById(id); // you guessed it - same as document.getElementById, without typing it every time
}
var htm = E('htm'), css = E('css'), js = E('js');
contentShow = (function(){ // self-executing scopes off var showing - variable style assignment requires function definition before execution
var showing = false;
return function(){ // returns unexecuted function
var ht = E('ht').style, cs = E('cs').style, jsc = E('jsc').style;
if(showing){
ht.display = cs.display = jsc.display = 'none'; showing = false;
}
else{
ht.display = cs.display = jsc.display = 'block'; showing = true;
}
}
})();
htm.addEventListener('click', contentShow);
css.addEventListener('click', contentShow);
js.addEventListener('click', contentShow);
See updated JSFiddle here.
If there are no other click Events on those Elements, you could even change
htm.addEventListener('click', contentShow);
css.addEventListener('click', contentShow);
js.addEventListener('click', contentShow);
to
htm.onclick = css.onclick = js.onclick = contentShow;
JSFiddle here
but keep in mind this technique overwrites previous Events of the same type.
Here is a variation of #K Scandrett answer which add some scalability/flexibility
var navElements = document.getElementsByClassName("nav");
//Add Event Listeners
for(var i = 0; i < navElements.length; i ++)
{
navElements[i].addEventListener('click', contentShow, false);
}
function contentShow(el) {
var whichOne = el.target.attributes["data-id"].value;
var target = document.getElementById(whichOne);
for(var i = 0; i < navElements.length; i ++)
{
var content = document.getElementById(navElements[i].attributes["data-id"].value)
content.style.display = content === target ? "block" : "none";
}
}
<span data-id="htm" style="margin-right:10px;color:red; cursor:pointer" class="nav">Click to show the HTML Block</span>
<span data-id="css" style="margin-right:10px;color:green; cursor:pointer" class="nav">Click to show the CSS Block</span>
<span data-id="js" style="margin-right:10px;color:blue; cursor:pointer" class="nav">Click to show the JS Block</span>
<br/>
<br/>
<div id="htm">Some HTML info here</div>
<div id="css" style="display:none">Some CSS info here</div>
<div id="js" style="display:none">Some JavaScript info here</div>
I know you're looking for a javascript solution here.and kudos to you for wanting to understand javascript before getting into jquery, but here is an out of the box solution for you.... pure HTML and CSS
.info {display:none;}
.info:target{display:block;}
Click to show the HTML Block
Click to show the CSS Block
Click to show the JS Block
<br/>
<br/>
<div id="htm" class="info">Some HTML info here</div>
<div id="css" class="info">Some CSS info here</div>
<div id="js" class="info">Some JavaScript info here</div>
What I've done here is, leverage internal page id links and the :target selector. In my mind, this is more semantic and can also still be extended by scripting while still maintaining semantics. This option also gives your uses the option of bookmarking selections etc.
CSS OPTION 2
This option achieves the initial display. It is not as clean and uses absolute positioning and z-indexes. Alos note that is uses a background color to conceal the initial option.
.info {position:relative;}
.info > div {
position:absolute;
top:0;
left:0;
background-color:#FFF;
z-index:10;
display: none;
}
#htm
{
display:block;
z-index:1;
}
.info > div:target {
display: block;
}
Click to show the HTML Block
Click to show the CSS Block
Click to show the JS Block
<br/>
<br/>
<div class="info">
<div id="htm">Some HTML info here</div>
<div id="css">Some CSS info here</div>
<div id="js">Some JavaScript info here</div>
</div>
On a side note you should consider adding/removing css classes using javascript instead of the display property directly. This will enable the use of CSS transitions.

JavaScript AddEventListener not working

So I'm trying to make a slideshow where the user can click next to browse through pictures. I've created an array for the images:
var staff = new Array();
staff[0] = "/images/Isabelle.png";
staff[1] = "/images/Nook.png";
staff[2] = "/images/Timothy_Tommy.png";
staff[3] = "/images/Mabel.png";
staff[4] = "/images/Sable.png";
staff[5] = "/images/Labelle.png";
And a function for changing the images:
var i = 1;
function nextImage(){
document.getElementById("slide").src = staff[i];
if(i < staff.length)
i++;
else i = 0; //wraps around to first image
}
The addEventListener function call I added into a registerHandlers function that I initialize with onload:
document.getElementById("next").addEventListener("click",nextImage,false);
And the image and "next" button are placed in divs inside body:
<div class="container">
<img id ="slide" src="images/Isabelle.png" />
</div>
<div id="next">
<button type="button">Next</button>
</div>
I've tried looking up solutions and example code but I can't seem to make this work
Try adding the event handler as DHTML, so you don't have to wait for it to load the elements, just in case that's an issue:
<button type="button" onclick="nextImage();">Next</button>

Help me simplify this JS code

I'm a beginner in JS and want to know a way to simplify this code. There are 7 different divs with iframes, and also 7 different links. I have shown 1 div with iframe and 1 link. I have no idea where to start. Any help would be greatly appreciated.
NOTE: The code works to my needs, but I just need to simplify it (less js code in html, and more in js file).
JavaScript in .js file:
function show_visibility(){
for(var i = 0,e = arguments.length;i < e;i++){
var myDiv = document.getElementById(arguments[i]).style;
myDiv.display = "block";}
}
function hide_visibility(){
for(var i = 0,e = arguments.length;i < e;i++){
var myDiv = document.getElementById(arguments[i]).style;
myDiv.display = "none";}
}
function refFrame() {
for(var i = 0,e = arguments.length;i < e;i++){
document.getElementById(arguments[i]).src = document.getElementById(arguments[i]).src;
}
}
Div/iframe to be modified:
<div id="r1-box">
<iframe id="frame-box1" class="work" src="youtubelink" width="720" height="405" frameborder="0"></iframe>
</div>
Link to execute JS:
<a id="r1" href="javascript:refFrame('frame-box2','frame-box3','frame-box4','frame-box5','frame-box6','frame-box7');show_visibility('r1-box');hide_visibility('r2-box','r3-box', 'r4-box','r5-box','r6-box','r7-box');">
</a>
As a beginner you shouldn't start using jQuery until you understand Javascript more.
There are a few ways you could simplify this, the most immediate one would be to get the Javascript out of the link and into a Javascript file, or at the top of the page:
window.onload = function() {
document.getElementById('#r1').onclick = function() {
refFrame('frame-box2','frame-box3','frame-box4','frame-box5','frame-box6','frame-box7');
show_visibility('r1-box');
hide_visibility('r2-box','r3-box', 'r4-box','r5-box','r6-box','r7-box');
};
// more...
};
window.onload is an event which fires once the page has - you guessed it - finished loading. There are better ways of doing this, but this is about as basic as it gets. I'd advise you look at javascript domready?
After looking at your code a bit more, I realised all your seven links will do essentially the same thing. You can simply this by using a single function:
function refClick(id) {
var i = 7,
frames = [],
boxes = [];
while(i--) {
if(i != id) {
frames.push('frame-box' + i);
boxes.push('r' + i + '-box');
}
}
refFrame.apply(null, frames);
hide_visibility.apply(null, boxes);
show_visibility('r' + id + '-box');
}
What I'm doing here is looping through 7 times, and building an array of arguments for the refFrame and hide_visibility functions. The id variable tells the loop not to put in that id into the arrays.
Using the .apply method, I can apply an array as the arguments and call it normally.
For each of your links, you can apply the following function
document.getElementById('#r1').onclick = function() {
refClick(1);
};
document.getElementById('#r2').onclick = function() {
refClick(2);
};
//.....
You could start using jQuery.
http://jquery.com/

Categories

Resources