I am trying to understand ajax and want to figure out how I can refresh a div that displays a rowcount from a mysql database live as the data is entered into that database.
I have a simple form on the same page and as the data is submitted from the form to the database how can I make the div update 'live' as well?
The code I've posted here posts a name from a form which is inserted into a mysql database. Then the number of rows in the database is counted and returned as a json object. It all works fine but only refreshes the rowcount when I reload the page and I want it to refresh instantly.
Many thanks.
The form
<form class="form-inline" action="" id="myform" form="" method="post">
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="name"></label>
<div class="col-md-8">
<input id="name" name="name" type="text" placeholder="name" class="form-control input-lg" required>
</div>
</div>
<!-- Button -->
<div class="form-group">
<label class="col-md-4 control-label" for="submit1"></label>
<div class="col-md-4">
<button id="submitButtonId" name="submit1" class="btn btn-primary btn-xl">Submit</button>
</div>
</div>
</form>
<!---------Display rowcount from database--------->
The jquery
<script>
$(document).ready(function(){
$("#submitButtonId").on("click",function(e){
e.preventDefault();
var formdata = $(this.form).serialize();
$.post('data.php', formdata,
function(data){
//Reset Form
$('#myform')[0].reset();
});
return false;
});
});
</script>
<script>
$(document).ready(function() {
$.ajax({
url: 'data.php',
dataType: "json",
success: function (data) {
$("#count").append(data.count);
}
});
return false;
});
</script>
data.php
<?php
//include db configuration file
include_once("db_conx.php");
$name= mysqli_real_escape_string($db_conx,$_POST['name']);
//Update Database
$stmt = $db_conx->prepare('INSERT INTO my_table set name?');
$stmt->bind_param('s',$name);
$stmt->execute();
//Count Rows
$sql="SELECT name FROM utility";
$query = mysqli_query($db_conx, $sql);
// Return the number of rows in result set
$rowcount=mysqli_num_rows($query);
// sending JSON output
$my_data=array(count=>"$rowcount");
echo json_encode($my_data,true);
?>
If you want the server to push events to the client, you can use Websockets. There are services like Pusher that can help, it has a free plan (100 connections, 200K messages per day) and a good documentation to integrate with PHP and some popular frameworks.
If you don't want to use websockets, you can use a more traditionnal polling : every X seconds, you make a GET request to the server asking for the count, if it changes you update it, if not you do nothing and wait for the next call. This can be setup easily with setTimeout() in Javascript.
With PHP + ajax you should query to the database every X time with a timeout (setTimeOut()).
You could use websockets or take a look to firebase.
Also I suggest you to change .append(data.count); to .html(data.count); in order to 'clean' the div, if not, you may have multiple 'data.count' on it.
Here a post with a lot of answers for this: What are Long-Polling, Websockets, Server-Sent Events (SSE) and Comet?
Related
I have a simple webstore and I'm trying to add multiple shipping options. There are two options and I want to store the option selected by the customer in a session (or alternatively a cookie).
The php script seems to work on its own but results in page reloading so I have been trying to implement ajax using jquery to send the data but either the code doesn't run or the page reloads.
I have tried to follow several answers, including substituting button for type="submit" but that results in the code not seeming to execute at all. Adding 'click' to .on triggers the code but also results in a reload. I've checked the console and can't see any issues. Thanks for any help.
jQuery
$(function(){
$('#shipping_form').on('submit', function(e){
e.preventDefault();
var ship = $('input[name="shipping_val"]').val();
$.ajax({
type: 'GET',
data: { discount: ship },
success: function(data) {
//go to next section
}
});
return false;
});
});
HTML/PHP
<?php
Session_start();
if(isset($_GET['shipping_submit'])){
$shipping_get = $_GET['shipping_val'];
}else{
$shipping_get = '3.99';
}
$_SESSION['shipping'] = $shipping_get ;
?>
<html>
<main class="container">
<form method="GET" name="shipping_form" id="shipping_form" action="">
<p>Please choose your prefered shipping method.</p>
<input type="radio" name="shipping_val" value="3.99" checked>
<label for="shipping_val">
Standard delivery
</label>
<input type="radio" name="shipping_val" value="6.99" >
<label for="shipping_val">
Express delivery
</label>
<button type="submit" id="shipping_submit" name="shipping_submit" >Update</button>
<?php
echo '<h1>' . $_SESSION['shipping'] . '</h1>';
?>
</form>```
Your problem is likely that you are using AJAX to submit data to the same file you are calling it from. Your ajax end point (PHP-side) needs to be a different PHP file.
See this other question:
values not updated after an ajax response
I have a registration form and I want to display all of the registrants. I want to output whatever records are in the database and then once the form is submitted to register another display that record as well.
I can successfully register the records and display them using ajax however It does not load the last registered record until you reload/comeback to the page. I want the last record to just join its brethren right after the form submits. I appreciate anything you can suggest.
home.php
<form id="register-student" method="post" action="process_student_registration.php" class="basic-form not-toggled">
<h2>Enter Student Info to Register</h2>
<fieldset id="student-name-group" class="form-group">
<div class="split">
<fieldset id="student-firstname-group">
<label for="student-first-name">First Name:</label>
<input id="student-first-name" type="text" name="student_first_name">
</fieldset>
</div>
<div class="split">
<fieldset id="student-lastname-group">
<label for="student-last-name">Last Name:</label>
<input id="student-last-name" type="text" name="student_last_name">
</fieldset>
</div>
</fieldset>
<fieldset class="submit-button">
<div id="loading" class="hidethis"><img id="loading-image" src="../../images/ajax-loader.gif" alt="Loading..." /></div>
<button id="register-student-button" type="submit" class="btn btn-success" name="register-student-button">Register Student</button>
</fieldset>
</form>
<script>
$(document).ready(function() {
var students = $.ajax({ //create an ajax request to load_page.php
type: "GET",
url: "fetch_students.php",
dataType: "html", //expect html to be returned
success: function(response){
$("#registered-students").html(response);
//alert(response);
}
});
});
</script>
<div id="registered-students"></div><!--End # registered-students-->
fetch_students.php
<?php
//Fetch the Students
//First lets make sure the user is allowed
require_once('../auth/agency_session.php');
//App Functions
require_once('../../includes/functions/app_functions.php');
//Agents Home Page
require_once('../../db_config.php');
$db_connect = connectDB($mysqli);
$agency_id = $_SESSION['ID'];
//Here we display all the students the agent has registered
//First check the connection
if(!mysqli_connect_errno()){
if($stmt = $db_connect->prepare("SELECT student_id, student_first_name, student_last_name, student_email FROM students WHERE agency_id = ?")){
//Bind Parameters
$stmt->bind_param('i', $agency_id);
//Execute
$stmt->execute();
//Store Results
$stmt->store_result();
//Get the rows
$num_rows = $stmt->num_rows;
//Bind the results
$stmt->bind_result($student_id, $student_first_name, $student_last_name, $student_email);
if($stmt->num_rows < 1){
echo'<h3>No Students Registered</h3>';
}
else{
//Fetch the values
echo'<h3>Registered Students</h3>';
echo'<ul class="grid">';
while($stmt->fetch()){
echo '<li id="'.$student_id.'" class="col">'.$student_first_name.' '.$student_last_name.'<span>'.$student_email.'</span></li>';
}//End While
echo'</ul>';
}//End else
}//End if no prepare statment happens
}//End if No connection
?>
process_student_registration.php
jQuery(document).ready(function($){
// Get the form and place it into a variable
var form = $('#register-student');
//Creating an Event Listener for the submit buttom on the contact form
$(form).submit(function(event){
$('.form-group').removeClass('.has-error');//Remove the error class on the things that have the error class
$('.error-message').remove();//Remove the error messages completeley
//Serialize the Form Data (Converts the data the user has entered into a key/value string that can be sent with an AJAX request)
var formData = $(form).serialize();
//Submit the form using AJAX
$.ajax({
type: 'POST',
url: $(form).attr('action'),
data: formData,
dataType :'json',
encode:true
//.done refers to a successful completion of the form
})
.done(function(data){
//Log the data into the console so that we can be sure what is happening
console.log(data);
//If we do have errors create the
if(!data.successmessage){
if(data.errors){
$('.error').remove();
$('.error-message').remove();
$('#register-student').addClass('form-has-error'); // add the form-has-error-class
$('#register-student-button').after('<p class="error">Please check the errors above.</p>');
$(form).removeClass('success');
$('.submit-success').remove();
if(data.errors.student_first_name){
$('#student-firstname-group').addClass('has-error'); // add the error class to show red input
$('#student-firstname-group').append('<div class="error-message"><p>' + data.errors.student_first_name + '</p></div>'); // add the actual error message under our input
}
if(data.errors.student_last_name){
$('#student-lastname-group').addClass('has-error'); // add the error class to show red input
$('#student-lastname-group').append('<div class="error-message"><p>' + data.errors.student_last_name + '</p></div>'); // add the actual error message under our input
}
}
} else if(data.successmessage){
//Remove the errors stuff
$('.error').remove();
$('.error-message').remove();
$('#register-student').removeClass('form-has-error'); // add the form-has-error-class
$('#blocking').removeClass('hidethis').addClass('showthis');
$('#loading').removeClass('hidethis').addClass('showthis');
$('.submit-success').remove();
//Add the success stuff
$(form).addClass('success');
setTimeout(function(){
$('#blocking').removeClass('showthis').addClass('hidethis');
$('#loading').removeClass('showthis').addClass('hidethis');
$('#register-student').append('<div class="submit-success"><p>' + data.successmessage + '</p></div>');
$(form).find('input, :text').val('');
//Run the Get operation on the database to add newly added records to the list
}, 5000);
//Clear the form upon successful completion
}
//.fail referes to an unsuccessful completion of the form
})
.fail(function(data){
//If there is a failed submission lets log the errors
console.log(data);
});
//Stop the broweser from submitting the form
event.preventDefault();
});
});
I had a similar issue... you are processing from two different php file:
process_student_registration.php and fetch_students.php
I believe your problem might be solved if you do all the processing from one file:
You are only passing two pieces of data. Rather than collecting the data from a form you can collect the data through inputs and go straight to the jQuery.
Your Collection HTML would look like this: NOTICE the dashes replaced with underscores.
<h2>Enter Student Info to Register</h2>
<input type="hidden" id="processStudent" value="process_student_registration.php">
<fieldset id="student-name-group" class="form-group">
<div class="split">
<fieldset id="student_firstname_group">
<label for="student_first_name">First Name:</label>
<input id="student_first_name" type="text" name="student_first_name">
</fieldset>
</div>
<div class="split">
<fieldset id="student_lastname_group">
<label for="student_last_name">Last Name:</label>
<input id="student_last_name" type="text" name="student_last_name">
</fieldset>
</div>
</fieldset>
<fieldset class="submit_button">
<div id="loading" class="hidethis"><img id="loading_image" src="../../images/ajax_loader.gif" alt="Loading..." /></div>
<button id="register_student_button" type="submit" class="btn btn_success" name="register_student_button">Register Student</button>
</fieldset>
<div id="registered-students"></div>
Your jQuery...
<script>
$(document).ready(function() {
$( "#register-student-button" ).click(function(){
var url = $('#processStudent').val();
var student_first_name = $('#student_first_name').val();
var student_last_name = $('#student_last_name').val();
var postit = $.post( url, {student_first_name:student_first_name,student_last_name:student_last_name});
postit.done(function( data ) {
alert('Student has been processed');
$('#registered-students').html(data);
});
});
});
Your PHP...
<?php
$student_first_name = $_POST['student_first_name'];
$student_last_name = $_POST['student_last_name'];
// PROCESS REGISTRATION HERE AS YOU ARE
// FETCH STUDENTS HERE AS YOU ARE
?>
I have figured out a solution. Basically I run the script to display records fomr the database on once on page load. Then I took basically the same script again and run it once more upon successful completion of the form. This way we only scan the database for new records as we need to. Not sre if it the most elegant or efficient way but she work like a charm.
So in my process_student_registration.php I added this to the success message.
//Run the Get operation on the database to add newly added records to the list
$.ajax({ //create an ajax request to load_page.php
type: "GET",
url: "fetch_students.php",
dataType: "html", //expect html to be returned
success: function(response){
$("#registered-students").html(response);
//alert(response);
}
Im building a login/register system using javascript to show particular divs for the system e.g
1st div = menu option to either login or register
2nd div = depending on what was clicked (login or register) shows login form or register form
3rd div = shows when user has successfully registered/logged in
the script looks like this:
html:
<article id="container">
<div id="load-new" class="game_menu">
<h1>LOAD/NEW</h1>
<button id="new_but" type="button">New Game</button>
<button id="load_but" type="button">Load Game</button>
</div>
<div id="reg" class="game_menu">
<h1>REGISTER</h1>
<form name="register" method="post" action="">
<label for="usernamesignup" class="uname">Your username</label>
<input id="usernamesignup" name="usernamesignup" required="required" type="text" placeholder="Username" />
<label for="emailsignup" class="youmail"> Your email</label>
<input id="emailsignup" name="emailsignup" required="required" type="email" placeholder="domain#mydomain.com"/>
<label for="passwordsignup" class="youpasswd">Your password </label>
<input id="passwordsignup" name="passwordsignup" required="required" type="password"/>
<label for="passwordsignup_confirm" class="youpasswd">Please confirm your password </label>
<input id="passwordsignup_confirm" name="passwordsignup_confirm" required="required" type="password"/>
<button id="reg_submit" type="button">Register</button>
</form>
</div>
<div id="login" class="game_menu">
<h1>LOGIN</h1>
<form name="login" method="post" action="">
<label for="username" id="username_label">Username:</label>
<input type="text" name="username" id="username" value=""/>
<label for="password" id="password_label">Password:</label>
<input type="password" name="password" id="password" value=""/>
<button id="login_submit" type="button">Login</button>
</form>
</div>
<div id="access" class="game_menu">
<h1>ACCESS</h1>
<button id="login_but" type="button">Login</button>
<button id="reg_but" type="button">Register</button>
</div>
<canvas id="TBG" width="640" height="416">
Please use a more up to date browser
</canvas>
the javascript looks like this
main.js:
//----------Login/Register Gui --------------
$('#load-new').hide();
$('#reg').hide();
$('#login').hide();
//create new instance of gui class
var ui = new Gui();
//if login_but is clicked do ui.login function
$('#login_but').click(ui.login);
//if reg_but is clicked do ui.register function
$('#reg_but').click(ui.register);
//if login_sumbit button is clicked do ui.login_ajax function
$("#login_submit").click(ui.login_ajax);
$("#reg_submit").click(ui.register_ajax);
gui.js:
function Gui (){
var valid = 'true';
var invalid = 'false';
//hide access div, show login div
this.login = function()
{
$('#access').hide();
$('#login').show();
};
//hide access div, show register div
this.register = function()
{
$('#access').hide();
$('#reg').show();
};
//function to send login data to php script login.php
this.login_ajax = function()
{
//username user inputted
var username = $("#username").val();
//password user inputted
var password = $("#password").val();
//inputted data made into JSON string
var dataString = {"reg":invalid, "login":valid, "username":username ,
"password":password};
//AJAX Request to login.php
$.ajax({
type:"POST",
url:"PHP/class.ajax.php",
data: dataString,
dataType: 'JSON',
success: function(success) {
alert("Your are logged in");
if(success == 'true'){
$('#login').hide();
$('#load-new').show();
}
},
error: function(){
alert("ERROR in AJAX");
}
});
};
this.register_ajax = function()
{
var username_signup = $("#usernamesignup").val();
var email_signup = $("#emailsignup").val();
var password_signup = $("#passwordsignup").val();
var password_signup_confirm = $('#passwordsignup_confirm').val();
var dataString = {"reg":valid, "login":invalid, "username_signup":username_signup,
"email_signup":email_signup,
"password_signup":password_signup, "password_signup_confirm":password_signup_confirm};
$.ajax({
type:"POST",
url:"PHP/class.ajax.php",
data: dataString,
dataType: 'JSON',
success: function(success) {
alert("You are registered");
if(success == 'true'){
$('#reg').hide();
$()
$('#load-new').show();
}
},
error: function(){
alert("ERROR in AJAX");
}
});
}
}
i use ajax to send requests to php scripts to process login or register.
the script that the ajax requests is simple a go between so i can select specific functions in either the login php or register php.
i would like to have an are in my html to show if a user is logged in or not a bit like the are in the top right on the runescape website : here.
now i tried this php in my header.php file:
if(isset($_POST['username'])){
$is_logged_in = '<div id = "user_box">Welcome '.$_POST['username'].'</div>';
}
else
{
$is_logged_in = '<div id = "welcome_box">Welcome friend!</div>';
}
but obviously this wouldnt work because the page doesnt refresh where im using javascript to show different parts of the menu.
MY QUESTION:
What would be the most pratical way to achieving this effect with the javascript/php system i have in place?
Would i use javascript to hide/show divs like i have with the menu divs? or is there a function i can use to refresh the page without it sending me back to the first menu div?
Thanks for your time
Tom
Right now you are only sending back one value from the php scripts that you are calling using ajax, you are only using true for a successful login or registration.
What you could do, is modify these scripts to return multiple values. So apart from the true value for a successful login, you also send the username and then in your javascript you use that username to build a html block to show in the top area where you want to show the username.
You are already using json, so you only have to generate an array with return values in your php script and use echo json_encode($your_return_values); to send it to your javascript success variable.
By the way, you can use jquery / javascript to replace and build whole sections of your html, you don't need to put everything in at the start just to hide it.
If I'm understanding your question correctly your wanting to indicate to the user that they are logged in without reloading the page and by displaying a div in the top right corner.
That being the case you could create a hidden div with an absolute top right position which would be something like:
<div id="welcome" style="display:none; postion:absolute; top:0; float:right;">...</div>
In the 'success:' portion of the ajax request above, add a call to a new js function that makes a separate ajax request to retrieve a json object containing the logged in users display name and any other information that you want to show. Using that json data you could then populate 'welcome' div accordingly and change it's display to block.
I am trying to send Push Notifications to android devices using a php script. This works fine if i send it to one device each time, but i have more than 1000 devices and want to send it to all of them at one go. I tried using a loop but it's not working.
<script type="text/javascript">
$(document).ready(function(){
});
function sendToAll(totalUsers){
for(var i=0;i<totalUsers;i++)
{
sendPushNotification(i);
}
}
function sendPushNotification(id){
var data = $('form#1').serialize();
$('form#1').unbind('submit');
$.ajax({
url: "send_message.php",
type: 'GET',
data: data,
beforeSend: function() {
},
success: function(data, textStatus, xhr) {
$('.txt_message').val("");
$('.txt_excerpt').val("");
},
error: function(xhr, textStatus, errorThrown) {
}
});
return false;
}
</script>
This is my HTML form. $no_of_users variable contains the total rows fetched in the select query i.e. the total number of users in the table.
<form id="1" name="" method="post" onsubmit="return sendToAll('<?php echo $no_of_users; ?>')">
<label>Send Message to All the Users</label>
<div class="clear"></div>
<div class="send_container">
<textarea rows="3" name="excerpt" cols="10" class="txt_excerpt" placeholder="Type excerpt here"></textarea>
<textarea rows="3" name="message" cols="25" class="txt_message" placeholder="Type message here"></textarea>
<input type="submit" class="send_btn" value="Send" onclick=""/>
You should use asyncronous requisitions to make all at "same time", use this instruction on your ajax call:
async: true,
You want to push some message to approx. 1000 devices from server. And you want to initiate this with the form and script you presented in the question. But you must also think about the way how server will communicate with devices. There must be some way for you server to reach clients.
One way - instruct you clients to poll server for new messages every N seconds for example. This generates unnecessary traffic and loads the server.
Second way - to use websocket on clients and have server-side support for this. It can be not so trivial as it can appear to be
And one more way - is to use long polling.
Anyways - devices must be instructed in some way how can they receive push messages from server.
i have a "wall" on each profile, and i wish to make it smarter, so you don't need to update the page to view your inserted message you just put up.
When you insert a message, it makes a ajax call and inserts to the database, and you receive a message about it has been inserted. But right now you need to refresh the page to see your inserted message. What i want to do is if you insert a new message, it should fadein /refresh the wall with messages that is right under the form.
How can I do this?
I have worked on it alittle and tried to make a new file, inserted all coding to show comments and then i set timeout to refresh each 2 seconds
function ajax_update() {
var wrapperId = '#box';
var profileID = document.getElementById('profileID');
var postFile = 'showcomments.php?id='+ profileID.value;
_v++;
_v2++;
$.post(postFile, { v2: _v2 , v: _v},
function(data){
$(wrapperId).html(data);
});
setTimeout('ajax_update()', 2000);
}
but this isnt good, as it makes too many server calls, so hope you can help me out, since i dont know how i should do this in a cool way
Form with ajax call:
http://phpbin.net/x/838833504
And my current php code that grab from db and list in messages:
http://phpbin.net/x/2145692361
I would suggest a slight methodology change:
submit the new post to the database via AJAX
in the success callback for that AJAX post, create an element with the content that was submitted and append it to the list of posts on the page.
if you want it to look cool just use some of the built in animation effects (fadeIn, show, etc).
This way, you're not polling for changes all the time, and you only have to request things from the server upon page loads.
function DoWallInsert(){
var wrapperId = '#box';
var profileID = document.getElementById('profileID');
$("#insert_response").html("Laddar..");
$.ajax({
type: "POST",
url: "misc/insertWall.php",
data: {
value: 'y',
BuID : $('#BuID').val(),
uID : $('#uID').val(),
message : $('#message').val()
},
success: function(msg){
// in here you will have to add the message to the top of the list of wall posts
// to do this you use prepend whatever html and the message in whatever way you
// are using to display the messages.
$(wrapperId).prepend("<div>" + $('#message').val() + "</div>");
}
});
}
html might look like this before:
<form action="javascript:DoWallInsert()" method="post">
<input name="message" type="text" id="message" value="" size="40">
<input type="hidden" name="BuID" id="BuID" value="123123">
<input type="hidden" name="uID" id="uID" value="53425">
<input name="submit" type="submit" id="submit" value="Skicka">
</form>
<div id="box">
<div id="post-1">Some stuff</div>
<div id="post-2">Some other stuff</div>
</div>
html should look like this after:
<form action="javascript:DoWallInsert()" method="post">
<input name="message" type="text" id="message" value="" size="40">
<input type="hidden" name="BuID" id="BuID" value="123123">
<input type="hidden" name="uID" id="uID" value="53425">
<input name="submit" type="submit" id="submit" value="Skicka">
</form>
<div id="box">
<div>Whatever was typed in the box</div>
<div id="post-1">Some stuff</div>
<div id="post-2">Some other stuff</div>
</div>
If the html you want to append to the list of posts has php in it then my best suggestion is to return the html for the new div in the response from the server on the on the AJAX call to this: misc/insertWall.php
insertWall.php should return "<a href='profil.php?id=".$userinfo[id]."'>".$userinfo["full_name"]."</a>". then you can process it and display it in the success part of DoWallInsert():
success: function(msg){
// in here you are receiving a response, you should display it in the page
// this assumes that you are fully formatting the message before returning it
// and you just want to insert it here.
$(wrapperId).prepend(msg);
}
One way is to return the newly updated wall listing from your .post() handler on the server. Then in the callback, repaint the wall area with that content (forget about using setTimeout()). You could also do the same thing, but working message by message, adding the latest message to the top of the "stack" in your wall content area.
So, repainting the whole wall:
$.post(postFile, { v2: _v2 , v: _v},
function(data){
// make your server return the updated wall content
// return data.whatever
// data.wallcontent
$('#wrapperId').html(data.wallcontent);
});
or message by message:
$.post(postFile, { v2: _v2 , v: _v},
function(data){
// make your server return the new message ready for insert
// return data.whatever
// data.message_you_just_posted_formatted
$('#wrapperId')
.prepend( data.message_you_just_posted_formatted );
});
That's the basic idea.