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.
Related
When a user selects a word in a text on my website (PHP), and then right clicks, i want a jQuery context menu to come up, this can be done by using one of the already existing jQuery context menu plugins.
But besides the options like copy / paste / cut, etc. I also want something to be done with the selected word using PHP. Which, i think, is a little harder.
For example using this script:
$selection = //the selected word or text
$target = //fetch from MYSQL database
$output = array();
while ($row = //fetch $target) {
If ($selection == $row->input) { array_push($output,$row->output); }
}
echo '//menu '.print_r($output).''; // of course not print_r! Just for the example's sake.
Databse example:
(Sorry for the oversized image)
Ok so selecting the word 'lazy' in the example text, and then right clicking, the jQuery box should pop up showing the results from the database extracted by PHP.
Example:
Ok, so i know you can't just combine javascript with PHP and it can only be parsed, but i thought loading an iframe withing the menu, which does the database extraction would do the job by using javascript to set the iframe src containing the selected word in the url.
However, iFrames are not really a nice way to solve this.
The question: How can i do this effectively? Execute this script on right-click and show the database-related content in the menu?
I would need to know the plugin you're using to give you some code examples but, general, I would go about this like this:
There has to be a click handler on the items in the jQuery context menu. Use it to submit an AJAX request to the server when the "selection" term is clicked.
Make sure to give the user some feedback (a loader or spinner)
Put the results into an array server-side.
JSON encode the array and send it as the response (e.g. echo json_encode($output)
JSON.parse(response) on client-side and you now have a JS object with the results
Put those results in the context menu (again, how depends on the plugin you're using)
AJAX is a great way to do what you want.
Here is a simple AJAX example. Note that in the 2nd .PHP file, that is where you put your database lookup etc.
Whatever you echo from the 2nd script is received by the calling javascript (first script again) and can be inserted into your context menu on-the-fly. Here is another example with a very detailed, step-by-step explanation of the process at the bottom of the answer.
I think you have to use Ajax to get JSON from a PHP file, which you would process on the actual page.
I you create a PHP file called test.php, with the following in it:
<?php
echo json_encode(array('time' => time(), 'hour', date('H')));
?>
Then the Javascript:
<script>
$('#curr_menu_entry').click(function() {
$.getJSON('test.php', function(data) {
$.each(data, function(key, val) {
$('#curr_menu_entry').append('<li id="' + key + '">' + val + '</li>');
});
});
});
</script>
Would that work?
I have a jQuery autocomplete script in my page, and if I type in the field it works on, and as requested after 3 characters, the drop containing the expected number of suggestions pops down...sort of...as there is no text in the drop down.
If I mouse over the drop down as though I were selecting one of the suggestions, a narrow bar shows a highlight for each row where a suggestion would be, but selection of one of the empty highlights empties the field. This is not surprising. I don't really understand the handling of the return data. I have seen very simple and complex code in autocomplete examples in other posts in these forums, but using the ones I thought I understood has usually broken it to the point where I don't get the drop down at all. Thus I'm unashamedly looking for someone to provide me with the code that works so I can pick it apart and work out how it works.
My basic JS code is:
$("#tf_txt_CLIENTNAME").autocomplete({
source: "search.php",
minLength: 3,//search after three characters
dataType: 'json',
select: function(event,ui){
//do domething
}
It's the do something area I just can't get right. As I said, I've tried too many variations of code in that space to mention here, and all of them broke it completely.
search.php produces the following JSON output for input of 'bra':
[{"txt_CLIENTNAME":"Braedon"},{"txt_CLIENTNAME":"Bradly"}]
from the following PHP source (borrowed and modified from another web source):
<?php
require_once 'includes/dbiconnect.php';
require_once 'includes/sqlfunctions.php';
$term = trim(strip_tags(addslashes($_GET['term']))); //retrieve the search term that autocomplete sends
$qstring = "SELECT `txt_CLIENTNAME` FROM `tbl_client_details` WHERE `txt_CLIENTNAME` LIKE '%".$term."%'";
$result = mysqli_query($db_link,$qstring); //query the database for entries containing the term
while ($row = mysqli_fetch_assoc($result)) {//loop through the retrieved values
$row['txt_CLIENTNAME']=htmlentities(stripslashes($row['txt_CLIENTNAME']));
$row_set[] = $row; //build an array
}
echo json_encode($row_set); //format the array into json data
?>
I simply would like it to display what it finds and plonk the one I select into the value of the text field. I can then update the other fields I want to populate (company, phone # & e-mail) using $.POST triggered by the onchange event for that field (I'm sure there are better ways to do that, but I understand how to do that for the moment).
I'm using jQuery 1.7.2 and jQuery UI 1.8.22. I have the latest jquery toolbox loading as well without the tabs component, but removing it has made no difference.
Thanks in advance,
Braedon
As per Jquery UI guide,
your JSON needs to contain label or value (or both)
You need to change your json as below
while ($row = mysqli_fetch_assoc($result)) {//loop through the retrieved values
$row['txt_CLIENTNAME']=htmlentities(stripslashes($row['txt_CLIENTNAME']));
$row_set[] = array('label'=>'txt_CLIENTNAME','value'=>$row['txt_CLIENTNAME']); //build an array
}
On my website an user is able to fill in an url. When he fills in the url, he gets all the images src's from that url. I push these src's to an array in php:
array_push($goodfiles,$pic);
Now the user will be able to choose on of the pictures (with a next or prev button) and then save it to the database. The picture that's saved is based on the id of the image in the array. So $goodfiles['0'] means id = "0" and so on.
I want the swapping of the images to work with ajax, so that the pages doesn't have to refresh all the time when clicking the next or previous button. And then when I save the form, I want to know the id of the current image, so that I can save it to the database.
How do I realize this with Ajax (jquery)?
Edit:
This is how I do it right now:
$current_id = $_GET['id'];
if(empty($_GET['id']) || !empty($empty)) { $current_id = 0; }
$prev_id = $_GET['id'] - 1;
if($prev_id < 0){ $prev_id = 0;}
$next_id = $_GET['id'] + 1;
if($next_id > $_SESSION['count']-1 && $_SESSION['count'] != 'empty') { $next_id = $_SESSION['count']-1;}
This is the code for the pagination
And this is the pagination:
<div id="url_pic">
<img src="<?=$_SESSION['pictures'][$current_id]?>" class="img_load"><br>
<? if($_SESSION['count'] > 1) { ?><center><img src="img/add/left.png"> <img src="img/add/right.png"></center> <? } ?>
</div>
So right now my solution doesn't contain any javascript, but it's all php coded. And the page refreshes everytime you want to see the next picture. I want to solve this in ajax, so that you can paginate through the images without a refresh. The way I want it is like this link:
http://d-scribe.de/webtools/jquery-pagination/demo/demo_options.htm
But except for the text, I want to paginate through images.
You probably don't need to use AJAX for this. Simply return a html file containing a JavaScript array, which contains all those image URLs and do the other stuff using JavaScript.
Get back to StackOverflow in case you've a more precise question and hopefully some code, which we can help on ;)
Load a script at the bottom of your php page the user side of the PHP where all your HTML is, above the closing body tag thats something loosely similar to this
<script type="text/javascript">
var myArray = <?php echo json_encode($myPHParray); ?>
</script>
this way when your page loads out it renders with a dynamic javascript json object as a variable that you can work with client side, this removes the need for an AJAX request all together unless your doing stuff with the data your playing with. From first glance Im guessing not really per say. But yea, at the very least its one less transaction to be made when the page is loading.
edit just noticed someone said similar while I was typing out.. Lars.. so I guess this is a follow up to his answer :-D
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.
Specific questions are at the end of this (very long) pre-amble. Sorry, I tried to make it as short as poss. (took over an hour to write the question).
A .php file uses a (php) function to read rows in a SQL db and dynamically create an HTML table.
For each row, the SQL data is returned via $book['id'], $book['code'], $book['description'], etc.
The $book['code'] is a two-char alpha-numeric ID, eg. B7 or DW
In the HTML for each row is a <td></td> containing an anchor tag with an onclick= event that runs a JQuery script (to show/hide elements for that row).
Suppose a couple or rows were clicked and a couple of elements were hidden by the embedded JQuery script (which is working correctly, by the way)
When the user views a different page and then returns to this one, hidden elements (that were hidden by the JQuery script) are no longer hidden.
I wish to preserve a string of $book['code'] values for each clicked row an d, upon return to the first page, parse that string to reset the hidden elements.
<?php
function render_row_from_mysql() {
$output .= '
...create header row...
foreach ($books as $book)
{
create table row cells 1, 2, 3, 4
after cell 4:
<td>
<a id="addToShelf.php" onclick="
jQuery.ajax(\'./addToShelf.php?id='.$book['id'].'ats'.'\');
jQuery(addToShelfLink'.$book['id'].')[0].style.display = \'none\';
jQuery(rfs'.$book['id'].')[0].style.display = \'block\';
jQuery(mt'.$book['id'].')[0].style.display = \'none\';
jQuery(grn'.$book['id'].')[0].style.display = \'block\';
return false;
">
add to bookshelf
</a>
</td></tr>' ;
}
}
Questions:
Why doesn't the JQuery code above, which works correctly, need closing parentheses?
What is the syntax for creating/updating a var, in the anchor tag, that would preserve the cumulative clicked-row data? I ask because my many attempts all break the code.
Should the var be initialized at the top of the function, before the foreach loop?
I tried using PHP to create/update a cookie by inserting the following code after "return false;" (see below). The below php code does create a cookie when pasted into a separate script for testing.) The php code does not fire. Why?
The answers are:
1) Still not sure, just syntax.
2) As mentioned in Q4, I had been entering code AFTER the "return false;" statement, which is what concludes the onclick event. Therefore, any code placed after "return false;" would not fire as part of the onclick event... and there was nothing else to MAKE it fire.
3) Irrelevant
4a.) The above code is created within a PHP code block -- one cannot create a PHP code block inside JQuery inside HTML that is being created by (i.e. already inside) PHP.
4b.) Further to answer (2), my alert() tests would not fire because they followed the "return false;" statement,
4c.) Any new PHP code must be moved out of the HTML and placed back with the rest of the PHP, such as above the function(render_row_from_mysql){}.
It is now "back to the drawing board" to figure out how to preserve the "clicked items" data between when a user leaves this page and when he returns back to it. At this time, I suspect that will be some kind of a FORM $POST event, but having never done one before I'm not sure what that will look like.
I completely agree with Bjorn comment from 22 minutes ago. You need to remove all that onclick code and add a identifying class to your anchor tags. You sure also make sure that each HTML element has a unique id, it is a W3C validation requirement. If each book's id is unique system wide I would use that, see Example below:
<?php
function render_row_from_mysql() {
$output .= '
foreach ($books as $book)
{
//create table row cells 1, 2, 3, 4
//after cell 4:
<td>
<a id="'.$book['id'].'" class="addToShelf">
add to bookshelf
</a>
</td></tr>' ;
}
}
Add this javascript code to the bottom of your HTML code.
jQuery(document).ready(function($) {
// bind event to all anchor tags with class addToShelf
$('a.addToShelf').click(function() {
var book_id = this.id;
$.ajax('addToShelf.php?id='+book_id, function() {
// execute code after the ajax request is complete...
$('addToShelfLink'+book_id).hide();
$('rfs'+book_id).show();
$('mt'+book_id).hide();
$('grn'+book_id).show();
});
return false;
});
});