In my index page I got 3 colums, the first column displays all the categories in a database, second column displays the subject when a category is clicked, and third col selects contents when subject is clicked ..
What Im trying to do is, While Clicking any category, Ajax Requests the database for all subjects related to that category, and display it in column1 and It Works, but when i click the generated subjects to get content for that subject it fails to request asynchronously, instead it takes me to content.php. to make it more clear i am pasting the index.php and script.js ( all the javascript and jquery files been included in header.php)
the index page
<?php
include("tpl/header.php");
?>
<div id="navigation">
<ul id="search_form">
<?php
$cat = Category::find_all();
foreach($cat as $category) {
echo '<li value="';
echo $category->cat_id;
echo '" class="myLi" "><a href="subject.php?id=';
echo $category->cat_id;
echo'">';
echo $category->category;
echo '</a></li>';
}
?>
</ul>
</div>
<div id="content1">
<h2>Subjects</h2>
<!-- works -->
</div>
<div id="content2">
<h2>Content</h2>
<!-- doesnt work -->
</div>
<?php
include_layout_template("footer.php");
?>
the js code
$(document).ready(function() {
$(".myLi").click(function(){
var id = this.value;
ajax.open('get', 'subject.php?id=' + encodeURIComponent(id));
ajax.onreadystatechange = function() {
// Pass it this request object:
handleResponse(ajax);
}
ajax.send(null);
return false; // So form isn't submitted.
});
$(".myLi1").click(function(){
var cid = this.value;
ajax.open('get', 'content.php?id=' + encodeURIComponent(cid));
ajax.onreadystatechange = function() {
// Pass it this request object:
handleResponse1(ajax);
}
ajax.send(null);
return false; // So form isn't submitted.
});
function handleResponse(ajax) {
// Check that the transaction is complete:
if (ajax.readyState == 4) {
// Check for a valid HTTP status code:
if ((ajax.status == 200) || (ajax.status == 304) ) {
// Put the received response in the DOM:
var results = document.getElementById('content1');
results.innerHTML = ajax.responseText;
// Make the results box visible:
results.style.display = 'block';
}
} // End of readyState IF.
} // End of handleResponse() function.
function handleResponse1(ajax) {
// Check that the transaction is complete:
if (ajax.readyState == 4) {
// Check for a valid HTTP status code:
if ((ajax.status == 200) || (ajax.status == 304) ) {
// Put the received response in the DOM:
var results1 = document.getElementById('content2');
results1.innerHTML = ajax.responseText;
// Make the results box visible:
results1.style.display = 'block';
}
} // End of readyState IF.
} // End of handleResponse() function.
});
..Well it fails only when I Click the subject on Index page, When I navigate to subject.php and click the link it gives the result asynchronously. so my question is how can i query multiple ajax calls on a single page(i.e in my case "index.php" ) .. any help ?
After the subjects are loaded, you should ajaxify them, but you are ajaxifying them when the document is ready, that is, before they even exist. Your call to $(".myLi1") doesn't match anything.
Another solution would be to attach your event to all elements matching .myLi1 now, or in the future.
With jQuery < 1.7, you can do this with the delegate() method, otherwise, with the on() method.
Related
I have a page and I am displaying the list(MAX 200 records) on my page using ajax.
I am using the below code to call the ajax and show the response on the page.
And the second script is for a button called "Load More". I have to show the 20 records on the page then the user clicks on load more than displays the next 20 records.
Now, My issue is, I am getting all the records and load more button
$(document).ready(function(){
$.ajax({
url: 'function21.php',
method:'post',
dataType: "json",
data:{action:"employeelist21"},
success: function(data){
$('#employeelist').append(data);
}
})
});
$(document).ready(function(){
var list = $("#employeelist21 li");
var numToShow = 20;
var button = $("#next");
var numInList = list.length;
//alert(numInList);
list.hide();
if (numInList > numToShow) {
button.show();
}
list.slice(0, numToShow).show();
button.click(function(){
var showing = list.filter(":visible").length;
list.slice(showing - 1, showing + numToShow).fadeIn();
var nowShowing = list.filter(":visible").length;
if (nowShowing >= numInList) {
button.hide();
}
});
});
PHP
function employeelist21($pdo)
{
$query=" sql query here";
$stmt = $pdo->prepare($query);
$stmt->execute();
$results = $stmt->fetchAll();
if (!empty($results)) {
$data='';
$data='<ul><li>
<div class="box">
<div><span>Company</span></div>
<div><span>Industry</span></div>
<div><span>Name</span></div>
<div><span>Location</span></div>
</div>
</li>';
foreach($results as $key){
$data.='<li>
<div class="box">
<div><h4>'.$key['Industry'].'</h4></div>
<div><p>'.$key['industry_name'].'</p></div>
<div><p>'.$key['name'].'</p></div>
<div><p>'.$key['city'].'</p></div>
</div>
</li>';
}
$data.='</ul><div class="text-center">Load More</div>';
}
else{
$data.='No records available';
}
echo json_encode($data);
}
First, I would rather transfer back a list of data (not html) in json format and use that like an array, creating the HTML for it in javascript. BUT we don't always get what we want, so in this case I would assign an attribute to each set of 20 like this:
// at the top of your script (not in a function)
let perPage = 20, onGroup=0
// in your ajax function ...
success: function(data){
$('#employeelist').hide();
$('#employeelist').append(data);
$('#employeelist box').each( function(index) {
if (index===0) return; //header row
$(this).data('group',Math.floor(index-1/perPage))
});
$('#employeelist box').hide()
$('#employeelist box [data-group=0]').show()
$('#employeelist').show();
}
Then for the button, remove this from the PHP and make it an element under the results div
<div class="text-center">Load More</div>
Then in your script
$(document).ready(function() {
$("#next").click(function(){
$('#employeelist box [data-group='+onGroup+']').hide()
onGroup++;
$('#employeelist box [data-group='+onGroup+']').show()
if ($('#employeelist box [data-group='+(onGroup+1)+']').length ===0) {
$(this).hide();
}
});
});
Hard to test here, but let me know if it doesn't work
I am working on an infinite scroll (load data on scroll) plugin for my site.
This is the load.js script:
(function($) {
$.fn.scrollPagination = function(options) {
var settings = {
nop : 10, // The number of posts per scroll to be loaded
offset : 0, // Initial offset, begins at 0 in this case
error : 'No More Posts!', // When the user reaches the end this is the message that is
// displayed. You can change this if you want.
delay : 500, // When you scroll down the posts will load after a delayed amount of time.
// This is mainly for usability concerns. You can alter this as you see fit
scroll : true // The main bit, if set to false posts will not load as the user scrolls.
// but will still load if the user clicks.
}
// Extend the options so they work with the plugin
if(options) {
$.extend(settings, options);
}
// For each so that we keep chainability.
return this.each(function() {
// Some variables
$this = $(this);
$settings = settings;
var offset = $settings.offset;
var busy = false; // Checks if the scroll action is happening
// so we don't run it multiple times
// Custom messages based on settings
if($settings.scroll == true) $initmessage = 'Scroll for more or click here';
else $initmessage = 'Click for more';
// Append custom messages and extra UI
$this.append('<div class="loading-bar">'+$initmessage+'</div>');
function getData() {
// Post data to ajax.php
$.post('ajax.php', {
action : 'scrollpagination',
number : $settings.nop,
offset : offset,
}, function(data) {
// Change loading bar content (it may have been altered)
$this.find('.loading-bar').html($initmessage);
// If there is no data returned, there are no more posts to be shown. Show error
if(data == "") {
$this.find('.loading-bar').html($settings.error);
}
else {
// Offset increases
offset = offset+$settings.nop;
// Append the data to the content div
$this.find('#container123').append(data);
// No longer busy!
busy = false;
}
});
}
getData(); // Run function initially
// If scrolling is enabled
if($settings.scroll == true) {
// .. and the user is scrolling
$(window).scroll(function() {
// Check the user is at the bottom of the element
if($(window).scrollTop() + $(window).height() > $this.height() && !busy) {
// Now we are working, so busy is true
busy = true;
// Tell the user we're loading posts
$this.find('.loading-bar').html('Lade...');
// Run the function to fetch the data inside a delay
// This is useful if you have content in a footer you
// want the user to see.
setTimeout(function() {
getData();
}, $settings.delay);
}
});
}
// Also content can be loaded by clicking the loading bar/
$this.find('.loading-bar').click(function() {
if(busy == false) {
busy = true;
getData();
}
});
});
}
})(jQuery);
This upper script posts data to a php file called ajax.php, which looks like this (shortened):
$sql = "SELECT * FROM table WHERE";
if (!empty($_GET['search'])){
$sql = $sql . " (Name LIKE '%".$_GET['search']."%' OR Description LIKE '%".$_GET['search']."%')";
} else {
$sql = $sql . " Name!=''";
}
$offset = is_numeric($_POST['offset']) ? $_POST['offset'] : die();
$postnumbers = is_numeric($_POST['number']) ? $_POST['number'] : die();
$sql = $sql . " LIMIT ".$postnumbers." OFFSET ".$offset;
$result=mysql_query($sql);
while($row=mysql_fetch_array($result)){
echo 'item';
}
This ajax.php - script, on the other hand, displays the data in my index.php file.
And here's where the problem is:
Please take a look at the upper if (!empty($_GET['search'])) - statement. Obviously, this $_GET-variable cannot be filled, since the corresponding forms (search-form) are located in my index.php - page.
Now my question is: How can I get the if (!empty($_GET['search'])) to work? I am really not good with ajax, and I believe the problem is that the data created in load.js gets posted to ajax.php in the first place.
Just for completion, this is the corresponding markup in index.php
<section id="start" class="...">
<div id="container123" class="...">
</div>
</section>
<!-- search form etc. -->
Thank you very much in advance. I know it is quite a lot of code. (btw, I know, MySQL is outdated and dangerous)
Modify your plugin to accept search term as parameter and code your index.php something like.
<script>
$("#container123" ).scrollPagination ({ q:'<?php echo $_GET['search']; ?>'"}); </script>
<div id="container123"></div>
Now since this code is written in index.php you will get $_GET['search']
i have written a javascript inside the php file, but while calling it from my main page like this
<script type="text/javascript" src="<?php echo base_url() . 'js/inf-scroll/javascript_showuserinst.php' ?>"> </script>
Problem: if i see in the javascript_showuserinst.php file a line as $.post('/instruction/show_user_inst/<?php echo $userid; ?>', {
here <?php echo $userid; ?> is giving me problem. Is that line syntax is correct?
I see the view source its showing <b>Notice</b>: Undefined variable: userid in <b>D:\xampp\htdocs\js\inf-scroll\javascript_showuserinst.php</b> on line <b>46</b><br />
But if i copy & paste the same js content in the main page without calling it from external file, it works perfectly.
javascript_showuserinst.php
Header("content-type: application/javascript");
?>
(function($) {
$.fn.scrollPagination = function(options) {
var settings = {
nop : 10, // The number of posts per scroll to be loaded
offset : 0, // Initial offset, begins at 0 in this case
error : 'No More Data To Display!', // When the user reaches the end this is the message that is
// displayed. You can change this if you want.
.............
.............
JavaScript files are expected to contain JavaScript.
Your JavaScript file contains a fragment of HTML.
Don't include HTML <script> tags in a JavaScript file.
<?php
echo "<script type='text/javascript' src='".base_url()."js/inf-scroll/javascript_showuserinst.php"."'></script>"
?>
This must be in your PHP Script File
<script type="text/javascript" src="<?php echo base_url() . 'js/inf-scroll/javascript_showuserinst.php' ?>"> </script>
Now javascript_showuserinst.php can be like below
(function($) {
$.fn.scrollPagination = function(options) {
var settings = {
nop : 10, // The number of posts per scroll to be loaded
offset : 0, // Initial offset, begins at 0 in this case
error : 'No More Data To Display!', // When the user reaches the end this is the message that is
// displayed. You can change this if you want.
delay : 500, // When you scroll down the posts will load after a delayed amount of time.
// This is mainly for usability concerns. You can alter this as you see fit
scroll : true // The main bit, if set to false posts will not load as the user scrolls.
// but will still load if the user clicks.
}
// Extend the options so they work with the plugin
if(options) {
$.extend(settings, options);
}
// For each so that we keep chainability.
return this.each(function() {
// Some variables
$this = $(this);
$settings = settings;
var offset = $settings.offset;
var busy = false; // Checks if the scroll action is happening
// so we don't run it multiple times
// Custom messages based on settings
if($settings.scroll == true) $initmessage = 'No more data to show';
else $initmessage = 'Click for more';
// Append custom messages and extra UI
$this.append('<div class="content"></div><div class="loading-bar">'+$initmessage+'</div>');
function getData() {
// Post data to ajax.php
$.post('/instruction/show_user_inst/<?php echo $userid; ?>', {
action : 'scrollpagination',
number : $settings.nop,
offset : offset
}, function(data) {
// Change loading bar content (it may have been altered)
$this.find('.loading-bar').html($initmessage);
// If there is no data returned, there are no more posts to be shown. Show error
if(data == "") {
$this.find('.loading-bar').html($settings.error);
}
else {
// Offset increases
offset = offset+$settings.nop;
// Append the data to the content div
$this.find('.content').append(data);
// No longer busy!
busy = false;
}
});
}
getData(); // Run function initially
// If scrolling is enabled
if($settings.scroll == true) {
// .. and the user is scrolling
$(window).scroll(function() {
// Check the user is at the bottom of the element
if($(window).scrollTop() + $(window).height() > $this.height() && !busy) {
// Now we are working, so busy is true
busy = true;
// Tell the user we're loading posts
$this.find('.loading-bar').html('Loading...');
// Run the function to fetch the data inside a delay
// This is useful if you have content in a footer you
// want the user to see.
setTimeout(function() {
getData();
}, $settings.delay);
}
});
}
// Also content can be loaded by clicking the loading bar/
$this.find('.loading-bar').click(function() {
if(busy == false) {
busy = true;
getData();
}
});
});
}
})(jQuery);
Try it out
I am dynamically adding list items to a list in jQuery through an ajax call that is called every second.
Below is the code for the ajax call.
$.ajax({
url: 'php/update_group_list.php',
data: '',
dataType: 'json',
success: function(data) {
var id = data.instructor_id;
group_cnt = data.group_cnt,
group_name = data.group_name,
group_code = data.group_code;
for (i = current_row; i < group_cnt; i++)
{
//setInterval(function() { $('#group-list-div').load('php/group_list.php'); }, 5000);
$('#group-list').append("<li><a href='#' data-role='button' class='view-group-btns' id='"+group_code[i]+"' value='"+id+"' text='"+group_name[i]+"'>"+group_name[i]+"</a></li>");
$('#delete-group-list').append("<fieldset data-role='controlgroup data-iconpos='right'>" +
"<input id='"+group_code[i]+i+"' value='"+group_code[i]+"' type='checkbox' name='groups[]'>" +
"<label for='"+group_code[i]+i+"'>"+group_name[i]+"</label>" +
"</fieldset>");
}
current_row = i;
$('#group-list').listview('refresh');
$('#delete-group-list').trigger('create');
}
});
Now I am having two problems
FIRST PROBLEM:
When I try to run the code below (it should show an alert box if any of the list items created in this line $('#group-list').blah...blah in the code above), nothing happens.
$(".view-group-btns").click(function()
{
alert("check");
});
SECOND PROBLEM:
Also when I try to send the form data for the checkboxes (referencing line $('#delete-group-list').blah...blah in the ajax call code above) the post returns the error unexpected token <
What am I doing wrong? I think the two problems are related as I am creating the list items that are used dynamically.
Here is extra code relating to the SECOND problem
HTML:
<form id='delete-group-form' action='php/delete_groups.php' method='post'>
<h3 style='text-align: center;'>Check the Box Beside the Groups you Would Like to Delete </h3>
<div style='margin-top: 20px;'></div>
<div id='delete-group-list'>
</div>
<div style='margin-top: 20px;'></div>
<input type='submit' id='delete-groups-btn' data-theme='b' value='Delete Groups(s)'>
</form>
JS Code
$('#delete-group-form').submit(function(e)
{
e.preventDefault();
alert($('#delete-group-form').serialize());
if ($('#delete-group-form').serialize() == "")
{
alert('No groups selected to be deleted.')
return false;
}
else
if ($('#delete-groups-form').serialize() == null)
{
alert('No groups selected to be deleted.')
return false;
}
else
{
$.post('php/delete_groups.php',$('#delete-groups-form').serialize()).done(function(data)
{
obj = jQuery.parseJSON(data);
var group_codes = obj.group_list;
alert(group_codes);
alert("The selected groups have been deleted");
window.setTimeout(2000);
return false;
});
}
return false;
});
delete_groups.php
<?php
$group_codes = $_POST['groups'];
$items = array('group_list'=>$group_codes); //creating an array of data to be sent back to js file
echo json_encode($items); //sending data back through json encoding
?>
I think the root of the SECOND problem is the line $group_codes = $_POST['groups']; specfically the $_POST['groups'] because when I replace it with $group_codes = 'test'; (just for debugging purposes) , the code works as expected.
You need to use event delegation to make your newly-created elements function properly:
$("#group-list").on("click", ".view-group-btns", function() {
alert("check");
});
I noticed you have 3 single quotes on this line... missed one after controlgroup
$('#delete-group-list')."<fieldset data-role='controlgroup data-iconpos='right'>"
That would explain the unexpected token <
You have to use the jquery on event.
$(".view-group-btns").on("click", function(event)
{
alert("check");
});
Why?
Because you can only use the regular "click" on elements that are created BEFORE the DOM is updated.
When you are dynamically creating new elements into the dom tree, then you can't use .click anymore.
on (and in the past, .live(), which is deprecated now) can listen to modifications in the DOM tree and can use the later-on created elements.
You have to bind the click function after you get the element from ajax call. Binding on pageLoad event will only bind with those elements that are already in the dom. So do something like this.
$.ajax({
success : function(res){
//bind your click function after you update your html dom.
}
})
I have the following jquery code
$(document).ready(function() {
//Default Action
$("#playerList").verticaltabs({speed: 500,slideShow: false,activeIndex: <?=$tab;?>});
$("#responsecontainer").load("testing.php?chat=1");
var refreshId = setInterval(function() {
$("#responsecontainer").load('testing.php?chat=1');
}, 9000);
$("#responsecontainer2").load("testing.php?console=1");
var refreshId = setInterval(function() {
$("#responsecontainer2").load('testing.php?console=1');
}, 9000);
$('#chat_btn').click(function(event) {
event.preventDefault();
var say = jQuery('input[name="say"]').val()
if (say) {
jQuery.get('testing.php?action=chatsay', { say_input: say} );
jQuery('input[name="say"]').attr('value','')
} else {
alert('Please enter some text');
}
});
$('#console_btn').click(function(event) {
event.preventDefault();
var sayc = jQuery('input[name="sayc"]').val()
if (sayc) {
jQuery.get('testing.php?action=consolesay', { sayc_input: sayc} );
jQuery('input[name="sayc"]').attr('value','')
} else {
alert('Please enter some text');
}
});
$('#kick_btn').click(function(event) {
event.preventDefault();
var player_name = jQuery('input[name="player"]').val()
if (player_name) {
jQuery.get('testing.php?action=kick', { player_input: player_name} );
} else {
alert('Please enter some text');
}
});
});
Sample Form
<form id=\"kick_player\" action=\"\">
<input type=\"hidden\" name=\"player\" value=\"$pdata[name]\">
<input type=\"submit\" id=\"kick_btn\" value=\"Kick Player\"></form>
And the handler code
if ($_GET['action'] == 'chatsay') {
$name = USERNAME;
$chatsay = array($_GET['say_input'],$name);
$api->call("broadcastWithName",$chatsay);
die("type: ".$_GET['type']." ".$_GET['say_input']);
}
if ($_GET['action'] == 'consolesay') {
$consolesay = "§4[§f*§4]Broadcast: §f".$_GET['sayc_input'];
$say = array($consolesay);
$api->call("broadcast",$say);
die("type: ".$_GET['type']." ".$_GET['sayc_input']);
}
if ($_GET['action'] == 'kick') {
$kick = "kick ".$_GET['player_input'];
$kickarray = array($kick);
$api->call("runConsoleCommand", $kickarray);
die("type: ".$_GET['type']." ".$_GET['player_input']);
}
When I click the button, it reloads the page for starters, and isn't supposed to, it also isn't processing my handler code. I've been messing with this for what seems like hours and I'm sure it's something stupid.
What I'm trying to do is have a single button (0 visible form fields) fire an event. If I have to have these on a seperate file, I can, but for simplicity I have it all on the same file. The die command to stop rest of file from loading. What could I possibly overlooking?
I added more code.. the chat_btn and console_btn code all work, which kick is setup identically (using a hidden field rather than a text field). I cant place whats wrong on why its not working :(
use return false event.instead of preventDefault and put it at the end of the function
ie.
$(btn).click(function(event){
//code
return false;
});
And you should probably be using json_decode in your php since you are passing json to the php script, that way it will be an array.
Either your callback isn't being invoked at all, or the if condition is causing an error. If it was reaching either branch of the if, it wouldn't be reloading the page since both branches begin with event.prevntDefault().
If you're not seeing any errors in the console, it is likely that the callback isn't being bound at all. Are you using jQuery(document).ready( ... ) to bind your event handlers after the DOM is available for manipulation?
Some notes on style:
If both branches of the if contain identical code, move that code out of the if statement:
for form elements use .val() instead of .attr('value')
don't test against "" when you really want to test truthyness, just test the value:
jQuery(document).ready(function () {
jQuery('#kick_btn').click(function(event) {
event.preventDefault();
var player_name = jQuery('input[name="player"]').val()
if (player_name) {
jQuery.get('testing.php?action=kick', { player_input: player_name} );
} else {
alert('Please enter some text');
}
})
});
I figured out the problem. I have a while loop, and apparently, each btn name and input field name have to be unique even though they are all in thier own tags.
$("#playerList").delegate('[id^="kick_btn"]', "click", function(event) {
// get the current player number from the id of the clicked button
var num = this.id.replace("kick_btn", "");
var player_name = jQuery('input[name="player' + num + '"]').val();
jQuery.get('testing.php?action=kick', {
player_input: player_name
});
jQuery('input[name="player"]').attr('value','')
alert('Successfully kicked ' + player_name + '.');
});