Ajax result from PHP to be clickable and run a Jquery function - php

So, I've been learning PHP over the past year or so and recently been playing with Ajax and Jquery. The reason for this is that it seems inefficient to constantly fire PHP scripts off and reload my html each time I want to display or do something.
So what I'm doing: I have a html document with input fields which I need to populate with data. The data is retrieved via a Ajax post call to a PHP script and returns a Json_encoded string. Jquery uses the JSON object to iterate through.
Where I am: I have managed to have Ajax pull back the correct results and populate the input elements I require. The results should be displayed as dynamically named Div IDs as list elements for each. This kind of works but I'm probably over complicating the process.
What I have with this code: So the results come back, and as I start typing in the search box, multiple results will return in the fashion I like. The on(click...) event works to a degree - i.e. it does populate the fields BUT only the last returned result from the Ajax call (last item).
I think the code is almost there (although could be made less complex but it's out of my reach at my current level). It's probably my flow which is wrong (i.e. using .each and then using a click event within it ...) ... I've attempted multiple ways of re-arranging the code but cannot fathom it. Any advice would be amazing. Full code relating to this is attached.
HTML:`
<input type="text" id="search_js" autocomplete="off">
<!-- Show Results -->
<h4 id="results-text"> <b id="search-string"></b> </h4>
<div id="resultsdiv">
<ul id="results">
<!--Results should show up here with custom Div IDs to keep unique -->
</ul>
<!-- END resultsdiv -->
</div>
<!-- End search-container div -->
</div>
...`
PHP:
<?PHP
$search_string = preg_replace("/[^A-Za-z0-9]/", " ", $_POST['query']);
$search_string = "$search_string%";
if (strlen($search_string) >= 1 && $search_string !== ' ') {
// Build Query
$searchstmt = "select * from vw_person_full where name like :s;";
$database->query($searchstmt);
$database->bind(':s', $search_string);
//Custom PDO function - returns associative array
$result_array = $database->resultset();
$output = $result_array;
//convert result array into json format
$json_result = json_encode($output);
echo $json_result;
Jquery:
$(document).ready(function() {
$("input#search_js").on("keyup", function(e) {
// Set Timeout
clearTimeout($.data(this, 'timer'));
// Set Search String
var search_string = $(this).val();
// Do Search
if(search_string == '') {
$("ul#results").fadeOut();
$('h4#results-text').fadeOut();
} else {
$("ul#results").fadeIn();
$('h4#results-text').fadeIn();
$(this).data('timer', setTimeout(search, 100));
};
});
var newsearchres;
function search() {
var query_value = $('input#search_js').val();
var output = '';
//if search box is not empty :
if(query_value !== '') {
$.ajax({
type: "POST",
url: "search.php",
data: {
query: query_value
},
dataType: 'JSON',
cache: false,
success: function(searchres) {
$.each(searchres, function(i, val) {
var countval = i;
//searchres = JSON.parse(searchres);
newsearchres = searchres[i];
console.log(val+" " + countval);
//individual divs for results with ID=divres_##
//output += '<div data-val-index="countval"id="divres' + countval + '" class="cl_divres">';
output += '<div data-val-index="'+countval+'" id="divres' + countval + '" class="cl_divres">';
output += '<li>' + val.fighter_name + '</li>';
//end individual divs:
output += '</div>';
//End search result Div:
output += '</div>';
//Display output in the result div:
$('#resultsdiv').html(output);
console.log(searchres);
});
}
});
};
}
function showDetail(ref) {
var val_id = $(ref).attr('data-val-index');
var val = $.each(newsearchres, function(i, val2) {
if(i == val_id) return val2;
});
$("#pid").prop({
"value": val.pid
});
$("#firstname").prop({
"value": val.first_name
});
$("#lastname").prop({
"value": val.last_name
});
$("#fightername").prop({
"value": val.fighter_name
});
$("#addressl1").prop({
"value": val.address_line1
});
$("#addressl2").prop({
"value": val.address_line2
});
$("#town").prop({
"value": val.town
});
$("#city").prop({
"value": val.city
});
$("#county").prop({
"value": val.county
});
$("#postcode").prop({
"value": val.postcode
});
$("#dob").prop({
"value": val.dob
});
$("#nat").prop({
"value": val.nationality
});
$("#email").prop({
"value": val.email
});
$("#homephone").prop({
"value": val.home_phone
});
$("#mobilephone").prop({
"value": val.mobile_phone
});
};
// $(document).find("div[id^='divres_']").on('click', function() {
$(document).on('click', 'div[id^="divres"]', function() {
console.log(this);
console.log("clicked");
showDetail(this);
});
});
Really sorry for crappy image - but hopefully it makes sense.

First thing that comes to mind right now is that you are ending the search result div at each item. I am only inclined to this because I see you open a new div in the $.each but you close 2.
See below:
$.each(searchres, function (i, val) {
var countval = i;
//individual divs for results with ID=divres_##
output += '<div id="divres_' + countval + '" class="cl_divres">';
output += '<li>' + val.name + '</li>';
//end individual divs:
output += '</div>';
//End search result Div:
output += '</div>'; // <--- add this after the $.each?

The possible reason is that "You are accessing the val for each li events that is accesing outside the each iteration so getting the last values only ."
So try to get the values from index .something as below -
$.each(searchres, function (i, val) {
var countval = i;
//individual divs for results with ID=divres_##
output += '<div data-val-index="countval"
id="divres_' + countval + '" class="cl_divres">';
output += '<li>' + val.name + '</li>';
//end individual divs:
output += '</div>';
//End search result Div:
output += '</div>';
//Display output in the result div:
$('#resultsdiv').html(output);
$(document).find("div[id^='divres_']").on('click',function(){showDetail(this); });
});
Now your callback for event may be as -
function showDetail(ref)
{
var val_id=$(ref).attr('data-val-index');
var val=$.each(searchres, function (i, val2) { if(i==val_id) return val2 ;});
$("#pid").prop({"value": val.pid});
$("#firstname").prop({"value": val.first_name});
$("#lastname").prop({"value": val.last_name});
$("#fightername").prop({"value": val.name});
$("#addressl1").prop({"value": val.address_line1});
$("#addressl2").prop({"value": val.address_line2});
$("#town").prop({"value": val.town});
$("#city").prop({"value": val.city});
$("#county").prop({"value": val.county});
$("#postcode").prop({"value": val.postcode});
$("#dob").prop({"value": val.dob});
$("#nat").prop({"value": val.nationality});
$("#email").prop({"value": val.email});
$("#homephone").prop({"value": val.home_phone});
$("#mobilephone").prop({"value": val.mobile_phone});
}

Related

Creating dynamic div content with jquery

I'm looking to put a div on my website where the content changes based on what link is clicked without refreshing. The content to put there comes from a MySQL database and it's put in JSON.
My problem is that I can't get the JSON data to display when clicking the links.
Here's the script I'm using:
$(document).ready(function () {
$.getJSON("jsondata.php",rightSideData);
function rightSideData(data) {
for(var i=0; i<data.length;i++) {
$("#changetext"+data[i].id).click(function() {
$("#rightside").html("<h1>" + data[i].title + "</h1><p />" + data[i].content);
});
}
}
});
This is the div element that has to change:
<div class='rightside' id='rightside'>Test</div>
The links are constructed this way:
echo "<a id='changetext" . $row['id'] . "'> ";
echo "<div class='tile'>";
echo "<h2>Tile</h2></div></a>";
I've tested the different elements and they work fine (changing the divs content with hardcoded data, displaying the JSON data), but I'm having a hard time figuring out why the combined thing isn't working.
Objects does'nt have a length, use $.each to iterate it instead, unless it's actually an array containing objects :
$(document).ready(function () {
$.getJSON("jsondata.php",rightSideData);
function rightSideData(data) {
$.each(data, function(i, d) {
$("#changetext" + d.id).on('click', function() {
var h1 = $('<h1 />', {text : d.title}),
p = $('<p />', {text : d.content});
$("#rightside").html(h1.add(p));
});
});
}
});
The problem is that i var will be data.length at the end of the loop and that's what the click handler will see.

jquery json to select issues

I'm having the below output from an ajax script:
{"DATA":[{"COUNTRYCODE":"1","DESCRIPTION":"USA","COUNTRYID":"211"}, {"COUNTRYCODE":"1","DESCRIPTION":"Canada","COUNTRYID":"37"},{"COUNTRYCODE":"1","DESCRIPTION":"Dominican Republic","COUNTRYID":"224"},
I am trying to populate a select menu with info from this JSON data:
<script type="text/javascript" charset="UTF-8">
$.getJSON(
'getcountries.php',
function(data) {
var items = [];
$('#country').append(data);
$.each(data['DATA'], function(key, val) {
$.each(val, function(key, value) {
console.log(value);
});
});
}
);
Issue with it is that the $('#country').append(data) (or append(data['DATA']) always returns error "Value does not implement interface Node."
Could anyone point out how I could get the specific JSON data I have into the select script?
.append() only accepts HTML string, DOM Element, or jQuery Object
See: http://api.jquery.com/append/
I assume this is the result you actually want.
var data = {"DATA":[{"COUNTRYCODE":"1","DESCRIPTION":"USA","COUNTRYID":"211"},{"COUNTRYCODE":"1","DESCRIPTION":"Canada","COUNTRYID":"37"},{"COUNTRYCODE":"1","DESCRIPTION":"Dominican Republic","COUNTRYID":"224"}]};
var $select = $('#country').empty();
$select.append(
data.DATA.map(function (el, i) {
return $('<option>')
.val(el.COUNTRYID)
.text(el.DESCRIPTION)
.data('DATA', el); // in case you also want to access its COUNTRYCODE
})
);
jsFiddle: http://jsfiddle.net/terryyounghk/ZshG4/
DEMO: http://jsfiddle.net/q5Q3d/
var a = {
"DATA":[
{"COUNTRYCODE":"1","DESCRIPTION":"USA","COUNTRYID":"211"},
{"COUNTRYCODE":"1","DESCRIPTION":"Canada","COUNTRYID":"37"},
{"COUNTRYCODE":"1","DESCRIPTION":"Dominican Republic","COUNTRYID":"224"}
]
}
$.each(a.DATA, function(idx, val){
var option = "<option value='" + val.COUNTRYID + "'>" + val.DESCRIPTION + "</option>";
$('select').append(option);
});

Unable to navigate Dynamically created pages in DOM

After so many trials, I have finally managed to create pages dynamically using PHP, JSON and AJAX and load them into DOM. But the problem now is I'm unable to call/navigate those pages dynamically, but manually i.e gallery.html#page1 ...etc.
I seek guidance rather than burdening you, as I'm here to learn.
**PHP - photos.php **
$photos = array();
$i=0;
while ($row = mysqli_fetch_array($query)){
$img = $row["fn"];
$photos[] = $img;
$i++;
}
$count = count($photos);
echo json_encode(array('status' => 'success', 'count' => $count, 'items' => $photos));
JSON array
{
"status":"success",
"count":3,
"items":
[
"img1.jpg",
"img2.jpg",
"img3.jpg"
]
}
I use the below method to fetch and store ID of the desired gallery,
<input type="hidden" value="<?php echo $id; ?>" id="displayid" />
and then I call it back to use it in AJAX.
var ID = $('#displayid').val();
AJAX and JQM
$.ajax({
Type: "GET",
url: 'photos.php',
data: { display: ID }, // = $('#displayid').val();
dataType: "json",
contentType: "application/json",
success: function(data) {
var count = data.count;
var number = 0;
$.each(data.items, function(i,item) {
var newPage = $("<div data-role=page data-url=page" + number + "><div data-role=header><h1>Photo " + number + "</h1></div><div data-role=content><img src=" + item + " /></div></div");
newPage.appendTo( $.mobile.pageContainer );
number++;
if (number == count) { $.mobile.changePage( newPage ); }; // it goes to last page
I got this code from here thanks Gajotres to dynamically navigate between pages. It's within the same code.
$(document).on('pagebeforeshow', '[data-role="page"]', function(){
var nextpage = $(this).next('div[data-role="page"]');
if (nextpage.length > 0) {
$.mobile.activePage.find('[data-role="header"]').append($('<a>').attr({'href':'#'+nextpage.attr('id'),'data-theme':'b'}).addClass('ui-btn-right').html('Next').button());
}
}); // next button
}); // each loop
} // success
}); //ajax
I found your problem.
This part of code can't be used here like this:
$(document).on('pagebeforeshow', '[data-role="page"]', function(){
var nextpage = $(this).next('div[data-role="page"]');
if (nextpage.length > 0) {
$.mobile.activePage.find('[data-role="header"]').append($('<a>').attr({'href':'#'+nextpage.attr('id'),'data-theme':'b'}).addClass('ui-btn-right').html('Next').button());
}
});
This is the problem. First remove pagebeforeshow event binding, it can't be used here like that. Rest of the code is not going to do anything because currently there are any next page (next page is going to be generated during then next loop iteration), so remove this whole block.
Now, after the each block ends and all pages are generated (that is the main thing, all pages should exist at this point), add this code:
$('[data-role="page"]').each(function(){
var nextpage = $(this).next('div[data-role="page"]');
if (nextpage.length > 0) {
$(this).find('[data-role="header"]').append($('<a>').attr({'href':'#'+nextpage.attr('id'),'data-theme':'a'}).addClass('ui-btn-right').html('Next').button());
}
});
This is what will happen. Each loop will loop through every available page (we have them all by now) and in case it is not the last one it will add next button.
Here's a live example: http://jsfiddle.net/Gajotres/Xjkvq/
Ok in this example pages are already there, but point is the same. They need to exist (no matter if you add them dynamically or if they are preexisting) before you can add next buttons.
I hope this helps.

Creating a comments page selection using AJAX data

I decided to go AJAX route for the heck of it, mainly to learn it, and to see how it worked. I want to add a page selection for comments that exceed, say, 10 posts.
I am using Codeigniter, and will post what I have so far:
Controller:
public function updatefilters()
{
$this->blurb_model->create_session_filter($_POST['filters']);
$this->blurb_model->get_threads($_POST['pagenum']);
}
Model:
public function get_threads($page = 0)
{
$NEEDPAGEHERE = $page
[fetch threads]
[return threads / count / etc]
}
So my goal is to display the number of pages to the user. This part is done. I have a submit button displayed for each page based on the total count of items returned in the "get_threads" model (code is omitted for relevance sake).
Here is my AJAX/javascript
Focus lies on the updatefilter function. I use the returned thread list to construct HTML and post it within the div. This works fine.
The problem is that I want to reuse the updatefilters() function when the user clicks on a page button...but its not working. I want to pass the value of the submit button into the updatefilter(pagenum) so that it then goes to the controller -> method, and I can do the math, but it does not work.
Javascript:
function updatefilters(pagenum){
// get the selected filters
var html;
var i = 0;
if (!pagenum)
{
pagenum = 0
}
var $selected = $('#selectable').children('.ui-selected');
// create a string that has each filter separated by a pipe ("|")
var filters = $selected.map(function(){return this.id;}).get().join("\|");
$.ajax({
type: "POST",
async: false,
url: 'welcome/updatefilters',
dataType: 'json',
data: { filters: filters, pagenum: pagenum },
success: function(data){
var html = "";
html += "<div id=board>"
html += "<div class='board' id='table'>"
html += "<div id='row'>header here</div>"
var pages = Math.ceil(data['num_threads']/10);
var htmlpage = "<div class='pages'>"
for (i=1 ; i < pages+1 ; i++)
{
htmlpage += "<li><input type='submit' id='page"+i+"' value='"+i+"' onclick='updatefilters(this.value);' /></li>"
}
htmlpage += "<div>"
htmlpage += "</ul>";
htmlpage += "</br></br></br>";
html += htmlpage;
for (i=0 ; i < data['threads'].length ; i++)
{
html += "<div id=row>";
html += " <div id='author' style='background: url("+data['threads'][i].location + ") no-repeat; background-position: center;'><p>"+data['threads'][i].username + "</p></div>";
html += " <div id='arrow'></div>";
html += " <div id='subject' title='"+ data['threads'][i].body +"'>";
html += " "+ data['threads'][i].subject +"<p>Created: "+data['threads'][i].posttime+"</p></div>";
html += " <div id='info'>";
html += " <div id='replies'>" + data['threads'][i].replies_num + "</div>";
html += " <div id='lastpost'>"+ data['threads'][i].lastreply+"</div>";
html += " </div>";
html += "</div>";
}
html += "</div></div>";
$('#board').html(html);
}
});
}
$(function() {
$( "#selectable" ).selectable({
selected: updatefilters
});
getactivesession();
function getactivesession(ev, ui){
var i = 0;
var actfilter, strfilter;
var strfilterarray = new Array();
$.ajaxSetup({cache: false})
$.ajax({
type: "POST",
async: false,
url: 'welcome/getactivesession',
dataType: 'json',
success: function (data){
strfilter = JSON.stringify(data)
strfilterarray = strfilter.split(',')
for (i=0 ; i < strfilterarray.length ; i++) {
strfilter = strfilterarray[i]
strfilter = strfilter.replace(/[\[\]'"]+/g,'');
var strfilterdash = strfilter.replace(/\s+/g, '-')
actfilter = '#'+ strfilterdash
$(actfilter).addClass('ui-selected')
}
updatefilters();
}
});
}
});
This would be an INCREDIBLE learning experience for myself, and a huge help if someone can spot the problem and explain it in an easily understood manner. I am extremely new with javascript and programming in general (which might explain the ugliness of the code).
Thanks!
Modify your selected event callback.
$("#selectable").selectable({
// Here is the event callback signature for reference
selected: function(event, ui) {
updatefilters();
}
});
You were passing an unexpected first parameter to updatefilters function.

Update Flot plot with 2 series in realtime

I'm working on displaying 2 time series of values using jquery and flot. I'm using them for a small period of time and for now I'm sticking to the examples. Basically I adapted several examples to extract from MySQL database the series using a PHP script that I include in the JQuery script. All works fine this far. I wish to be able to refresh this series every several seconds. This refresh doesn't seem to work and I'm not sure why. Bellow is the jquery code used to generate the graph. I put now part one of the script.
$(function(){
//add data source to flot. 2 datasets with same structure: data in UNIX_TIMESTAMP format, value in DECIMAL format
<?php include 'datasource.php'; ?>;
//declare datasets
var datasets = {
"temperature": {
label: "Temperature (C)",
data: <?php echo json_encode($dataset1); ?>
},
"humidity": {
label: "Humidity (%)",
data: <?php echo json_encode($dataset2); ?>
}
};
//set fixed colors for each series
var i = 0;
$.each(datasets, function(key, val) {
val.color = i;
++i;
});
// insert checkboxes
var choiceContainer = $("#choices");
$.each(datasets, function(key, val) {
choiceContainer.append(' <input type="checkbox" name="' + key +
'" checked="checked" id="id' + key + '">' +
'<label for="id' + key + '">'
+ val.label + '</label>');
});
choiceContainer.find("input").click(plotAccordingToChoices);
//define plot options
var options = {series: { shadowSize: 0 },
yaxis: { min: <?php echo json_encode($mintemp) ?>, max: <?php echo json_encode($maxtemp) ?> },
xaxis: { show: true, mode: "time", timeformat: "%h:%M %d.%m.%y", labelWidth: "10"}};
//draw plot
function plotAccordingToChoices() {
var data = [];
choiceContainer.find("input:checked").each(function () {
var key = $(this).attr("name");
if (key && datasets[key])
data.push(datasets[key]);
});
if (data.length > 0)
$.plot($("#placeholder"), data, options);
}
plotAccordingToChoices();
//define plot refresh timeout
setInterval(plotAccordingToChoices(), 3000);})
The first argument to setInterval should to be a string:
setInterval('plotAccordingToChoices()', 3000);
Or only the function name (not calling it):
setInterval(plotAccordingToChoices, 3000);
See: https://developer.mozilla.org/en/window.setInterval
To get updated data from the server-side (PHP), you also need to do remote calls (AJAX). You may use jQuery getScript function.
Something like this:
function updatePlot() {
$.getScript('update_plot.php');
}
setInterval(updatePlot, 3000);
Then, in your update_plot.php file, you can return JavaScript code mixed with PHP (just like you already did):
<?php // here some PHP code to get your data ?>
// and here some javascript code to use the data
plotAccordingToChoices(); // and finally update the plot

Categories