I'm trying to create a web page which generates a series of unique DIV IDs, each displaying different content based off of the entries in an SQL table.
Each div has a "hide" and "show" button, which work independently when manually giving each div a unique name.
I can get the divs themselves to generate based on class names in PHP, which displays the divs correctly.
The problem lies in the "hide" and "show" buttons since they're controlled by JavaScript. The code is as follows:
for ($j = 0 ; $j < $rows ; ++$j)
{
for($i =0; $i < $rows2; $i++)
{
if (mysql_num_rows($ans) > 0) //check if widget table is empty
{
$widgetusr[$j] = mysql_result($ans,$j,'wname')or die(mysql_error()); //user's widget
$widgetstore[$i] = mysql_result($ans2,$i,'wname'); //store widget
if($widgetusr[$j] == $widgetstore[$i] && $widgetusr[$j] != 'Medieval Calendar') //check if user has already purchased the widget
{
echo "<div class=widget_container".$j%2 .">"; //container divs are named 1 and 0. j mod 2 should return either 1 or 0
?>
<!----Start of weather Widget--->
<!---Script for show/hide buttons weather widget--->
<script>
var widg = "<?php echo $widgetusr[$j]; ?>";
var id = "#" + widg;
$(document).ready(function(){
$("#hide1").click(function(){
$(id).hide();
});
$("#show1").click(function(){
$(id).show();
});
});
</script>
<button id="hide1">Hide</button>
<button id="show1">Show</button>
<!---End Script for show/hide buttons weather widget--->
<?php
echo "<div class = 'widget' id='$widgetusr[$j]'>
</div>
</div>
<!----End of Widget---> ";
}
}
else
{
echo "You have no widgets please visit <a href='store.php'> the store </a> to purchase some. <br/>"; //widget table is empty. Redirect to widget store.
}
}
}
?>
I tried to pass the php varriable (containing an SQL value) to JavaScript (which works successfully, I was able to print out "#financial widget" as an id name.), however neither the show, nor hide button works. The generated divs all have the correct names also.
If additional information is required please ask. I tried to be as general as possible.
You really only need one button. Change your php to render the following html
<div class="widget_container">
<button class="btn ">Hide</button>
<div class="widget">widget1</div>
</div>
<div class="widget_container">
<button class="btn">Hide</button>
<div class="widget">widget2</div>
</div>
<div class="widget_container">
<button class="btn">Hide</button>
<div class="widget">widget3</div>
</div>
and output the following Outside of the loop, ensuring jQuery is loaded:
<script type="text/javascript">
//Standar jquery doc ready event, fires when the dom is loaded
$(document).ready(function(){
//add an event listener elements with a class of "btn"
$('.btn').click(function () {
//"this" is the element click, so we find siblings of this with a class
//of "widget" and toggle its visibility
$(this).siblings('.widget').toggle();
//Change the text of the button the below is short hand for:
//if($(this).text() == "Hide"){
// $(this).text("Show");
//}else{
// $(this).text("Hide");
//}
$(this).text($(this).text() == "Hide" ? "Show" : "Hide");
});
});
</script>
Example
Some useful links:
http://learn.jquery.com/using-jquery-core/document-ready/
http://api.jquery.com/click/
http://api.jquery.com/siblings/
http://api.jquery.com/closest/
http://api.jquery.com/toggle/
http://api.jquery.com/text/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
Example with fixed height widgets: http://jsfiddle.net/bdpm4/2/
Update 2
Perhaps a better way to do it: http://jsfiddle.net/bdpm4/3/
you should use class instead of id and dont put your $(document).ready() in the loop.
HTML:
<div class="widget_container">
<button class="btn hideBtn">Hide</button>
<button class="btn showBtn">Show</button>
<div class="widget">widget1</div>
</div>
<div class="widget_container">
<button class="btn hideBtn">Hide</button>
<button class="btn showBtn">Show</button>
<div class="widget">widget2</div>
</div>
JS:
$(document).ready(function(){
$('.btn').on('click', function (evt) {
var btn = $(evt.target);
btn.siblings('.widget').toggle();
btn.parent().find('.btn').toggle();
});
});
CSS:
.showBtn {
display:none;
}
here is an example: http://jsfiddle.net/xdA4r/4/
Related
I have a list a.href to many URL contain film.
When I click a.href, it will reload my page. I don't know how to add the class .active to the a.href current selected.
In Ajax call, it simple like this code, it's working because the page is not reloaded. But I write on PHP and using $_GET and $_POST method. So the page must be reloaded.
Have any method to add the class .active on a.href link was clicked?
<div class="btn-group listEp col-md-12">
$i = 0;
Episode:
<?php foreach($data['episodes'] as $epList) { ?>
<a class="btn btn-default" href="<?php echo $epList['href']); ?>"> <?php echo $i++; ?> </a>
<?php } ?>
</div>
$(function() {
$('#listEp').on("click", "a", function() {
$( "#listEp a:first-child" ).css("cssText", "background: #4CAF50 !important;");
$(this).addClass('active').siblings().removeClass('active');
});
});
If you don't want to reload page after click and create a custom action on this just do this:
$('#listEp').on("click", "a", function(e) {
e.preventDefault() // this will disable default action which is redirect in case of a element
e.stopPropagation() // this will stop element beeing propagated by other functions
$( "#listEp a:first-child" ).css("cssText", "background: #4CAF50 !important;");
$(this).addClass('active').siblings().removeClass('active');
});
Looks like you're targeting an ID which doesn't exist, the element has a class listEp. Try $('.listEp') instead
You can do simply like this,
$('a.btn[href]').click(function(){
$('a.btn[href]').removeClass('active');
$(this).addClass('active');
});
above code removes active class from other same elements and adds class in this element.
Add below code to that page which is rendering on reload,
$(document).ready(function(){
$('a.active.btn[href]').removeClass('active');
});
I have a web page in PHP that shows blog posts/ articles that were posted from 2015-2008. basically at the top of the page I have buttons that have the year on it, and below all the blog posts and articles correlatin to the years. I want to have a feature so that if the user clicks 2013, all other posts with years not matching 2013 will dissapear and the correct year posts/articles will move up to the top of the page, so the user doesn't have to scroll.
Here is my code, the content is loaded through a controller so the page is basically created by grabbing data from an array.
<div class="calendar-key">
<div class="cd-timeline2-img cd-2015" id="btn" >'15</div>
<div class="cd-timeline2-img cd-2014" >'14</div>
<div class="cd-timeline2-img cd-2013" >'13</div>
<div class="cd-timeline2-img cd-2012">'12</div>
<div class="cd-timeline2-img cd-2011" >'11</div>
<div class="cd-timeline2-img cd-2010" >'10</div>
<div class="cd-timeline2-img cd-2009" >'09</div>
<div class="cd-timeline2-img cd-2008" >'08</div>
<div class="cd-timeline2-img cd-2007" >'07</div>
<?php foreach ($article as $slug => $article): ?>
<div class="cd-timeline-block">
<div class="cd-timeline-img cd-<?php echo $article['year'] ?>">
<span class="timelinedate"><?php echo $article['month'] ?><?php echo $article['day'] ?></span>
</div>
<div class="cd-timeline-content">
<a href="<?php echo $article['link'] ?>">
<h3 class="press_title" id="<?php echo $article['year'] ?>-<?php echo $article['first'] ?>"><?php echo $article['title'] ?></h3>
<img src="<?php echo $article['image'] ?>" width="100%" height="auto" />
</a>
<p><?php echo $article['description'] ?> </p>
<div class="social-share-buttons article-share-buttons pull-left">
<a class='social-email' href='<?php echo SocialShareLink::email("", "Check out this article, ".$article['title']." \n\n" .$article['link']); ?>'</a>
<a class='social-facebook' href='<?php echo SocialShareLink::facebook($article['link']); ?>' target='_blank'></a>
<a class='social-twitter' href='<?php echo SocialShareLink::twitter("", $article['link']); ?>' target='_blank'></a>
<a class='social-google' href='<?php echo SocialShareLink::googleplus($article['link']); ?>' target='_blank'></a>
</div>
Read more
</div>
</div>
<?php endforeach; ?>
the for each basically takes an array I have in a config file with data, and populates the articles on the page for however many there are in the array.
'articles' => [
'article#1 example' => [
'description' => "exampletextblablabla",
'title' => 'article title',
'link' => '//www.google.com',
'year' => '2015',
'month' => 'Jul ',
'day' => '25',
'first' => '1', //first article of that year
'image' => '../../images/example.jpg'
],
//more articles in this format
and then my failed attempt at js
<script type="javascript">
$('.cd-timeline2-img a').on('click',function(){
var eq = $(this).index();
$('cd-timeline-img cd-<?php echo $article['year'] ?>').removeClass('show');
$('cd-timeline-img cd-<?php echo $article['year'] ?>').eq(eq).addClass('show');
});
</script>
I am not very good at javascript, so I tried something like this but nothing works. I feel like this is an easy little script to right, any help would be great! thanks.
Woohoo! Finally, I got it working and 100% where I want it. So I used your code and threw it into a Fiddle: https://jsfiddle.net/rockmandew/4Lyofmkh/44/
You will see that I went with my approach - by default, the articles are display none and have a class of 'show' on them to begin with - you will also notice I changed where you had your 'cd-(year)' - I did this because you needed to identify the entire article container since that is what you would be hiding/showing.
I also added a 'Show All' button, so the user can view all if desired.
So like I said I changed your HTML markup right here:
<div class="cd-timeline-block cd-2015 show">
<!-- Article Year in Div Class below -->
<div class="cd-timeline-img">
It was "cd-timeline-img cd-2015" previously. That is the only change you need to make to your markup, besides adding the "show all" button (if you want it):
<div class="show-all">Show All</div>
Furthermore, I applied the display:none css property to the ".cd-timeline-block"
.cd-timeline-block {
margin-top:35px;
display:none;
}
Which is why we initialize the page with the "show" class on there:
<div class="cd-timeline-block cd-2015 show">
Which has the following styles:
.show {
display:block;
}
Finally, we get to the meat of it all, the jQuery. I will post the working code that I used and then explain it. The following code is to toggle articles based on the year clicked:
$('.calendar-key a').each(function() {
$(this).on('click', function() {
var x = 'cd-' + $(this).attr('rel');
$('.cd-timeline-block').each(function() {
if($(this).hasClass(x)) {
$('.cd-timeline-block').not(this).each(function() {
if($(this).hasClass('show')) {
$(this).toggleClass('show');
}
});
$(this).each(function() {
if(!$(this).hasClass('show')) {
$(this).toggleClass('show');
}
});
}
});
})
});
As you will see, when a ".calendar-key" link is clicked, the clicked link will produce a variable based on the links "rel" - the variable adds the "cd-" prefix onto the "rel" value. Then for each ".cd-timeline-block" if it has the class that was created from clicking (the variable just discussed), it will cycle through all of the ".cd-timeline-block" elements that isn't "this" (meaning all elements that don't match the selected year.) - for all of those elements, if it has the "show" class, it will be toggled. Then the last part, it takes the "this" and cycles through each of them, if it doesn't have the class "show", then it toggles the class "show", thus displaying the desired elements.
Finally, the show all button is controlled with the following function:
$('.show-all a').on('click', function() {
$('.cd-timeline-block').each(function() {
if(!$(this).hasClass('show')) {
$(this).toggleClass('show');
}
});
});
Its a fairly simple function. When the ".show-all" link is clicked, it cycles through all of the ".cd-timeline-block" elements, again, if they don't have the "show" class, the function will toggle the "show" class.
I know that was a lot but hopefully it all made sense. Again, here is the associated Fiddle I made to help you.
https://jsfiddle.net/rockmandew/4Lyofmkh/44/
Let me know if you need any further help.
Latest Update:
https://jsfiddle.net/rockmandew/4Lyofmkh/46/
Fiddle now contains new mark-up for easiest solution to updated issue marked in comments below.
It finally dawned on me that I was filtering your list of years not your posts. For future reference post a snippet of actual code, now bits with php all over them. Now the script looks for the rel attribute in your year list for the year, matches that year to the class "cd-year" in each post and filters as necessary. I stripped out all of the superfluous parts of the post like the social links as they're not needed for this exercise.
http://jsfiddle.net/1dyocexe/2/
//this is where you'd have your <?php echo $article['year'] ?> set the current year
var year = 2014;
getPosts(year);
function getPosts(year) {
$(".cd-timeline-block").find("div").each(function (i) {
var elm = $(this);
var cdYear = "cd-" + year;
var use = elm.hasClass(cdYear);
if (use === true) {
elm.show();
} else {
elm.hide();
}
});
}
$(".calendar-key div a").on("click", function () {
var year = $(this).attr("rel");
getPosts(year);
});
I created a page that displays post with comments using ajax
To view the comments user must click comment button correspond to the post
For simple understanding, example:
In HTML
Block
<button id="btn1">cmt1</button>
<button id="btn2">cmt2</button>
<div id="cmt1">comments</div>
<div id="cmt2">comments</div>
'
I tried of using for loop as
for(var i=0;i<count;i++){
$("#cmt"+i).hide();
$("#cmtbtn"+i).click(function(){
$("#cmt"+i).toggle('slow');
});
}
But It works well for the last cmtbtn only and whenever i click all other buttons last comment box only displays
I'm saying that is there is a way of for loop or any looping
Update: My Js file is here http://jsfiddle.net/9ss50nzc
Try to give a same and unique class to all "Comment Button" and also to "Comment Div". Like example bellow :
<button id="btn1" class="comtbtn"> cmt1 </button>
<button id="btn2" class="comtbtn"> cmt2 </button>
<div id="cmt1" class="comt-div">comments1</div>
<div id="cmt2" class="comt-div">comments2</div>
Then catch the click event on class "comtbtn" . Bellow is the js script to hide show of comment -
$('.comtbtn').click(function() {
var btnId = $(this).attr("id");
var id = btnId.slice(-1);
$( "#cmt"+id ).toggle( "slow" );
});
Add css to hide all the comment section when initially loaded to the DOM.
.comt-div{
display:none;
}
Is this the sort of thing you want? A means of getting the index of the button which is equivalent to the indexed position of the hidden comment on your document?
You just hide the previous comment and display the new comment.
var oldNode = '';
function showComment = function(index) {
if (typeof oldNode != undefined) $(oldNode).hide('slow');
$('.comment:eq('+$(index).index()+')').show();
oldNode = $('comment:eq('+$(index).index()+')');
}
<button onclick="showComment(this)">cmnt 1</button>
<button onclick="showComment(this)" >cmnt 2</button>
<div class='comment' style='display: none'>comment a</div>
<div class='comment' style='display: none'>comment b</div>
Start with giving your buttons and divs classes
<button id="btn1" class="actionButtons">cmt1</button>
<button id="btn2" class="actionButtons">cmt2</button>
<div id="cmt1" class="actionDivs" style="display:none">comments1<br/>more comments<br/>and even more</div>
<div id="cmt2" class="actionDivs" style="display:none">comments2<br/>another comment<br/>and another one</div>
Then loop through elements with that class name
for(var i = 0; i < $(".actionButtons").length; i++){
$(".actionButtons")[i].onclick = function () {
for(var j = 0; j < $(".actionDivs").length; j++){
if ($(".actionDivs")[j].id == this.innerText)
$("#" + this.innerText).show();
else
$("#" + $(".actionDivs")[j].id).hide();
}
};
}
Fiddle
I hope this takes you closer to your solution.
I got the answer it is possible to toggle inside loop by using traversing. Thanks everyone finally I sort out the answer.
I'm having problem with a div which has a button on it.Button has id='delsts' and that whole div is fetched from php like below code:-
//php code
foreach ($data as $row) {
$status = $row['status'];
$fn = $row['firstname'];
$time =$row['posted_dt'];
echo "<div id='stsshown'>
<div class='upropic'></div>
<span class='uname'><a href='#'>".ucfirst($fn)."</a></span>
<span class='postdt'>".$time."</span><form action='#'><input type='button' value='x' id='delsts' title='remove from timeline' name='delsts'></form>
<div id='detailbox'>
asdasd
</div>
<div class='stsbox'>".$status."</div></div>";
}
And this below jquery function is directly added from html(not php)
//Jquery code
<script type="text/javascript">
$(document).ready(function(){
$(document).on('click','#delsts',function(){
$('#detailbox').slideToggle('fast');
});
</script>
Now, according to my php code I have fetched some data first so, everything is fine there I get some five div on my webpage (as I have five data on database related to that div).Now secondly jquery code is handling onclick event function on id 'delsts' of those five div.Now the main problem is that when I click those button of any five div my jquery function works for only first div out of other div why?how can we make every div work same jquery onclick event function individually?
Do not use id with the same value for multiple elements. Use a class selector instead for all elements.
Example HTML:
<div class='stsshown'>
<div class='upropic'></div>
<span class='uname'><a href='#'>username</a></span>
<span class='postdt'></span><form action='#'><input type='button' value='x' class='delsts' title='remove from timeline' name='delsts'></form>
<div class='detailbox' style="display:block;">
test
</div>
<div class='stsbox'></div>
</div>
JS:
$(document).ready(function(){
$('.delsts').on('click', function(){
$(this).closest('.stsshown').find('.detailbox').slideToggle('fast');
});
});
This example is usable for generation of multiple sets of elements you want to achieve.
There can be only 1 id element with the same name in the document, but you generate more of them in loop.
Use classes instead of IDs, or assign unique IDs for each item.
change your jquery code to:
<script type="text/javascript">
$(document).ready(function(){
$(".delsts").click(function(){
$(this).next(".detailbox").slideToggle('fast');
});
});
</script>
and php:
foreach ($data as $row) {
$status = $row['status'];
$fn = $row['firstname'];
$time =$row['posted_dt'];
echo "<div class='stsshown'>
<div class='upropic'></div>
<span class='uname'><a href='#'>".ucfirst($fn)."</a></span>
<span class='postdt'>".$time."</span><form action='#'><input type='button' value='x' class='delsts' title='remove from timeline' name='delsts'></form>
<div class='detailbox'>
asdasd
</div>
<div class='stsbox'>".$status."</div></div>";
}
I am trying for hours now and for some reason i can't find a solution for my problem.
The thing is, i need something like a div thats showing up when i click on an link.
That's working so far.
But the main problem is, that i need it work within a while loop. So i can get the data dynamically into grid, but all of the php created links have the same id and all of the "to-show-divs" show up at the same time. so my question is how can i create dynamic ids or classes and how do i get them to work within javascript?
echo "<div class='grid grid-pad'>";
$db=mysql_query("SELECT * FROM work") or die (mysql_error());
while($var=mysql_fetch_array($db))
{
echo "<div class='col-1-3'>
<div class='content'>
<div id='thumb' ><img alt='$var[id]' src='$var[thumb]'/></div>
<div class='menu' style='display: none;'>$var[link]</div>
</div>
</div>";
}
echo "</div>";
<script>
$(document).ready(function() {
$('#thumb').click(function() {
$('.menu').slideToggle("fast");
});
});
</script>
You can do what the comment suggests or just make an iterator variable and concat that to the id like so:
$index = 0;
while($var=mysql_fetch_array($db))
{
echo "<div class='col-1-3' id='item_". $index ."'>
<div class='content'>
<div id='thumb_". $index++ ."' >STUFF</div>
<div class='menu' style='display: none;'>$var[link]</div>
</div>
</div>";
}
Change <div id="thumb"> to <div class="thumb"> and then use following jQuery:
$('.thumb').click(function() {
$(this).next('.menu').slideToggle("fast");
});
Otherwise you'll have multiple elements with the ID "thumb", which you shouldn't.
Since the DIV is right after the link, you can use the JQuery function next() to get the next node after the link, which is the DIV:
$(document).ready(function() {
$('#thumb').on('click', function(e) {
// prevent IE from actually executing the href of the link
e.preventDefault();
// get next node, call the toggle.
$(this).next().slideToggle("fast");
// prevent executing of the href of the link
return false;
});
});
If you have more of these "thumb" links, please us a class instead of an ID - an ID has to be unique.
Edit:
Realizing that there actually are no links but DIVs, you can skip the "prevent executing" stuff of course.