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.
Related
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});
}
I use the code below for sending ajax request to get more products on scroll down event. However it also sends ajax request when I scroll up, which is not intended. How can I modify it so that it will send a request only when I scroll it to the bottom?
_debug = true;
function dbg(msg) {
if (_debug) console.log(msg);
}
$(document).ready(function () {
$(".item-block img.lazy").lazyload({
effect: "fadeIn"
});
doMouseWheel = 1;
$("#result").append("<p id='last'></p>");
dbg("Document Ready");
var scrollFunction = function () {
dbg("Window Scroll Start");
/* if (!doMouseWheel) return;*/
var mostOfTheWayDown = ($('#last').offset().top - $('#result').height()) * 2 / 3;
dbg('mostOfTheWayDown html: ' + mostOfTheWayDown);
dbg('doMouseWheel html: ' + doMouseWheel);
if ($(window).scrollTop() >= mostOfTheWayDown) {
$(window).unbind("scroll");
dbg("Window distanceTop to scrollTop Start");
$('div#loadMoreComments').show();
doMouseWheel = 1;
dbg("Another window to the end !!!! " + $(".item-block:last").attr('id'));
$.ajax({
dataType: "html",
url: "search_load_more.php?lastComment=" + $(".item-block:last").attr('id') + "&" + window.location.search.substring(1),
success: function (html) {
doMouseWheel = 0;
if (html) {
$("#result").append(html);
dbg('Append html: ' + $(".item-block:first").attr('id'));
dbg('Append html: ' + $(".item-block:last").attr('id'));
$("#last").remove();
$("#result").append("<p id='last'></p>");
$('div#loadMoreComments').hide();
$("img.lazy").lazyload({
effect: "fadeIn"
});
$(window).scroll(scrollFunction);
} else {
//Disable Ajax when result from PHP-script is empty (no more DB-results )
$('div#loadMoreComments').replaceWith("<center><h1 style='color:red'>No more styles</h1></center>");
doMouseWheel = 0;
}
}
});
}
};
$(window).scroll(scrollFunction);
});
You'll need to detect the direction of the scroll and add that as a boolean check. This post covers it.
The snippet they provide:
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
// downscroll code
} else {
// upscroll code
}
lastScrollTop = st;
});
So you'll probably do something like:
$(window).scrollTop() >= mostOfTheWayDown && st > lastScrollTop
I have changed the below line
if ($(window).scrollTop() >= mostOfTheWayDown)
to
if( $(window).height() + $(window).scrollTop() == $(document).height())
this worked for me. Hope this can help others too. Thanks
How to code this? when I hover my name It pop outs like a form but I think its not a form
I want exactly the same like this because I want to happen in my page when I hover my name it has a value of id and send it via ajax to the php then the php script queries the id and return its other details then the other details will display like in the image I already have a function and a php code the only I need is how to do like this image
code for js function:
function searchWarriors() {
var id = $("#name").val();
$.ajax({
url: "retrieve_result.php",
type:"GET",
datatype:"json",
data: {id: id},
success: function(data) {
var toAppend = '';
if(typeof data === "object"){
for(var i=0;i<data.length;i++){
var warrior = data[i];
toAppend += '<ul class="ul">';
toAppend += '<li>'+data[i]['loc']+'</li>';
toAppend += '<li>'+data[i]['email']+'</li>';
toAppend += '<li>'+data[i]['sex']+'</li>';
toAppend += '</ul>';
}
$(".ul").remove();
$("#details").append(toAppend);
}
}
});
return false;
}
Code for my PHP:
<?php
header("Content-Type: application/json");
include 'functions/class.php';
$db = new DB();
$result = $db->getDetails($_GET['id']);
$details = array();
foreach($result as $values){
$details[] = $names;
}
echo json_encode($details);
?>
Code for my html to call function
<?php
foreach($result as $id){
//I don't know if this is right
echo'<a id="name" href="myphpcode.php"?id='.$id['user_id'].'>'.$id['name'].'</a>';
}
?>
<div id="details">
</div>
Easiest way to do this is to normally create exactly how you want the pop-up to look in a php script, then use jQuery and call the script with $("#Popup-id").load(script-url.php?getvar=1). The div element will need a high z-index in order to show on top of the screen.
What i am doing:
I am appending a div with a form and some buttons.The two buttons are save and cancel.When save is clicked,i am posting the form and getting the response.I want to replace the old div that houses the save was clicked.
This is the html and jquery http://jsfiddle.net/thiswolf/vSnJJ/1/
I am using this php but the post data is not sanitized since its an example
<?php
/**
test if replaced item can post and be deleted
#move ---->next
*/
$sliderKey = $_POST['sliderKey'];
$sliderPosition = $_POST['sliderPosition'];
$sliderTitle = $_POST['sliderTitle'];
$sliderLocation = $_POST['sliderLocation'];
$sliderDescription = $_POST['sliderDescription'];
$uniqid = uniqid();
echo "<div class='krudItem' id='$uniqid'><form class='aj' name='itemForm' method='post'action=''><section><label>Slider Title</label><input type='hidden' name='sliderKey' value='$sliderKey'/><input type='hidden' name='sliderPosition' value='$sliderPosition'/><input type='text' name='sliderTitle' value='$sliderTitle'/></section><section><label>Slider Location</label><input type='text' name='sliderLocation' value='$sliderLocation'/></section><section><label>Slider Description</label><textarea name='sliderDescription'>THIS IS THE REPLACEMENT</textarea></section><button name='saveNew' class='saveNew' id='$uniqid'>save</button><button name='newCancel'>delete</button></form></div>";
?>
This is the entire jquery i am using
jQuery(function() {
function randString(n)
{
if(!n)
{
n = 5;
}
var text = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for(var i=0; i < n; i++)
{
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
$("#button").click(function () {
$("<div class='krudItem' id='xxx'><form class='aj' name='itemForm' method='post' action=''><section><label>Slider Title</label><input type='hidden' name='sliderKey' value='16'/><input type='hidden' name='sliderPosition' value='12'/><input type='hidden' name='clickedButton' value='initial'/><input type='text' name='sliderTitle' value='lorem'/></section><section><label>Slider Location</label><input type='text' name='sliderLocation' value='ipsum'/></section><section><label>Slider Description</label><textarea name='sliderDescription'>hello world</textarea></section><button name='saveNew' class='saveNew' id='buttonId' value='saveNew'>save</button><button name='newCancel'>cancel</button></form></div>").appendTo('.krudSpace');
});
//save new
jQuery('.saveNew').live("click",function(event)
{
jQuery(this).attr("id",randString(7));
event.preventDefault();
var contentPanelId = jQuery(this).attr("id");
jQuery.ajax({
type: "POST",
url: "insert.php",
data: jQuery(".aj").serialize(),
success: function(data){
var quoted = "#"+contentPanelId;
jQuery(quoted).replaceWith(data)
}
});
return false;
});
});
It works to some extent but the old div is not replaced at all but the response is appended below the old.
You're making things difficult. Just save the parent itself:
var $p = jQuery(this).parent();
and do:
$p.replaceWith(data)
Here's an updated jsFiddle (it uses error rather than success because there is no PHP): http://jsfiddle.net/vSnJJ/2/.
I am using the following code to get a list of members and their information using ajax, jquery, php, json.
The only problem is when i use .html , it only displays the first record, it doesn't display all of the records. Totally confused.
<script type="text/javascript">
$( document ).delegate("#member_home", "pagecreate", function() {
var refreshId = setInterval(function(){
var friends= new Array();
$.ajaxSetup({cache: false})
$.ajax({
url:'http://www.l.example.com/app/scrip/friends_lookup.php',
data: "",
dataType: 'json',
success: function(data){
$.each(data, function(key, val) {
var friend = val['friend'];
var phone = val['phone'];
var status = val['status'];
var email = val['email'];
var updated = val['updated'];
$('#member_friends').append("<div class='member-box'>"+friend+"<span class='status-pic1'><img src='images/"+status+".png' width='40' height='40'/></span><span class='phone_box'><a href='tel:"+phone+"'><img src='images/icons/phone.png' width='40' height='40' /></a></span><span class='email-box'><a href='mailto:"+email+"'><img src='images/mail.png' width='40' height='40' /></a></span><div class='clear'></div><span class='update-status'><i>last update: "+updated+"</i></span>");
});
}
});
}, 1500);
});
</script>
I tried this, and it didn't work:
<script type="text/javascript">
$( document ).delegate("#member_home", "pagecreate", function() {
var refreshId = setInterval(function() {
var friends= new Array();
$.ajaxSetup({cache: false})
$.ajax({
url: 'http://www.l.example.com/pp/scripts/friends_lookup.php',
data: "",
dataType: 'json',
success: function(data){
var output = [];
for (var i = 0, len = data.length; i < len; i++) {
output[output.length] = {
friend : data[i].friend,
phone : data[i].phone,
status : data[i].status,
email : data[i].email,
updated : data[i].updated
};
$('#member_friends').html("<div class='member-box'>"+friend+"<span class='status-pic1'><img src='images/"+status+".png' width='40' height='40'/></span><span class='phone_box'><a href='tel:"+phone+"'><img src='images/icons/phone.png' width='40' height='40' /></a></span><span class='email-box'><a href='mailto:"+email+"'><img src='images/mail.png' width='40' height='40' /></a></span><div class='clear'></div><span class='update-status'><i>last update: "+updated+"</i></span>");
}
}
});
}, 1500);
});
</script>
You are over-writing the values each iteration of your $.each loop. Before the loop, create an array to store the data, then add to the array each iteration:
$.ajax({
success : function (data) {
var output = [];
for (var i = 0, len = data.length; i < len; i++) {
output[output.length] = {
friend : data[i].friend,
phone : data[i].phone,
status : data[i].status,
email : data[i].email,
updated : data[i].updated
};
}
//you now have an array of objects that each contain a set of information
}
});
The for loop I used is quite fast, here's a JSPerf to show the performance increase over using $.each(): http://jsperf.com/jquery-each-vs-for-loops/2
Also you may have noticed that I used output[output.length] = ... instead of output.push(...). The former performs faster in old browsers (the latter performs faster in modern browsers), I tend to try to help the old browsers out since they really need the help.
I guess your problem is that when you use .html() within a loop, for every iteration, it will replace all content added with the .html() during the previous iteration. Logically that would however leave you with only the last record, not the first.
You have to call .html() after the loop, currently it will replace the contents of #member_friends
in every loop iteration, so you will always see the last item.
This should be the workaround:
var output = [];
var html = []
for (var i = 0, len = data.length; i < len; i++) {
output[output.length] = {
friend : data[i].friend,
phone : data[i].phone,
status : data[i].status,
email : data[i].email,
updated : data[i].updated
};
html.push("<div class='member-box'>"+friend+"<span class='status-pic1'><img src='images/"+status+".png' width='40' height='40'/></span><span class='phone_box'><a href='tel:"+phone+"'><img src='images/icons/phone.png' width='40' height='40' /></a></span><span class='email-box'><a href='mailto:"+email+"'><img src='images/mail.png' width='40' height='40' /></a></span><div class='clear'></div><span class='update-status'><i>last update: "+updated+"</i></span>");
}//end of for
$('#member_friends').html(html.join(''));