I found this code and it is the perfect solution for my problem but i just found out it won't work in ie9. Does anyone know how to re-write this code to work in IE9? here is the javascript code for it.
function showonlyonev2(thechosenone) {
var newboxes = document.getElementsByTagName("div");
for (var x = 0; x < newboxes.length; x++) {
name = newboxes[x].getAttribute("class");
if (name == 'newboxes-2') {
if (newboxes[x].id == thechosenone) {
if (newboxes[x].style.display == 'block') {
newboxes[x].style.display = 'none';
}
else {
newboxes[x].style.display = 'block';
}
} else {
newboxes[x].style.display = 'none';
}
}
}
}
I ran it in jsFiddle and got this error:
Problem at line 4 character 9: Read only.
name = newboxes[x].getAttribute("class");
also here is the HTML part (short Version removed the head and body tags):
<table>
<tr>
<td>
<div style="border: 1px solid blue; background-color: #99CCFF; padding: 5px; width: 150px;">
<a id="myHeader1" href="javascript:showonlyone('newboxes1');" >show this one only</a>
</div>
<div class="newboxes" id="newboxes1" style="border: 1px solid black; background-color: #CCCCCC; display: block;padding: 5px; width: 150px;">Div #1</div>
</td>
<td>
<div style="border: 1px solid blue; background-color: #99CCFF; padding: 5px; width: 150px;">
<a id="myHeader2" href="javascript:showonlyone('newboxes2');" >show this one only</a>
</div>
<div class="newboxes" id="newboxes2" style="border: 1px solid black; background-color: #CCCCCC; display: none;padding: 5px; width: 150px;">Div #2</div>
</td>
<td>
<div style="border: 1px solid blue; background-color: #99CCFF; padding: 5px; width: 150px;">
<a id="myHeader3" href="javascript:showonlyone('newboxes3');" >show this one only</a>
</div>
<div class="newboxes" id="newboxes3" style="border: 1px solid black; background-color: #CCCCCC; display: none;padding: 5px; width: 150px;">Div #3</div>
</td>
</tr>
</table>
here is my jsFiddle view
http://jsfiddle.net/Nuker_Viper/JvLDx/13/
Your edit makes the question clearer:
I ran it in jsFiddle and got this error: Problem at line 4 character 9: Read only.
name = newboxes[x].getAttribute("class");
You haven't declared name anywhere, so you're using name in some containing scope (probably global scope, e.g., window.name). Apparently IE9 considers that a read-only property, although I can't find any docs to support that.
In any case, you don't want to be mucking about with someone else's variable. Put var name; at the top of your function so you're using your own variable. :-)
Original answer when we had to guess at what was going wrong:
IE has a long-standing bug where it thinks the class attribute is called className, even in getAttribute. IE9 continues this bug in the misnamed "compatibility" mode. In standards mode, it gets it right.
The best thing to do is to avoid the issue entirely, since there's no need to use getAttribute for the class attribute; use the reflected property instead:
name = newboxes[x].className;
Related
I'm fairly new to Javascript, and i've reached an issue I can't figure out yet, so I'll explain it as best as I can.
I've got 2 divs containing a reply link with the same ID, OnClick. Only difference is the data-attribute which I thought could be used to differentiate the two. There are 2 reply divs that are styled to be hidden. The aim is once the reply link is clicked, the correct div will display below it.
The issue is, when you click any of the two Reply links, it only opens the first reply div below the first parent div. I'll created a little example to give a better understanding:
// Opens reply div and retrieves data-attribute (reply_id) to insert into MYSQL database
function replyLink(element) {
document.getElementById('reply').style.display = "block";
}
// Close div link, displays after opening reply box
function closeLink() {
document.getElementById('reply').style.display = "none";
}
#comment{
border: 1px solid #333333;
width: 500px;
height: 85px;
padding: 5px;
margin: 10px 10px 15px 10px;
}
#comment #content{
border: none;
padding: 15px;
font-size: 12px;
}
#comment #link{
border: none;
padding: 5px;
margin-top: 5px;
}
#comment #link a{
border: none;
text-decoration: none;
font-size: 12px;
color: blue;
}
#comment #link a:hover{
border: none;
text-decoration: underline;
font-size: 12px;
color: blue;
}
#reply{
border: 1px solid red;
padding: 15px;
margin: 0px 0px 10px 45px;
width: 400px;
}
<div id="comment">
<div id="content">
Content #1
</div>
<div id="link">
<a href='javascript:void(0);' onclick="replyLink()" data-test='1'>Reply</a>
</div>
</div>
<div id="reply" style="display: none;">
reply container 1
<a href='javascript:void(0);' onclick='closeLink()' />[Close]</a>
</div>
<div id="comment">
<div id="content">
Content #2
</div>
<div id="link">
<a href='javascript:void(0);' onclick="replyLink()" data-test='2'>Reply</a>
</div>
</div>
<div id="reply" style="display: none;">
reply container 2
<a href='javascript:void(0);' onclick='closeLink()' />[Close]</a>
</div>
Would a java genius be able to help me out.
You can use the classes for styling and IDs with indexes to identify the unique div boxes.
Here is the working example
function replyLink(index) {
document.getElementById('reply_' + index).style.display = "block";
}
// Close div link, displays after opening reply box
function closeLink(index) {
document.getElementById('reply_' + index).style.display = "none";
}
.comment {
border: 1px solid #333333;
width: 500px;
height: 85px;
padding: 5px;
margin: 10px 10px 15px 10px;
}
.comment .content {
border: none;
padding: 15px;
font-size: 12px;
}
.comment .link {
border: none;
padding: 5px;
margin-top: 5px;
}
.comment .link a {
border: none;
text-decoration: none;
font-size: 12px;
color: blue;
}
.comment .link a:hover {
border: none;
text-decoration: underline;
font-size: 12px;
color: blue;
}
.reply {
border: 1px solid red;
padding: 15px;
margin: 0px 0px 10px 45px;
width: 400px;
}
<div class="comment">
<div class="content">
Content #1
</div>
<div class="link">
<a href='javascript:void(0);' onclick="replyLink(0)" data-test='1'>Reply</a>
</div>
</div>
<div class="reply" id="reply_0" style="display: none;">
reply container 1
<a href='javascript:void(0);' onclick='closeLink(0)'>[Close]</a>
</div>
<div class="comment">
<div class="content">
Content #2
</div>
<div class="link">
<a href='javascript:void(0);' onclick="replyLink(1)" data-test='2'>Reply</a>
</div>
</div>
<div class="reply" id="reply_1" style="display: none;">
reply container 2
<a href='javascript:void(0);' onclick='closeLink(1)'>[Close]</a>
</div>
While the use of an id is straightforward when first working with JavaScript and HTML, it's use is discouraged as an anti-pattern. IDs make for brittle code (as you are seeing here) and don't scale well. Instead, don't use ids at all and instead use classes or a relative reference to the elements, such as this, .closest(), nextElementSibling, parentNode, etc.
Also, using hyperlinks as a "hook" to initiate some code upon a click event is semantically incorrect. Hyperlinks are for navigation and people who use screen readers will have difficulty navigating your page. Just about every visible HTML element supports a click event, so just attach a click handler directly to the element instead of wrapping the element with a hyperlink.
Lastly, there is no need for separate show and hide functions. Just add or remove a "hidden" class based on what was clicked.
You can see in my answer how much cleaner the HTML and JavaScript are without ids.
See comments inline below.
// Set up a single event handler for any clicks to any reply or Close
document.addEventListener("click", function(event){
// Check to see if the click originated at a Reply element
if(event.target.classList.contains("reply")){
// Find the closest ".comment" ancestor of the clicked reply
// element and then get the next element sibling to that and
// unhide it.
event.target.closest(".comment")
.nextElementSibling.classList.remove("hidden");
} else if(event.target.classList.contains("replyContainer")){
event.target.classList.add("hidden");
}
});
.hidden { display:none; }
.comment{
border: 1px solid #333333;
width: 500px;
height: 85px;
padding: 5px;
margin: 10px 10px 15px 10px;
}
.comment .reply{
padding: 5px;
margin-top: 5px;
}
.replyContainer{
border: 1px solid red;
padding: 15px;
margin: 0px 0px 10px 45px;
width: 400px;
}
<div class="comment">
<div class="content">Content #1</div>
<div class="reply">Reply</div>
</div>
<div class="hidden replyContainer">reply container 1[Close]</div>
<div class="comment">
<div class="content">Content #2</div>
<div class="reply">Reply</div>
</div>
<div class="hidden replyContainer">reply container 2[Close]</div>
<div class="comment">
<div class="content">Content #3</div>
<div class="reply">Reply</div>
</div>
<div class="hidden replyContainer">reply container 3[Close]</div>
I created a 3x3 table for my tic-tac-toe game using the table tag and i added a click event listener to the each of the row using forEach loop but unfortunately nothing is showing in my console
const boxes = document.querySelectorAll('.box');
const strategy = document.querySelector('#strategy');
const restartBtn = document.querySelector('#restart');
const arry = [];
const tick_x = 'X';
const tick_o = 'O';
const userAction = () => {
boxes.forEach((box) => {
box.addEventListener('click', function clk() {
console.log("clicked")
})
})
}
html {
height: 100%;
}
body {
margin: 0;
padding: 0;
background-color: teal;
overflow: hidden;
font-family: "Itim", cursive;
}
.game {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
p {
color: white;
text-align: center;
margin: 40px auto;
width: 200px;
}
table {
margin-bottom: 50px;
border-radius: 10px;
border-top: 2px solid white;
border-left: 2px solid white;
border-bottom: 2px solid white;
border-right: 2px solid white;
}
button {
width: 100px;
}
h1 {
width: 100%;
height: 100%;
text-align: center;
}
.row1 td {
width: 100px;
height: 100px;
border-bottom: 1px solid white;
border-left: 1px solid white;
}
.row2 td {
width: 100px;
height: 100px;
border-bottom: 1px solid white;
border-left: 1px solid white;
}
.row3 td {
width: 100px;
height: 100px;
border-left: 1px solid white;
}
.r11 {
border-left: none;
}
<div class="intro">
<p class="name">TIC-TAC-TOE</p>
<h2 id="strategy"></h2>
<p class="player">Player X'S turn</p>
</div>
<table>
<tr class="row1">
<td class="r11">
<h1 class="box" id="0"> </h1>
</td>
<td class="r12">
<h1 class="box" id="1"> </h1>
</td>
<td class="r13">
<h1 class="box" id="2"> </h1>
</td>
</tr>
<tr class="row2">
<td class="r21">
<h1 class="box" id="3"> </h1>
</td>
<td class="r22">
<h1 class="box" id="4"> </h1>
</td>
<td class="r23">
<h1 class="box" id="5"> </h1>
</td>
</tr>
<tr class="row3">
<td class="r31">
<h1 class="box" id="6"> </h1>
</td>
<td class="r32">
<h1 class="box" id="7"> </h1>
</td>
<td class="r33">
<h1 class="box" id="8"> </h1>
</td>
</tr>
</table>
<button id="restart"><h3>Reset</h3></button>
</div>
I recommend that you use a single event handler for the whole table rather than creating one for each row. (This used to be known as a "delegated event handler.")
That would look like this:
let table = document.querySelector('table')
function onClickCell( event, cellId ) {
// this is invoked when a cell is clicked
console.log(`onClickCell`, cellId)
}
// this is the delegated event handler
table.addEventListener('click', event => {
// figure out which table cell it occurs within
let td = event.target.closest('.box')
// if click wasn't inside a cell (e.g. was in gutter), don't fire the cell-click handler
if(!td) return true
// click WAS inside a cell: fire cell-click handler with some helpful data
let cellId = td.getAttribute('id')
return onClickCell(event, cellId)
})
Some reasons for using a delegated event handler:
Better runtime performance
Admittedly, this is less of an issue with modern browsers than it was 10 years ago, and isn't a major problem given that your use-case is so small, but it's still a good practice.
One handler is easier to manage than three
You will want clicks on the table to do different things depending on the current game phase. During the "gameplay" phase, clicking on a cell should claim the cell for the active player. Before gameplay begins, maybe there is no visible grid of cells, or maybe you have an invented mechanic for choosing which player goes first. After the gameplay phase, you may want clicking on a cell to reveal on which turn that cell was claimed (so players can study the game they just finished). No matter what you've got in mind, having a single root-level click handler for the table will drastically simplify the job of re-wiring how clicks are handled.
Survivability
If you modify the document, either by overwriting some innerHTML, or by using the DOM API to modify nodes, you'll obliterate existing click handlers that are attached to the modified portion of the document. But a delegated handler is, by definition, attached to a distant ancestor of the relevant part of the DOM, meaning it will survive and stay active.
Define your own API
You have zero control over the arguments that the browser provides to a regular DOM event handler. But a delegated handler can pass any data you want to your specialty function, meaning you can define a custom API for the functions it calls. In my example, I make the delegated handler do the work of grabbing the cell's ID, and then it passes that value as an argument to the cell-click handler; that's work the cell-click handler no longer needs to do. The delegated handler could also collect other info about the current game state and provide that to the cell-click handler. A delegated handler can also selectively ignore some some clicks, or call additional functions, or even call the cell-click function multiple times -- essentially letting you invent new kinds of events. A more sophisticated version might even fire literal CustomEvents that are listened for at the document level.
You never call userAction, so you can either call it or wrap it in a closure and call it (as below)
const boxes = document.querySelectorAll('.box');
const strategy = document.querySelector('#strategy');
const restartBtn = document.querySelector('#restart');
const arry = [];
const tick_x = 'X';
const tick_o = 'O';
(() => {
boxes.forEach((box) => {
box.addEventListener('click', function clk () {
console.log("clicked")
})
})
})()
html{
height: 100%;
} body{
margin: 0;
padding: 0;
background-color: teal;
overflow: hidden;
font-family: "Itim", cursive;
}
.game{ display: flex; flex-direction: column; justify-content: center; align-items: center; } p{ color: white; text-align: center; margin: 40px auto; width: 200px; }
table{
margin-bottom: 50px;
border-radius: 10px;
border-top: 2px solid white;
border-left: 2px solid white;
border-bottom: 2px solid white;
border-right: 2px solid white;
}
button{
width: 100px;
} h1{ width: 100%; height: 100%; text-align: center;
}
.row1 td{
width: 100px;
height: 100px;
border-bottom: 1px solid white;
border-left: 1px solid white;
}
.row2 td{
width: 100px;
height: 100px;
border-bottom: 1px solid white;
border-left: 1px solid white;
}
.row3 td{
width: 100px;
height: 100px;
border-left: 1px solid white;
}
.r11 {
border-left: none;
}
<!DOCTYPE html>
<head></head>
<body>
<div class="intro">
<p class="name">TIC-TAC-TOE</p>
<h2 id="strategy"></h2>
<p class="player">Player X'S turn</p>
</div>
<table>
<tr class="row1">
<td class="r11"><h1 class = "box" id ="0"> </h1></td>
<td class="r12"><h1 class = "box" id ="1"> </h1></td>
<td class="r13"><h1 class = "box" id ="2"> </h1></td>
</tr>
<tr class="row2">
<td class="r21"><h1 class="box" id ="3"> </h1></td>
<td class="r22"><h1 class="box" id ="4"> </h1></td>
<td class="r23"><h1 class="box" id ="5"> </h1></td>
</tr>
<tr class="row3">
<td class="r31"><h1 class="box" id ="6"> </h1></td>
<td class="r32"><h1 class="box" id ="7"> </h1></td>
<td class="r33"><h1 class="box" id ="8"> </h1></td>
</tr>
</table>
<button id="restart"><h3>Reset</h3></button>
</div>
</body>
You create the userAction function, but never call it.
Add at the end:
userAction()
Alright so basically i've been searching for a way that when someone clicks a text , a scroll down menu drops down with basically more information ( Sort of like a read more ).
I little experience in Java or Jquery and im not even sure where the problem is wether it's in my functions.php or my script itself . I've done alot of research and tried alot of things but none seem to be able to help me out so i figured id make my own post .
Keep in my , i took most of the codes in templates given by other member and tried to modify the code so it works with my site, I am trying to accomplish something similar to this site : http://www.randomsnippets.com/2011/04/10/how-to-hide-show-or-toggle-your-div-with-jquery/ the second example where there are 3 boxes and only one shows up when you click on it, However mine will simply be text instead of boxes)
My Javascript file looks like this(as stated in comment idk what thechosenone is , my guess is when you select a box it is now known as the chosen one ) :
jQuery(document).ready(function (){
$('.newboxes').each(function(index) {
if ($(this).attr("id") == thechosenone) {
$(this).show(200);
}
else {
$(this).hide(600);
}
});
}(jQuery)
So i went ahead and modified my function.php and added these line of code :
add_action('wp_enqueue_scripts', 'showonlyone' );
function showonlyone() {
wp_enqueue_script('showonlyone', get_template_directory_uri() . "/js/showonlyone.js");
}
As for calling the java script into my wordpress page I have no idea how to do this . The template gave me something like this :
<table>
<tr>
<td>
<div style="border: 1px solid blue; background-color: #99CCFF; padding: 5px; width: 150px;">
<a id="myHeader1" href="javascript:showonlyone('newboxes1');" >show this one only</a>
</div>
<div class="newboxes" id="newboxes1" style="border: 1px solid black; background-color: #CCCCCC; display: block;padding: 5px; width: 150px;">Div #1</div>
</td>
<td>
<div style="border: 1px solid blue; background-color: #99CCFF; padding: 5px; width: 150px;">
<a id="myHeader2" href="javascript:showonlyone('newboxes2');" >show this one only</a>
</div>
<div class="newboxes" id="newboxes2" style="border: 1px solid black; background-color: #CCCCCC; display: none;padding: 5px; width: 150px;">Div #2</div>
</td>
<td>
<div style="border: 1px solid blue; background-color: #99CCFF; padding: 5px; width: 150px;">
<a id="myHeader3" href="javascript:showonlyone('newboxes3');" >show this one only</a>
</div>
<div class="newboxes" id="newboxes3" style="border: 1px solid black; background-color: #CCCCCC; display: none;padding: 5px; width: 150px;">Div #3</div>
</td>
</tr>
</table>
Can someone please tell me how im supposed to be calling this function and add it to a block of text ? I just want that when someone clicks on it , this box or whatever, drops down and displays additional information and when you click on another line of text this window will scroll back up and the other one will drop down .
Took me a minute but here you go:
http://jsfiddle.net/V4DTZ/
Now, for whats going on in the code:
<table>
<tr>
<td>
<div style="border: 1px solid blue; background-color: #99CCFF; padding: 5px; width: 150px;">
<a class="newboxes" href="#" id="newboxes1">show this one only</a>
</div>
<div class ="div_newboxes" id="div_newboxes1" style="border: 1px solid black; background-color: #CCCCCC; display: block;padding: 5px; width: 150px;">Div #1</div>
</td>
<td>
<div style="border: 1px solid blue; background-color: #99CCFF; padding: 5px; width: 150px;">
<a class="newboxes" href="#" id="newboxes2" >show this one only</a>
</div>
<div class ="div_newboxes" id="div_newboxes2" style="border: 1px solid black; background-color: #CCCCCC; display: none;padding: 5px; width: 150px;">Div #2</div>
</td>
<td>
<div style="border: 1px solid blue; background-color: #99CCFF; padding: 5px; width: 150px;">
<a class="newboxes" href="#" id="newboxes3" >show this one only</a>
</div>
<div class ="div_newboxes" id="div_newboxes3" style="border: 1px solid black; background-color: #CCCCCC; display: none;padding: 5px; width: 150px;">Div #3</div>
</td>
</tr>
You'll see that I changed the id of the links to their corresponding div, and I added a div_ prefix on the ids of the div.
This way we have an easy way to select the div that matches with the link
I gave all of the links the same class, so that we can set up one onclick event for all of the links.
All of the div that contain your content also has the same class, so we can toggle them all at once.
Here is the jquery:
jQuery(document).ready(function (){
$('.newboxes').on('click', function(){
var div_id = "#div_" + $(this).prop('id');
$('.div_newboxes').each(function(i, value){
if($(value).prop('id')=== $(div_id).prop('id')){
$(div_id).show(200);
}
else{
$(value).hide(600);
}
});
})
}(jQuery))
Note that because we used an onclick event for all elements with class = "newboxes"
we are now able to use this to refer to the specific calling element. There is now no need to have theChosenOne variable.
When document is ready, attach event handlers to all of the elements needed
The event handler that is called every time a click happens on these elements
Event Handler
var ShowHideBlocks = function(){
$('.newboxes').each(function(index) {
if ($(this).attr("id") == thechosenone) {
$(this).show(200);
}
else {
$(this).hide(600);
}
});
}
Attached to all interested elements
jQuery(document).ready(function (){
$('.newboxes').each(function(index) {
$(this).bind('click',function(){
thechosenone = $(this).attr(id); //thechosenone is a global variable
ShowHideBlocks(); // Invoke the showHide method as part of anonymous handler
});
}
});
}(jQuery)
I've got a jade email template. It includes a mixin file which includes the header mixin, which should be in all emails. It gets included properly, but due to the nesting level within it (3 levels deep), anything I put after the mixin, doesn't maintain nesting where it should.
views/mixins/email.jade
mixin header(siteLogo)
div(style='margin-bottom: 20px; border: 1px solid #ddd; padding: 20px; width: 50%; margin: 0 auto 20px;')
div(style='text-align: center; border-bottom: 1px solid #EEE; padding-bottom: 10px;')
img(src='#{siteLogo}', style='text-align: center;')
views/emails/forgot_password.jade:
include ../mixins/email
+header(siteLogo)
p
| Hi #{name},
p
| Welcome to the site!
Generates the email html like:
<div style="margin-bottom:20px;border:1px solid #ddd;padding:20px;width:50%;margin:0 auto 20px">
<div style="text-align:center;border-bottom:1px solid #eee;padding-bottom:10px">
<img src="path/to/image/logo" style="text-align:center">
</div>
</div>
<p>Hi BobCobb</p>
<p>Welcome to the site!</p>
But I want both of those paragraph tags to be inside of the main <div> like:
<div style="margin-bottom:20px;border:1px solid #ddd;padding:20px;width:50%;margin:0 auto 20px">
<div style="text-align:center;border-bottom:1px solid #eee;padding-bottom:10px">
<img src="path/to/image/logo" style="text-align:center">
</div>
<p>Hi BobCobb</p>
<p>Welcome to the site!</p>
</div>
To actually answer the original question, you need to specify within the mixin where the block should render.
views/mixins/email.jade
mixin header(siteLogo)
div(style='margin-bottom: 20px; border: 1px solid #ddd; padding: 20px; width: 50%; margin: 0 auto 20px;')
div(style='text-align: center; border-bottom: 1px solid #EEE; padding-bottom: 10px;')
img(src='#{siteLogo}', style='text-align: center;')
if block
block
Jade is useless for html email. I would strongly recommend against using any web intended framework.
Read up more on how html email differs from the web.
Here is what your code should look like if it is optimized for html email:
<table width="50%" border="0" cellpadding="0" cellspacing="0" style="border:1px solid #dddddd">
<tr>
<td align="center">
<img alt="" src="path/to/image/logo" width="100" height="75" style="margin: 0; border: 0; padding: 0; display: block;">
</td>
</tr>
<tr>
<td style="font-family: Helvetica, Arial, sans-serif; font-size: 14px; color: #000000; padding:20px; border-top:1px solid #dddddd;">
<p>Hi BobCobb</p>
<p>Welcome to the site!</p>
</td>
</tr>
</table>
I am currently using jquery slideonlyone function. I am having problems implementing an expanding/collapsing image(Plus.png)(Minus.png) change when clicked on. this is my jquery code.
<script type="text/javascript">
function slideonlyone(thechosenone) {
$('div[name|="newboxes2"]').each(function(index) {
if ($(this).attr("id") == thechosenone) {
$(this).find("img").attr({src:"Minus.png"}).slideDown(200);
}
else {
$(this).find("img").attr({src:"Plus.png"}).slideUp(600);
}
});
}</script>
<table><tr>
<td>
<div style="border: 1px solid blue; background-color: #99CCFF; padding: 5px;">
<a id="myHeader1" href="javascript:slideonlyone('newboxes1');" ><img src="images/faq_cuts/Plus_Circle.png";/>slide this one only</a>
</div>
<div name="newboxes2" id="newboxes1" style="border: 1px solid black; background-color: #CCCCCC; display: block;padding: 5px;">Div #1</div>
</td>
<td>
<div style="border: 1px solid blue; background-color: #99CCFF; padding: 5px;">
<a id="myHeader2" href="javascript:slideonlyone('newboxes2');" ><img src="images/faq_cuts/Plus_Circle.png";/>slide this one only</a>
</div>
You don't actually have any images in your html.
Also, you are using attr incorrectly. If you want to set the src of an image it would be .attr("src","Minus.png").