i've got a simple question here,
Ive got this form thats inside my chat html:
<form action="../addchat.php" method="POST" enctype="multipart/form-data">
<textarea id="textarea" style="border-radius:0px; border:none; background-color:rgb(243,243,243); min-height:100px;"name="comment" rows="4" cols="50"></textarea><br>
<input height="25px" width="20px" style="float:right;" type="image" src="../arrow.png" name="submit" value="Comment">
</form>
This form is for users to submit their chat messages. and after which, form post will direct the information to addchat.php, which contains the following code:
<?php
ob_start();
session_start();
include_once("config.php");
$reply=mysqli_real_escape_string($mysqli,$_POST['comment']);
$cid=mysqli_real_escape_string($mysqli,$_SESSION['cid']);
$uid=mysqli_real_escape_string($mysqli,$_SESSION['userid']);
$time=time();
$ip=$_SERVER['REMOTE_ADDR'];
$q= mysqli_query($mysqli,"INSERT INTO conversation_reply (user_id_fk,reply,ip,time,c_id_fk) VALUES ('$uid','$reply','$ip','$time','$cid')") or die(mysqli_error($mysqli));
?>
This script obviously adds the data into the tables and after which another script on the chat html page will display out the chat messages.
However, the current issue is that firstly, after user click submit, page will redirect to another blank page and show success message. Secondly, user need to refresh to see the new chat messages.
This chat application is a private chat (similar to Facebook), so not very sure how to do it? Would appreciate some help:)
If you do not want it to redirect. Move the PHP code to the same file as the form. You could use include for this.
Then make the form action="".
Then around the PHP, you need to check that the POST exists so it only runs when the form submits:
e.g.
if (!empty($_POST))
As for the refresh problem. You may want to look into AJAX or even socket.io.
It is not simple to answer this question, as it belongs to how hard/complex you want in your chat application.
If you don't want to get redirect when submitting, you can use AJAX to post the form Submit a form using jQuery
If you don't want to refresh the page to load new chat messages, you can use AJAX call to get new messages in interval of time http://www.w3schools.com/jsref/met_win_setinterval.asp.
If you want to receive new chat messages at the time they are sent from sender (who is chatting with current user), you might consider about using push server like NodeJS (http://nodejs.org) or Socket.io (http://socket.io/)
I wouldn't use PHP for that purpose if I were you, or if you do, you'll need lot of ajax to make this chat working.
ajax request to send... ajax request every n milliseconds to fetch new messages. you should also use an api instead of a webpage to interact with your server-side app. Your server will need to be highy available and respond really fast.
You should choose a language that support websockets (take a look at python with django, for example, or java, or whatever...) if you want this chat to be really efficient.
While writing these lines I found something (Ratchet library)to use websocket in php (I don't know how it works but maybe you'll get problems with the max_execution_time of your server if it works with a "while true" loop)
Edit: as Tuan Duong suggests, nodejs is another good alternative
standard html form submissions always will submit (and redirect) to the page defined in the action attribute of the form. with jquery you can prevent this default behavior plus send the form-data with ajax:
$("form").on("submit", function(event){
event.preventDefault();
$.ajax({
url: "../addchat.php",
type: "POST",
cache: false,
data: {
comment: $("#textarea").text()
},
success: function(data){
//something you could do on success of your ajax call.
//you might not need it in this case.
}
});
});
secondly, you'll need some procedure that refreshes your output-area automatically. create a div in your html to show the chat-output:
<div id="chat_content_div"></div>
then you'll have to do something like this in your javascript to refresh it automatically:
var refresh_time = 500; // chat refresh time in ms
setInterval(function(){
$.ajax({
url: "chat_output.php",
type: "GET",
dataType: "html",
cache: false,
success: function(data){
$("#chat_content_div").html(data);
}
});
}, refresh_time);
in the "chat_output.php" you only display (html) data from the database to be displayed in this div.
Related
I'm building my own custom login page for wordress. The login form seems to work, however I would like to be able to customize the error message more specifically.
When the login credentials are incorrect and you log in, the error message appears only after the page has reloaded. What I would like to do is show the error message without reloading the page.
I searched on stackoverflow and wordpress reference but couldn't find a solution for my case. Anyone have a suggestion on how I might achieve my goal?
Thanks for any replies, I appreciate any help.
Update 2
I thank the users who helped me with their answers, they were very helpful and I really appreciate it. I literally spent all day on this problem, I finally achieved my goal. The ajax request works and the message is displayed as I wanted. I had to go through a lot of things several times. However I leave the updated code for anyone who needs help.
My custom_login_page.php file
This contains the html structure, the form and the script that executes the ajax requests. Put the file in your active child theme. In my case I called the custom_login_page.php file. For this to be read by wordpress you need to create a new page and select it as a template.
<?php
// Template Name: Custom Login Page
?>
<?php get_header(); ?>
<div class="container_main">
<?php if (is_user_logged_in()) {
?><span>Sei gia loggato</span><?php // If the user is logged in, it shows the message below
} else { // otherwise, if the user is not logged in, it shows the login form
?>
<form id="login" action="login" method="post">
<!-- Message error -->
<p class="status"></p>
<!-- Username -->
<label for="username">Username</label>
<input id="username" type="text" name="username">
<!-- Password -->
<label for="password">Password</label>
<input id="password" type="password" name="password">
<!-- Link Recover -->
<a class="lost" href="<?php echo wp_lostpassword_url(); ?>">Lost your password?</a>
<!-- Submit Button -->
<input class="submit_button" type="submit" value="Login" name="submit">
<?php wp_nonce_field( 'ajax-login-nonce', 'security' ); ?>
</form>
<?php
} ?>
</div>
<?php get_footer(); ?>
<script>
jQuery(document).ready(function($) {
// Perform AJAX login on form submit
$('form#login').on('submit', function(e){
$('form#login p.status').show().text(ajax_login_object.loadingmessage);
$.ajax({
type: 'POST',
dataType: 'json',
url: ajax_login_object.ajaxurl,
data: {
'action': 'ajaxlogin', //calls wp_ajax_nopriv_ajaxlogin
'username': $('form#login #username').val(),
'password': $('form#login #password').val(),
'security': $('form#login #security').val() },
success: function(data){
$('form#login p.status').text(data.message);
if (data.loggedin == true){
document.location.href = ajax_login_object.redirecturl;
}
}
});
e.preventDefault();
});
});
</script>
My functions.php file
In functions.php I put the functions linked to the form and some redirects useful when doing logine logout.
/* Redirect Custom Login Page */
function redirect_custom_login_page() {
wp_redirect(site_url() . "/login");
exit();
}
add_action("wp_logout", "redirect_custom_login_page");
/* Redirect wp-admin & wp-login php */
add_action("init","fn_redirect_wp_admin");
function fn_redirect_wp_admin(){
global $pagenow;
if($pagenow=="wp-login.php" && $_GET['action'] !="logout"){
wp_redirect(site_url()."/login");
exit();
}
}
/* Ajax Form Login */
function ajax_login_init(){
wp_register_script('ajax-login-script', get_template_directory_uri() . '/ajax-login-script.js', array('jquery') );
wp_enqueue_script('ajax-login-script');
wp_localize_script( 'ajax-login-script', 'ajax_login_object', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'redirecturl' => home_url(),
'loadingmessage' => __('Sending user info, please wait...')
));
// Enable the user with no privileges to run ajax_login() in AJAX
add_action( 'wp_ajax_nopriv_ajaxlogin', 'ajax_login' );
}
// Execute the action only if the user isn't logged in
if (!is_user_logged_in()) {
add_action('init', 'ajax_login_init');
}
function ajax_login(){
// First check the nonce, if it fails the function will break
check_ajax_referer( 'ajax-login-nonce', 'security' );
// Nonce is checked, get the POST data and sign user on
$info = array();
$info['user_login'] = $_POST['username'];
$info['user_password'] = $_POST['password'];
$info['remember'] = true;
$user_signon = wp_signon( $info, false );
if ( is_wp_error($user_signon) ){
echo json_encode(array('loggedin'=>false, 'message'=>__('Wrong username or password.')));
} else {
echo json_encode(array('loggedin'=>true, 'message'=>__('Login successful, redirecting...')));
}
die();
}
Introduction
I will briefly describe how HTML forms work, why your page is reloading and how you can communicate with the server without reloading your page, finally, how you can update your page based on this communication.
How HTML forms work
When you create a form tag and a structure into it, with a button of submit type inside of it, specifying an action (or using the default), then, upon clicking on the button mentioned earlier, your form is submitted. On submitting your form, all elements inside the form, having a name attribute (i.e. name="somename") is picked up and a request will be sent to the specified action (defaulting to the same page), where the form data will be represented as key-value pairs, the keys being the names of your form elements and the values being the values of the elements.
Upon form submit, your browser will send a request to the target of the form. The action of the form (if valid) will pick up the request, handle it and respond to your browser.
When the browser receives this response, it will display it as the content of the page. The users experience this behavior as a page reload. You are bothered with this behavior, as you described in your question and you would prefer to have a less obtrusive, smoother behavior. This is possible with AJAX requests.
AJAX
AJAX requests are well-documented, so, if you are unfamiliar with them - which surely is the case -, then I advise to read the content of the link I have given you above and gain some experience with AJAX. If you get stuck with it, let me know your blocker, but, for now, I will assume that the tutorials clarify the matter for you and in a reasonable amount of time you will successfully learn how to tackle them.
You can also communicate with your server (without page reload) with push notifications or websockets, but since this is a request-response use-case, I strongly advise the use of AJAX. Since AJAX stands for Asynchronous Javascript and XML, the asynchronous part suggests that you are calling an asynchronous function that you do not wait for, that is, your request is being sent to the server and there is an event to handle the server response, upon which you can specify function(s) to be executed, known as the callback(s).
If you are going to have an AJAX request, then you do not necessarily need the form and the submit button is definitely not needed, instead, you could use an input type="button" with a click event handler that will pick up the data and send the request.
How to handle server responses
The simplest way to handle the requests is to just take the (HTML) response and refresh your page content for the regions you want to update (without page reload, of course). But this is not necessarily ideal.
If your structure does not change, but your content does, then it makes much more sense to change your server code to just send the content as JSON (Javascript Object Notation) and update only the content of your page. This approach ensures that your server does not have to send very large, superfluous responses to your browser if it's unnecessary. Instead, it just sends the data, reducing the load of your server's networking and, as a result, making your server more scalable. But this means that your browser will have to update the content itself, which is no longer automatic and you need to code the behavior in a client-side language, such as Javascript.
How you should proceed
Since all this is obviously new to you, I advise you to start with the simplest approach, to have some success that will boost your morale, that is, at first stage, send the request as AJAX, the server should only respond with the inner HTML of the body tag, rather than the whole HTML and you could do a
document.body.innerHTML = response;
in your callback.
The reasonable expectation is that your page is not reloaded by the browser, but it is refreshed. If you reach this stage, then you might decide that it is good-enough for you, or you can decide to improve it, change the server-side to respond to the AJAX request with a JSON and implement some client-side functions to handle the request and refresh the content.
I of course advise the latter, but you of course have the liberty of choice here.
Now, let's understand what a request method is.
A GET request is a request defined by a URL (Unified Resource Locator) and the parameters are passed as GET parameters, that is, inside the URL, after the ? mark, like
https://www.yourpage.com?yourparameter=yourvalue&yoursecondparameter=yoursecondvalue
A POST request is a request where POST parameters can also be defined. In PHP you have neat ways to determine the request type, see this excellent page: Detecting request type in PHP (GET, POST, PUT or DELETE)
Now, when you load the page for the first time, a GET request is being send. Once the form is submitted (via AJAX), you need to specify that you are sending a POST request and then the server will know that it will need to send only the data (rather than the HTML) as a response.
What you want isn't achievable using PHP. As quick explanation, PHP is a server side scriptiong language, which means that only the server can execute your code. So whenever you press Login is has to go to the server (doing a request) and then you'll get back the new HTML from your server.
How to do this
Is quite an investment but if you really want to learn or build this you should look into Javascript AJAX requests. In a nutshell, AJAX is how you communicate with your server without any page reload.
Alternative
You could also try to use some plugins that try to do this. I have no experience with them but here's one that claims to do exactly what you want: https://nl.wordpress.org/plugins/login-with-ajax/
If that one doesn't fit your needs, you can at least continue searching using the term AJAX.
I hope this helps :)
TLDR
With PHP, you can't. Use an AJAX WordPress plugin or build a custom solution using Javascript and AJAX.
I'm trying to write a feature for my Fantasy Football league that allows players to trade with each other. Functionally it all works fine, but as I've coded it all in PHP I have an annoying problem where any time a button is pressed the page is effectively refreshed twice. I've read that I can get around this with jQuery and Ajax but sadly I don't really have any experience with either.
Here's a small section of the code that allows logged in users to withdraw a trade offer they have made:
echo "<input type='submit' id='btn-danger' name='withdraw".$trade_id."' value='Withdraw'>";
if($_POST && isset($_POST['withdraw'.$trade_id])) {
$withdraw = $link->prepare("DELETE FROM trade_id_offers_out WHERE trade_id_offer_id = ".$trade_id);
$withdraw->execute();
}
This creates a "Withdraw" button for each trade offer they have sent out and has a unique name of "withdraw" plus whatever number the offer is in the SQL table.
As I say functionally it works perfectly fine. But it refreshes the page twice and I'm wondering how I can take this code and turn it into something a little more practical?
Many thanks for your time.
First you should make sure you have included jQuery into your page html before any other jQuery (there are plenty of tutorials out there).
Second you need to give the submit button a class so you can select it using a jQuery selector. Change the php code of the button to this:
echo "<input type='submit' id='btn-danger' class='withdrawTradeBtn' name='withdraw".$trade_id."' value='Withdraw'>";
Finally you would make a ajax post request to your url (same url as your page in this case). The js would look something like this and would need to be placed before the end of the html body tag or after all your buttons are rendered:
(Note: I have not tested this but it should be pretty close to what you are after)
<script>
//we need to wait for the page to be loaded in the users browser
$(document).ready(function(){
//we are selecting all the buttons with the class withdrawTradeBtn
//we are binding to the click event so whenever any of the buttons are pressed the code will be ran.
$('.withdrawTradeBtn').on('click', function(e){
//we need to prevent the button from actually reloading the page
e.preventDefault();
//now we need to make a ajax post request to the url
$.post(
'/your/url', //the url to make the post
{$(this).attr('name'):'Withdraw'}, //the submitted data
function(data, status, jqXHR) {// success callback
//here is were you would delete the button or whatever
}
);
});
});
</script>
Most likely you would want to delete the trade entry from the html. You would do that in the success callback of the ajax post. I cant really add anything here because I don't know what your html structure looks like.
Hope this helps, let me know if you need any more help!
I have two pages. mobile.html and video.php. mobile.html sends an ajax post request with a single variable. video.php should read that variable and pass it to a JS function in the same page that would change a video control. I tried to use this logic:
mobile.html sends an ajax post request
video.php has PHP code inside a div to read the request and get the variable
reload video.php and allow the JS code in the same page to get the variable from inside the div
pass the variable to the intended JS function in video.php.
execute the function on the video.
here is my code and for simplicity I replaced the video with <p> tag. mobile.html code works fine. my problem is in video.php
mobile.html
$.post("video.php", {gesture: action}, function(response){
$("#result").html('response: '+response);
});
video.php
<html>
<head>
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
//a div to hold the value of post variable
<div id="dom-target" style="display: none">
<?php
if ( $_SERVER['REQUEST_METHOD'] == 'POST' )
{
if( isset($_POST["gesture"]))
{//put the variable value inside the div to fitch it later
$gesture = $_POST["gesture"];
echo $gesture;
}
else {
echo "none";
}
}
else {
echo json_encode("PHP no post");
}
?>
</div>
//p content should be updated with the value of $gesture
<p id="update">
should be updated with post variable using JS
</p>
<script>
//get post variable from the div
var div = document.getElementById("dom-target");
var myData = div.textContent;
$("#update").html(myData);
console.log("myData: "+myData);
</script>
</body>
</html>
I have been up over my head for a week trying to work around this problem but I cannot seem to get the result that I want because when I reload the page I find my variable in the ajax callback function :/
the output I am getting currently is "PHP no post" in video.php and myData: "PHP no post" in the console of video.php which is ok because obviously the first time I run the page it is not through a post request. however when I click the button that triggers the post request in mobile.html I get the output of this line console.log("myData: "+myData); with the correct data but in mobile.html console! not in video.php console. meaning that the code is run in the callback function of the ajax post request in mobile.html.
I failed to find a way to update the <p id="update"> in the currently opened video.php page. Now I am not even sure I can do it with PHP since it runs only on a server and JS runs only on the web browser.
My question is: can I do the steps explained above using PHP ?
IF YES can you help me figure out a way to dynamically and instantly update the video.php page using a post call sent from mobile.html ? or any other way that would work with PHP?
IF NOT can you suggest what other languages/platforms I can use to do what I want to do ?
UPDATE:
to have an idea of what I want to achieve, I did two pages using localstorage. open mobil.html in one window and then openvideo.html
in another window side by side. play the video then use the controls on mobile.html and see how it changes the playback in video.html.
I want to be able to do the same thing but remotely using PHP because I have to use a real mobile instead of mobile.html
You are sending your gesture value to the video.php file, but you are not using it to get a new paragraph element with the updated value in it. PHP should do its work on the server and JavaScript strictly on the frontend.
Keep your POST request the same.
$.post("video.php", {gesture: action}, function(response) {
$("#result").html('response: ' + response);
});
But modify the response that server returns. The gesture value is in the $_POST array. From there you can use it to render a new paragraph and echo or return this to the frontend.
<?php
// Set default value.
$gesture = 'none';
if ( isset( $_POST[ "gesture" ] ) ) {
// Overwrite if there is a gesture value.
$gesture = $_POST[ "gesture" ];
}
// Echo a new paragraph with the gesture in it.
echo '<p id="update">' . $gesture . '</p>';
exit;
?>
first just please organize the code a little bit so you can see the code well
you need to put the post request inside a function with a trigger action because with that it would be never called
you need to make sure that you are getting the correct data in 'action' variable (console.log it before the post)
(if $.post is not working for some reason download jquery and use it locally because it might not be in the slim CDN)
Hint:
$( document ).ready(function() {
console.log(gesture); //check this in the console after refreshing the page
$.post("video.php", {gesture: action}, function(response){
$("#result").html('response: '+response);
});
});
I am answering my own question for those who have been rumbling about not understanding how to update a part of a web page in real time without having to reload it. Long story short, To achieve the scenario I mentioned in my question I have to use WebSockets as #EmielZuurbier pointed out in the comments of the first answer, so thanks to him.
There are tons of ways to do that.For beginners, you have to be patient and make sure you understand how it works properly before you jump in coding. Also, know that some codes that are available on the internet work only on the backend and that there are specific ways to make websockets work on a browser. In my case I used Node.js in the server side and isomorphic-ws in the client side in a web browser
here are some helpful references that helped me during the past week:
Here is the official site for Node.js for installation and documentation.
This is a good video to get you started if you are new to WebSockets. it explains Websockets and display real implementation of it.
Here you can find documentatino of WebSocket().
This video demonstrate how to implement a websocket in your local
machine (aka laptop): How to Create a WebSocket Server & Client.
Be aware that the video above will work only on backend which you can run using Terminal on mac or Command line in Windows. To work it on a
browser I used isomorphic-ws which is a wrapper that allows
websockets to work on web browsers.
I wish this could help anyone who was stuck like me on how to implement a real time communication between two ends.
I have the following icon present in my system, which on click, should allow the user to delete a post:
<span id='remove' class='glyphicon glyphicon-remove' aria-hidden='true'></span>
clicking on the icon should then perform a PHP query which will drop the row from the table, removing the post from the database.
But I am unaware and want to discover if making an icon perform an action is possible?
The process
There are essentially five steps to take :
1) You can send a HTTP request to an url http://www.example.com/post/15 when you click your remove button :
$("#remove").click(function(){
$.ajax({
type: "DELETE",
url: "http://www.example.com/post/1",
data: [],
success: function() {
console.log("Yey!");
},
dataType: "json"
});
});
3) On the server, you could use .htaccess to forward all your requests to index.php.
4) In index.php, you could use eg. $_SERVER['PATH_INFO'] to know that post/15 is the final part of your url http://www.example.com/post/15. From this, your code in index.php should conclude that that you're trying to do something with the post that has an id with value 15, and from the request type it can conclude that you want to delete it.
5) Once you know that, you can just delete the post with id 15 from the database and echo whatever response you want to send back to the client.
Some sources to check out
How to Use jQuery’s $.ajax() Function
A Beginner’s Guide to HTTP and REST
Httpful: The REST Friendly PHP HTTP Client Library
You can use javascript to bind an action to a browser event (such as a 'click'). In your case, look at the onclick event in javascript.
It may be easier to use jQuery:
https://api.jquery.com/click/#click-eventData-handler
Then you will need to use ajax to submit the form to the server (your php script). jQuery provides functionality for this as well:
http://api.jquery.com/jquery.ajax/
what you could do is make a button in the same form and hide it by using css, then you could activate this button on clicking the span tag:
Html:
<input type="submit" id="#hiddenButton" style="display:none;"/>
Jquery:
$("#remove").click(function(){
$("#hiddenButton").click();
});
I am trying to do a simple query for info from a database through an html page. I've got all the backend stuff working fine, but I'm having trouble on the client side. I currently have a form where the user submits their ID# to get some info on their case.
But with my current setup, it returns an entirely new page and I just want to read in a text string, process it and update the content on the current html page without opening up a new one and replacing the old one. How can this be done?
Here's my code so far:
function showInfo() { } // I want to make the request here instead
<form name="register" action="http://localhost:8080/testapp/authenticate" method="get">
<p><label for="badge">ID #:</label>
<input id="badge" name="ID" type="text" pattern="[0-9]{6}"
placeholder="xxxxxx">
<button id="checkButton" type="submit" onClick="showInfo()">Enter</button>
</p>
</form>
My guess is that you're actually submitting the form, which is posting back to the server. What you will want to do is cancel the form from submitting and submit it using AJAX (which is what I believe you want?).
To do so, your showInfo() function should do one of these three things (I can never remember which one)
return false;
cancel the event, something like e.preventDefault()
stop the propagation, something like e.stopPropagation()
Once you've successfully prevented the form from hard-submitting, you can then do what you'd like by submitting your data via AJAX and manipulating your response however you'd like.
1st - Jason is absolutely right that what you want for this situation is AJAX, below is an example in motion.
2nd - You should be using a Javascript library such as jQuery, which might look intimidating (as it did for me at first), but it is really easy and completely worth the small effort to get it going.
3rd - With jQuery, your application tidbits should look something like this, using the example you provided:
HTML -
<p>
<label for="badge">ID #:</label>
<input id="badge" name="ID" type="text" pattern="[0-9]{6}"
placeholder="xxxxxx">
// Please note that I removed the onClick section from the line below.
<button id="checkButton" type="button">Enter</button>
</p>
JQUERY -
// The default function you described to take information and display it.
function showInfo(data) {
// Insert your function here, probably using JSON as the Content Type
}
// This is the key AJAX function, using jQuery, that takes your info and gets a
// response from the server side, the sends it to the function above in order for it
// to be displayed on the page.
function processIdInfoCheck() {
$.ajax({
type: 'post',
url: '/http://localhost:8080/testapp/authenticate',
data: {
'id': $('#badge').val();
},
dataType: 'json',
success: displayIdInfoReturn,
error: function () {
alert("There was an error processing your request, please try again");
}
});
}
// When the page loads, the code below will trigger, and bind your button click
// with the action you want, namely triggering the AJAX function above
(function ($) {
$('#checkButton').bind('click', processIdInfoCheck);
})(jQuery);
Just remember, AJAX takes some effort to get the desired effect, but when you look at page load times, request numbers, etc... It is totally worth it. Please let me know if this was helpful and if you need any specifics.