I'm using PHP to echo out 50 video id's from an XML file. I use the video id's to embed 50 YouTube videos into my website. This works fine but I need to isolate the videos two at a time. I don't want the user to see all fifty videos at once. I want them to see two, then click next, see another two, then maybe click back, etc. etc.
Here's what I have so far:
$url = "http://www.theURLofmyXML.blah";
$xml = simplexml_load_file($url);
$i = 0;
while ($i < 49) {
$title = (string) $xml->query->results->item[$i]->title;
$videoid = (string) $xml->query->results->item[$i]->id;
$explanation = (string) $xml->query->results->item[$i]->explanation;
$i = $i + 1;
echo $title."<br />";
echo '<iframe width="400" height="225" src="http://www.youtube.com/embed/'.$videoid.'?rel=0&autohide=1&showinfo=0" frameborder="0" allowfullscreen></iframe><br/>';
echo $explanation."<br /><br />";
}
So I think the best thing to do is echo all fifty items to the page inside divs labeled 0 to 49...then use JavaScript to hide all divs except 0 and 1 until you click a next button and it switches to hiding everything except 2 and 3...and so on...
But I'm not sure how to do that in JavaScript/jQuery. I think using .show() and .hide() would work but I'm not sure of the syntax.
You can use the following HTML structure:
Previous videos
<div class="video-row active">
<!-- First couple videos -->
</div>
<!-- Loop through all videos, writing the other rows -->
<div class="video-row">
<!-- Last couple videos -->
</div>
Next videos
Note: Use the active class only in the first video row to show them by default on the page load.
With CSS, hide all .video-row (using: display:none;) and show only .video-row.active (using: display:block;).
Finally, use the following Javascript (jQuery needed) to navigate between video rows:
jQuery('.prev-video-row').click(function (event)
{
event.preventDefault();
var prev = jQuery('.video-row.active').prev();
if (prev.length)
{
jQuery('.video-row').removeClass('active');
prev.addClass('active');
}
});
jQuery('.next-video-row').click(function (event)
{
event.preventDefault();
var next = jQuery('.video-row.active').next();
if (next.length)
{
jQuery('.video-row').removeClass('active');
next.addClass('active');
}
});
Honestly speaking, I don't think it's great to have 50 videos embedding in a page - regardless of visibility or not; simply because they will be processed by the browser despite not being visible. (Feel free to correct me if I'm wrong, but the browser is going to see, and process, the whole DOM - and just apply the styles to the "hidden" bits.)
Gustavo Straube has given a really good answer on how to do this if you want to have 50 elements in the DOM despite the effects it may have on both browser and bandwith.
I'd probably go for something more along the lines of parsing the XML, storing all the data as JSON then dynamically updating the DOM with jQuery from HTML supplied with a templating framework like Mustache.js.
/* Generate JSON */
$url = "http://www.theURLofmyXML.blah";
$xml = simplexml_load_file($url);
$i = 0;
$json = array();
while ($i < 49) {
$arr['title'] = (string) $xml->query->results->item[$i]->title;
$arr['videoid'] = (string) $xml->query->results->item[$i]->id;
$arr['explanation'] = (string) $xml->query->results->item[$i]->explanation;
$json[] = $arr;
}
echo json_encode($json);
Then, in your markup have something like the below, just to initialise your first x videos - in this example 10..
$(document).ready(function(){
var template = '{{$title}}<br /><iframe width="400" height="225"'
+ 'src="http://www.youtube.com/embed/{{$videoid}}?rel=0&autohide=1&showinfo=0" frameborder="0" allowfullscreen></iframe><br/>'
+ '{{explanation}}<br /><br />';
var html = '';
var i=0;
for(; i<10; i++){
var item = json[i];
html += Mustache.to_html(template, item);
}
$('#videos').html(html); //where #videos is a div to contain your videos
Next up have an anchor (in this example #next) to get the next 10 videos..
$('#next').click(function(){
/* template, i and json are still in scope! */
var j = i+10;
for(; i<j; i++){
var item = json[i];
html += Mustache.to_html(template, item);
}
$('#videos').html(html); //where #videos is a div to contain your videos
});
The advantage of this is it's also easy to do a previous anchor...
$('#prev').click(function(){
/* template, i and json are still in scope! */
var j = i -10;
i -= 20; //10 for the current page, 10 for the start of the previous page
for(; i<j; i++){ //rebuild div content of previous page
var item = json[i];
html += Mustache.to_html(template, item);
}
$('#videos').html(html);
});
Just to re-iterate, this is an alternative solution - I've suggested it as using JSON is a little bit more lightweight and more flexible than XML, and it also removes the requirement for having 50 DOM elements that aren't in use at one time. There may be a reason you've chosen the implementation that you have, but it's not the implementation I would take if I was given this problem!
For html like:
<div id="section0"></div>
Your jquery would look like:
$(document).ready(function() {
$('#section0').show();
$('#section1').show();
$('#nextButton').click(function(e){
e.preventDefault();
$('#section0').hide();
$('#section1').hide();
$('#section2').show();
$('#section3').show();
return false;
}
});
And so on...
Related
After User Clicks Sumbit Button Data passes through one half of the path to images and then the code below links it to the second half. I want to know how I can display all this without Page Reload? I know it might be done with AJAX but I have no idea on how to do so. So please can someone help?
<?php
$albumnamepath = $_POST['field'];
echo $albumnamepath;
$display = "SELECT * FROM paths WHERE user_id = '$session_user_id' AND album_name = '$albumnamepath'";
$result = mysql_query($display);
echo "<table>";
$i = 0;
while ( $row = mysql_fetch_array($result) ) {
if ($i % 4 == 0) { //3 == 0.
echo '<tr>';
}
echo "<td>".'
<ul class="img-list">
<li><div class="picbox"><img src="'.$albumnamepath.$row['thumbnail'].'"><span class="text-content"><span>'.$row['caption'].'</span></span>'."</li>
</ul>
</td>";
//echo '<a href="'.$albumnamepath.$row['location'].'" class="swipebox" title="'.$row['caption'].'"><img src="'.$albumnamepath.$row['thumbnail'].'">';
if ($i % 4 == 3) { //3 == 2.
echo '</tr>';
}
$i++;
}
//Here is a check in case there is not a multiple of 3 images in a row.
if ($i % 4 != 0) { //4 != 0.
echo '</tr>';
}
echo "</table>";
?>
Thank you.
I don't think Ajax would help you very much, since you'll be using ajax to get, essentially, the entire page. Ajax is usually used if you want to change a part of the page, and the data either has to come from the server real-time (i.e. after the page is loaded), or is expensive to calculate or deliver in full (e.g. a very long, or infinite list, and if most users only use a small amount). Otherwise, it's more efficient to send all the data in one go, and then manipulate it in the browser.
I would suggest the following approach: divide the table rows into groups of table rows; e.g. 5 rows (chosen arbitrarily). Change the block of code where you echo '' to:
if ($i % 4 == 0) { //3 == 0.
$block=ceil($i/(4*5));
echo '<tr class="block_$block">';
}
This means each block of 5 rows (by 4 across) will be a different class - "block_1", "block_2" and so forth.
Then, you can hide and display blocks using Javascript. To hide a block, use the following javascript code:
var trToHide = document.getElementsByClassName("block_1");
for(var i = 0; i < trToHide.length; i++) {
trToHide[i].style.display="none";
}
To unhide a block:
var trToHide = document.getElementsByClassName("block_3");
for(var i = 0; i < trToHide.length; i++) {
trToHide[i].style.display="block";
}
Obviously, you will want to use variables to keep track of which block is displayed; then you can have a "Next" and "Back" button, which hides the current block, adds/subtracts one, then displays the (new) current block. You will also want to have all blocks except the first one hidden at the start. Left as an exercise to the reader.
Answer:
You have to use ajax request.
You use form to set filters? Then you can use .ajaxSumbit (but you need jQuery Form Plugin for it).
Also, you can add form submit handler, where you will prevent form default submit action and send ajax request instead of it. Look this example:
File getImages.php:
// in this file you will do same actions as you do now to output table with images
Note, that getImages.php must contain only table with results or message, that there are no results.
File with form, where you set filters:
// some html with forms etc
<form id='myForm'>
// some inputs etc
</form>
<div id='results'></div>
And javascript:
$("#myForm").submit(function(e) { // use e parameter for preventDefault();
$.ajax({
type: "POST",
url: "path/to/getImages.php",
data: $("#myForm").serialize(), // serializes the form's elements.
success: function(data)
{
$("#results").html(data);
}
});
return false; // <-- deny sumitting from and reloading page
//e.preventDefault(); // <-- this do same as `return false;` <-- deny sumitting from and reloading page
});
Explanation:
Browser load page with form, where you can set filters. User sets filters and pressing button submit. Browser will send ajax request to file getImages.php with some parameters (filters, user set filter before sending the form). This script generates some output with table, with img tags etc and return it. Browser receives this output and puts it to element with id #results:
<div id='results'></div>
^
------------------^
Data, generated by script getImages.php will be inserted here.
So, filtered images will be received and shown without page reload :)
Is it what you need?
Hope this will help you.
So I have a php array that I am JSON encoding and handing to some JQuery. Basically I am using the information from the array to dynamically change the content of one drop down based on the value of another drop down. I am running into some problems with the JQuery though as JQuery is pretty new to me.
First off my PHP:
<?php
$sql = mysql_query("SELECT * FROM menu") or die(mysql_error());
$menuItems = array();
$x = 0;
while($row = mysql_fetch_object($sql))
{
$menuItems[$x]['ID'] = $row->ID;
$menuItems[$x]['parent'] = $row->parent;
$menuItems[$x]['name'] = $row->Name;
$menuItems[$x]['header'] = $row->header;
$menuItems[$x]['Sort'] = $row->sort;
$x++;
}
?>
This code returns an array of ~30 menu items.
Then my JQuery:
<script>
var menuItems = <?php echo json_encode($menuItems); ?>;
$('#dropdown1').change(function (){
if($('#dropdown1').val() == 0){
$('dropdown2').children().remove().end()
for(var x = 0; x < menuItems.length; x++){
if(menuItems[x]['header'] == 1){
$('#dropdown2').options[menuItems[x]['sort']] = new Option(menuItems[x]['name'], menuItems[x]['sort']);
}
}
}
});
</script>
What I want this to do is when dropdown1 is changed, dropdown2's options are removed and then repopulated with specific things from the array.
Currently this code does delete the options for dropdown2 when dropdown1 is changed but re-population just isn't working. From what I can tell in testing, the for loop to iterate through the array is only entered once, despite their being about 30 items in it and I assume that is were my main problem is.
What am I doing wrong here?
change it to
for(var x = 0; x < menuItems.length; x++){
if(menuItems[x]['header'] == 1){
var option = $('<option />', {
text : menuItems[x]['name'],
value: menuItems[x]['sort']
});
$('#dropdown2 option[value="'+[menuItems[x]['sort']]+'"]').replaceWith(option);
}
}
$('#dropdown2').options[] is not valid, as jQuery doesn't have those methods, that's for plain JS DOM nodes.
So from the comments there seemed to be some confusion on what I meant, and I apologize. It was one of the instances where the explanation made sense to me, but I just must not have conveyed everything well enough.
To clear up a little bit of the confusion. The array that was passed from the PHP code to the javascript contained everything I could ever need for the second drop-down.
As many pointed out the .options[] was the culprit for why the code wasn't executing. This was simply from another example I had found, and with my limited knowledge I assumed it was correct, and it wasn't.
I instead used the the .append() function and things seem to be working normally now.
I have a form that I set up for staff to fill out when ordering spray paint for our company. This form is submitted to a PHP page which shows the results of the order form and allows the user to print however. It also prints the print button as well as the URL to the page. How can I make it print without these two things? This is the code I am using inside the style tag...
#media print {
.hide-on-print { display:none; }
}
And this is my print button...
echo '<br /><br />Print';
Thanks for the help!
You can't hide the URL or any other header or footer text. These are settings controlled by the browser and are not accessible via any API. Ultimately it is up to the user to decide whether they are printed or not.
You can hide the print button by using display:none for that element in the print CSS for that page.
Recently I have seen here this similar question. If you want to get rid of the URL address, you can create a new window, copy the printable content there and print the new window, then close it. Then the original address will be replaced by the about:blank.
function printpage() {
var styles = document.getElementsByTagName('style');
var style = '';
for (var i=0; i<styles.length; i++) {
style += styles[i].innerHTML;
}
var data = document.getElementById('print_content').innerHTML;
data += '<br/><button onclick="window.print()" class="noprint">Print the Report</button>';
data += '<br/><button onclick="window.close()" class="noprint">Close Preview</button>';
data += '<style type="text/css" media="print"> .noprint {visibility: hidden;}</style><style type="text/css">'+ style +' </style>';
myWindow = window.open('', '', 'width=800,height=600');
myWindow.innerWidth = screen.width;
myWindow.innerHeight = screen.height;
myWindow.screenX = 0;
myWindow.screenY = 0;
myWindow.document.body.innerHTML = data;
myWindow.focus();
}
jsfiddle code + result page (works with IE7+)
I am generating divs in PHP, from an array, thus:
echo "<div id='parentdiv'>";
for($counter = 0; $counter < count($list); $counter++){
echo "<div>".$list['important_info']."</div>";
}
echo "</div>";//parentdiv
I want to add some click functionality to each div independently, i.e. the action performed on clicking depends on the div, and more importantly the index of the array, $list;
I want to give each div an id based on it's index in the PHP array.
So I could do
echo "<div id='"."divindex_".$counter."'>".$list['important_info']."</div>";
where "divindex_" is just used to prevent the id form beginning with a numeric value.
Then, I think in jQuery I can write click functions for each div.
However the problem is the $list size is variable, so I don't know how many divs there are.
So what I'm thinking is something like,
$("#parentdiv div").click(function(){
var id = split($(this).attr('id').split("_")[1];//get the php index from the id
//do something with the id, e.g. ajax or whatever
});
Is there a better way to do this? If you think what I'm doing is strange and not a very good idea, then I understand. But I don't know how to do this any other way. Any help appreciated.
Simply use:
$("#parentdiv div").click(function(){
var id = $(this).index(); //index of div, 0 based
var val = $(this).text(); //content of div, if you need it
});
No need to add unique IDs :) .
Demo:
http://jsfiddle.net/q9TaJ/
Docs:
http://api.jquery.com/index/
First, make sure to properly escape your outputs:
echo '<div id="parentdiv">';
for ($counter = 0; $counter < count($list); $counter++){
echo sprintf('<div data-id="%d">%s</div>',
$counter,
htmlspecialchars($list['important_info'])
);
}
echo '</div>';//parentdiv
I'm also using a special attribute called data-id which you can easily access in jQuery with this code:
$('#parentdiv > div').on('click', function() {
var id = $(this).data('id');
});
you can pass your variables as html attributes. Then bind the click event to a single class.
<div class="divs" data-id="myid"></div>
in jquery
$('.divs').click(function(){
console.log($(this).data('id));
});
I searched, but did not find the answer to this.
I have a website that displays hundreds of images in thumbnail format. I'm currently using php to display all of the images in thumbnail, then when the thumbnail is clicked upon to display the images in full-size.
What I would like to do is be able to click on a thumbnail and see the resulting full-size image, then at that point be able to scroll both back and forth through the full-size images without going back to the thumbnails.
As an added feature, when viewing the thumbnails, I would like to only load the ones that are currently displayed on the client page...ie - if the client screen resolution supports 20, then load only 20 and wait to load the rest on the client until the user scrolls down. The primary client in this use case is an iphone.
Thanks in advance!
you need to use a slider jquery plugin
Like
Jquery Light Box Plugin
When you click on the image, it should point to a new PHP file containing the full size image, or even better, load it in a new <div> with php you can get the client resolution with other tools
You actual have two seperate questions. One is to show the thumbs fullsize and be able to click to the next image. Almost every plugin to show images has that options. Personally i use fancybox, but pick anyone you like. To enable the next/prev buttons you need to group the images useing the rel tag.
Now to load the images per page, similar to google does it, you need to load it all in by javascript. Below is a setup of how you could do it. This is untested, as I did not have an image gallery at hand.
In the code below I load all images into the array at once, which is not perfect when you have a lot of images (like 1000+). In that case your better of using AJAX to load a new page. But if you have a smaller amount of images, this will be faster.
<script>
//simple JS class to store thumn and fullimage url
function MyImage(thumbnail, fullimage, imgtitle) {
this.thumb = thumbnail;
this.full = fullimage;
this.title = imgtitle;
}
//array that holds all the images
var imagesArray = new Array();
var currentImage = 0;
<?php
//use php code to loop trough your images and store them in the array
//query code to fetch images
//each row like $row['thumb'] and $row['full'] and $row['title'];
while ($row = mysqli_fetch_assoc($result))
{
echo "imagesArray.push(new MyImage('".$row['thumb']."', '".$row['full']."', '".$row['title']."'));";
}
?>
//the thumb width is the width of the full container incl. padding
//In this case I want to use 50x50 images and have 10px on the right and at the bottom. Which results in 60x60
var thumbWidth = 60;
var thumbHeight = 60;
var screenWidth = $('body').width();
var screenHeight = $('body').height();
var maxImagesPerRow = Math.round(screenWidth / thumbWidth);
var maxImagesPerCol = Math.round(screenHeight / thumbHeight);
var totalImagesPerPage = maxImagesPerRow * maxImagesPerCol;
//function to load a new page
//assuming you use jquery
function loadNextPage() {
var start = currentImage;
var end = currentImage + totalImagesPerPage;
if (end >= imagesArray.length) {
end = imagesArray.length - 1;
}
if (end<=start)
return; //last images loaded
$container = $('#thumbnailContainer'); //save to var for speed
$page = $('<div></div>'); //use a new container, not on stage, to prevent the dom for reloading everything on each iteration of the loop
for (start;start<=end;start++) {
//add a new thumbnail to the page
$page.append('<div style="margin:0;padding:0 10px 10px 0;"><a class="fancybox" rel="mygallery" href="'+imagesArray[start].full+'" title="'+imagesArray[start].title+'"><img src="'+imagesArray[start].thumb+'" alt="" /></a></div>');
}
currentImage = start;
//when all images are added to the page, add the page to the container.
$container.append($page);
}
$(function() {
//when loading ready, load the first page
loadNextPage();
});
//function to check if we need to load a new page
function checkScroll() {
var fromTop = $('body').scrollTop();
//page with a 1-based index
var page = 1 + Math.round(fromTop / screenHeight);
var loadedImages = page*totalImagesPerPage;
if (loadedImages==currentImage) {
//we are scrolling the last loaded page
//load a new page
loadNextPage();
}
}
window.onscroll = checkScroll;
</script>
<body>
<div id='thumbnailContainer'></div>
</body>