I have a list of divs created using a while-loop
while($row = mysql_fetch_array($result)){
$output = "<div id='drag'>$row[id] - $row[name] - $row['email']</div>";
echo $output;}
When I try to make those divs highlighted for a few seconds.
Only the first div seems to be reacting.
$("#drag").effect("highlight", {}, 2000);
Is there any strategy to make all the output be highlighted this way? And is there a way to make a certain div or divs highlighted?
IDs must be unique by definition. You can use classes instead.
while($row = mysql_fetch_array($result)){
$output = "<div class='drag'>$row[id] - $row[name] - $row['email']</div>";
echo $output;
}
Then...
$(".drag").effect("highlight", {}, 2000);
id is used to give a div unique id. so in the while loop you are giving same id in the loop to all div. that's why when you are trying to highlight, it is effecting first div.
try this code:
while($row = mysql_fetch_array($result)){
$output = "<div class='drag'>$row[id] - $row[name] - $row['email']</div>";
echo $output;
}
after that apply effect to that class drag
$(".drag").effect("highlight", {}, 2000);
hope it will help you :)
Using multiple items in a page with the same id is disallowed and, though it may work for some use cases, will cause problems in others (as you're seeing). In general, you'll want to use classes unless ids are required. I'd also recommend that you specify the selector more distinctly that you would with the id (ie, more elements).
For my own code, I tend to use an id for the page body (ie, which page it is) and distinct elements on the page (header content, main content, right rail content, footer content). It's rare that I use ids anywhere else (though it's been known to happen).
Once you switch it over to a class, you can easily change your JS to do something like
$("div.drag").effect("highlight", {}, 2000);
If possible, adding something more distinct to the div.drag path so that you won't wind up effecting other parts of the page you hadn't considered/written when you worked on this.
Related
I created a page which gets filled by a php databasequery (all rows are being read from the MySQL-table and written to the table in HTML). All 10 seconds the same PHP-script gets requested by jQuery AJAX and should refresh the current table content. The return-value of this function will then be used to change the table HTML-value.
There are some buttons in the table. When they're clicked, they toggle from on to off (or vice versa) and another PHP-file gets called with AJAX, which then controls 433MHz wireless sockets via shell commands. Purpose of these 10-seconds ajax-refresh is to synchronize the button with the actual state of the electrical socket (which is saved in the MySQL-database).
$(document).ready(function(){
$(".toggle").click(function() {
if($(this).hasClass("ein")) {
$(this).removeClass("ein");
$(this).html("aus");
$.post("various/executeCode.php", {transmitted:true, id:$(this).attr('id'), toggle:'0'}, function(result) {
});
} else {
$(this).addClass("ein");
$(this).html("ein");
$.post("various/executeCode.php", {transmitted:true, id:$(this).attr('id'), toggle:'1'}, function(result) {
});
}
});
});
window.setInterval("reloadPage()", 5000);
function reloadPage()
{
$.get('various/reloadPage.php', function(data) {
$("#content").html(data);
});
}
$stmt = $dbh->query("SELECT * FROM `funksteckdosen`");
$row = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($row as $r)
{
echo "<tr>";
echo " <td>" . $r['name'] . "</td>";
echo " <td><button id='" . $r['id'] . "' class='toggle" . ($r['toggle'] == 0 ? "" : " ein") . "'>"
. ($r['toggle'] == 0 ? "aus" : " ein") . "</button></td>";
echo "</tr>";
}
Now I have the following problem: As soon as the page gets refreshed by AJAX the first time, the buttons stop working. Javascript doesn't execute the click()-function anymore. Why is that?
Problem 2:
The content of the table gets deleted and replaced by the new one. Am I somehow possible to fade new lines (or the button background-color) in, instead of just showing them? That would be the final touch.
I hope you understood my explanations.
The click handlers don't work anymore because the new buttons never had the handlers attached to them. When you attach a handler like this:
$(".toggle").click(function() {
What jQuery does is find all of the currently existing .toggle elements and, for each one, add that function as a handler. Since the new ones are added later via an AJAX call, they're not included in that set and, thus, never have that function attached to them.
The way jQuery address this is with the .on() function. The structure of using is it very similar:
$('body').on('.toggle', 'click', function() {
The difference here is the element which is actually getting the click event bound to the function. With this, the click event is actually being added to the body tag, which isn't changing from the AJAX call. Any unchanging common parent for the dynamic elements will work, 'body' and document are usually used as defaults since they're pretty top-level.
When any child element raises a click event, that event continues up all of the parent elements. So it eventually reaches a common parent, such as 'body'. The .on() function then also has a second selector as its first argument. That selector filters the originating elements of the click event before calling the function.
Benefits of using this approach include:
There's only one event handler function attached to a single common parent, instead of many attached to many elements, which can be a performance improvement on large or complex pages.
Child elements added to the common parent element later in the page's lifespan are still handled, since they will still send their click events to the parent regardless of when they were added. (This is the immediate benefit in your situation.)
As for fading in the content, if I understand the effect you're looking to achieve, you can try something like fading out what's already there, removing it, adding the new content, and then fading it in. Maybe something like this:
$.get('various/reloadPage.php', function(data) {
$('#content').fadeOut(400, function() {
$("#content").html(data);
$('#content').fadeIn();
});
});
There might be newer structures to accomplish this same thing with the relatively newer "promises" model, but essentially what this does is fade the content out and then include a call-back function to call when it's finished fading out. That call-back function replaces the HTML and then fades it back in. Depending on the structure of your HTML you might need to fade out/in a parent element instead of the one I'm targeting, but hopefully you get the idea here and can tweak it until it looks right.
Problem 1: The click event handler is bound to the initial toggle class elements but dynamically created events are not bound.
Try using live() or on() to bind dynamically created elements. See: Event binding on dynamically created elements?
Problem 2: #content is replaced when using html()
Try using append() to add data into an existing element. Using html() will replace the contents of the element.
I have chained a hide() and a fadeIn() to animate the append.
$('#content').append(data).hide().fadeIn(1000);
I’ve just started learning PHP and have attempting to build my first data driven web page to aid with my learning but I now seem to have come across a problem that's been driving me nuts.
Here is a bit of background.
What I have been attempting to do is pull content from a database, this content is already marked up with html paragraph tags. The content will be user submitted and so I have no way of knowing how many paragraphs each row will contain.
I am then looping through the content and counting the paragraphs so that I end up with 5 paragraphs inside each containing div.
Here is the code I am using to do this, I know my code is a bit basic but it seems to work fine as long as all of the content is retrieved in just a single query.
$stmt = $db->prepare('SELECT * FROM content');
$stmt->execute();
foreach($stmt as $row) {
$allParagraphs .= $row['content'];
}
$paragraphArray = explode("</p>", $allParagraphs);
$paragraphCount = 0;
echo '<div class="bookPage">';
foreach ($paragraphArray as $value) {
echo $value;
$paragraphCount = $paragraphCount + 1;
if ($paragraphCount == 5){
echo '</div><div class="bookPage">';
$paragraphCount = 0;
}
}
echo '</div>';
And now my problem.
Now I would like to include pagination with an endless scroll effect using PHP and Jquery. I feel confident enough to do this; however, I have noticed that the current code I am using (to count every 5 paragraphs) is not going to work when I introduce pagination.
As far as I can see, after working through the code what is going to happen is that the closing div is going to be inserted and then, when the 2nd query made via ajax (read more link clicked) it is going to result in a new opening div. This results in the leftover paragraphs from each query being surrounded by the div tag and not containing the 5 paragraphs I need.
Basically, in its simplest terms, what I would like to do is to still be able to wrap div tags around every 5 paragraphs but also still be able to paginate the results via ajax.
If anyone could advise me of the best way to go with this it would be very much appreciated.
My musings on this issue so far...
I am not sure if this is even possible to do which leads me to believe I have approached this the wrong way. I’m not very experienced at the moment but I can’t help think that it would be easier to store every paragraph in a separate row in the database which would allow me to then pull them out in multiples of 5. But then, something else is telling me that would not be a practical solution at all, especially as I have no way of knowing how many paragraphs each user would be writing/submitting.
I dont have enough points to post an image so here is a link to an image i uploaded in attempt to demonstrate what i mean should my attempt at describing the issue not be enough.
Diagram showing issue
Thank you in advance of any suggestions.
I guess you could remove all the HTML tags in your PHP script and just return the content of the paragraphs as JSON object, for example.
So, basically, you'd return something like:
echo json_encode($paragraphArray);
And request that with jQuery like this (which is an adoption of the first example at http://api.jquery.com/jQuery.getJSON/):
jQuery.getJSON('yourURL.php', function(data) {
var items = [];
jQuery.each(data, function(key, val) {
items.push('<p>' + val + '</p>');
if(items.length == 5) {
appendItemsToBody(items);
items = [];
}
});
appendItemsToBody(items);
});
function appendItemsToBody(items) {
if(items.length) {
jQuery('<div/>', {
'class': bookPage,
html: items.join('')
}).appendTo('body');
}
}
Depending on what should happen when clicking on "load more", you could pass the count of currently displayed items as data to the call to your PHP script via jQuery.getJSON() (see their API documentation) and then decide in your PHP script which paragraphs you should return (i.e. where to start from). You'd have to append the "rest" of the paragraphs to fill up the 5 items to the existing last div in jQuery, and put the rest into new divs.
I got this script:
<script>
$('#zoom_01').elevateZoom({});
</script>
Where #zoom_01 is an ID of an image. I have many images with ID's like so:
zoom_01
zoom_02
zoom_03
zoom_04
and so on
How do i make so that javascript would take all ID's instead of one?
I was thinking something like this:
<script>
<?php
foreach ($ArrayAllOfIDs as $i) {
$('#<?php echo $i; } ?>').elevateZoom({});
}
?>
</script>
But it didnt work.
Although using the class attribute as mentioned above is probably your best bet, if you are forced to work with the IDs for whatever reason You can use a "starts with" selector like
$("[id^=zoom_]").elevateZoom({})
which will apply elevateZoom to all DOM elements with an id that starts with "zoom_".
Add a class to all the images that would be affected at the same time.
Ids are used to identify a unique, non repeating item. Since your images are all pretty much the same, a class can group them together.
Then, change your javascript to select the class.
$('.zoom').elevateZoom({});
I don't know what elevateZoom is, but you can likely have this syntax:
$('#zoom_01, #zoom_02, #zoom_03, ...').elevateZoom({});
Make the PHP write out the Javascript so it is available when the page is loaded in the browser.
<script>
<?php
foreach ($ArrayAllOfIDs as $i) {
echo '$(\'#zoom_'. $i .'} \').elevateZoom({});\n';
}
?>
</script>
I've been working on a program to draw cards. I have 54 cards and I want to have them drawn individually. Here's what I've gotten so far. It reads an array, shuffles it, resets it, and then places them with a foreach.
<?
session_start();
include "array.php";
shuffle($cards);
reset($cards);
$i = 1;
foreach($cards as $card){
print <<<HERE
<div id="$i">\n<img src="img/{$card[1]}.gif" alt="{$card[0]}" width="176" height="276"/><br/>
<h1 style="font-family: sans-serif;">{$card[0]}</h1>\n</div><br />\n\n
HERE;
$i++;
}
?>
Each result of each card comes out as this:
<div id="1">
<img src="img/#.gif" alt="Card Name #" width="176" height="276"/><br/>
<h1 style="font-family: sans-serif;">Card Name #</h1>
</div><br />
In array.php, there is a 2-dimensional array which holds the paths and names of each card. For example:
$array = array();
$array[] = array("Card Name 1", "1");
$array[] = array("Card Name 2", "2");
$array[] ...
Anyways, I'm new at jquery and I need help into creating an animation which shows a card and changes the picture for every click in the order which it outputs until it runs out.
How can I create this animation? Do I need to change my code completely to accomplish this? Is there an easier method?
Thanks in advance!
There are lots of ways to do this, but here's the first that came to mind:
$(document).ready(function(){
var i=0,
$cards = $("div").hide();
$cards.click(function(){
$cards.eq(i).slideUp(function() {
i = (i+1)%$cards.length;
$cards.eq(i).slideDown();
});
}).eq(0).slideDown();
});
You should assign your card divs a common class and change the jQuery selector to use it, e.g., $("div.card"), but the general idea is select all the card divs and hide them, show the first, and on click of whichever one is showing hide it and show the next.
I've coded the above to keep looping around, but you can add your own end-of-deck actions as required.
Demo: http://jsfiddle.net/FrrhZ/
jQuery provides a number of animation methods, and you can make the animation as complicated as you like, but for demo purposes I just went with .slideUp() and .slideDown().
By the way, I'd remove the <br> elements from between your individual divs. You don't need them if only one card is displayed at a time, but even to display multiple cards divs are block elements and will display one under then other by default - if you need more spacing set the margins via CSS rather than adding spacer elements.
For your each individual div set opacity 0 and give class="card"
Then use this function
$(document).ready(function()
{
$(".card").animate({opacity:"1"});
});
Ex: http://jsfiddle.net/FrrhZ/10/
The $(".card") is a jQuery selector to get all elements with class ".card". The above will show each card appearing from nowhere, a cool effect.
This is just an example, you can do many more things with jQuery animate(), have a look http://api.jquery.com/animate/
For example, you can set the speed like this
$(".card").animate({opacity:"1"}, 1000);//animation to be completed in 1000 miliseconds.
Or you can show a metro like animation where the entity goes a little up while appearing, to do that add margin-top:10px and opacity:0 to your divs and then use this function
$(document).ready(function anim()
{
$(".card").animate({opacity:"1", marginTop:"0px"}, 'slow');//animate also excepts some keywords for speed like 'slow', 'fast'
});
Ex: http://jsfiddle.net/FrrhZ/14/
You can get even more creative with animate(), these were just few of many things possible with jQuery animate(), you can even chain animations, everything is provided in the link. Go ahead and explore.
I have an HTML div:
<div id='text_icon_<?php $i++; ?>' class="text_icon">Some Text</div>
that I print inside a foreach loop. I am using ajax to handle the click() event on it and change its text to Done!, so I have an output like:
<div class="text">Done!</div>
If I run the loop 4 times and I click on one of the divs (i.e. the one with class text_icon) then only first one is working while the rest of the divs are not working.
Update:
Your update indicates the below is not the problem, the IDs are unique.
Without your jQuery code it's hard to help you debug, so here's an example of how it can be done:
HTML:
<div id='text_icon1' class='text_icon'>Div #1</div>
<div id='text_icon2' class='text_icon'>Div #2</div>
<div id='text_icon3' class='text_icon'>Div #3</div>
<div id='text_icon4' class='text_icon'>Div #4</div>
JavaScript code using jQuery:
$("div.text_icon").click(function() {
// Within the `click` handler, `this` points to the
// DOM element. If you're kicking off some ajax something,
// you'll probably be doing something like this:
// Grab `this` to a variable we can access from the
// `success` closure
var theDiv = this;
// Do our call
$.ajax({
url: "your_url_here",
success: function() {
// It worked, udate the div
$(theDiv).text("Done!");
}
});
});
Live copy
Original answer:
If you're really using "DIV id='text_icon' class="text_icon..../DIV", e.g.:
<DIV id='text_icon' class="text_icon">....</DIV>
...then the problem is that the id is not unique. ID values must be unique on the page (reference). That would seem to fit with the symptom you describe, with "only the first one" working. Most browsers, when given invalid HTML with multiple IDs, will use the ID on the first element in document order and ignore the remaining ones.
If you don't need the div to have an ID at all, you can just remove it. Otherwise, just ensure the ID is unique, e.g.:
<DIV id='text_icon1' class="text_icon">....</DIV>
<DIV id='text_icon2' class="text_icon">....</DIV>
<DIV id='text_icon3' class="text_icon">....</DIV>
<DIV id='text_icon4' class="text_icon">....</DIV>
As far as I can tell, you are giving your divs the same ID. Targetting multiple elements with the same ID is impossible, the IDs need to be unique.
Try this:
$i = 1;
foreach ($array as $al) {
echo "<div id='text_icon_$i'>blablabla</div>";
$i++;
}
Of course, you'll need to modify your jQuery code too to include a potentially unlimited number of such IDs (I don't know whether performance will be good this way, but I remember doing it once for a comments list on a blog).
Another way would be to use a common class rather than unique IDs :).
Apart from the arguments about unique IDs, could it also be that the click handlers need to be hooked up again after the ajax call? If so, it'd be better to use .live rather than .click.
$("div.text_icon").live("click",
function(event) {
var icon = $(this);
}
}