0

Looking for a solution to an issue that I am having. My PHP file is able to store a date and time from a user's input. However, once the date is stored, it is no longer accessible to be used in my Javascript function.

I am just lost on how data is processed step by step. How would I extract stored data in my database to use in my Javascript function?

UPDATE: ADDED CODE

PHP: Simply stores input, and shows it was stored

    <?php
// ONLY Process Form if $_POST is NOT Empty
if ( ! empty( $_POST ) ) {

  // Connect to MySQL
  $mysqli = new mysqli( 'hn', 'un', 'pw', 'db' );

  // Check Our Connection
  if ( $mysqli->connect_error ) {
    die( 'Connect Error: ' . $mysqli->connect_errno . ': ' . $mysqli->connect_error );
  }

  // Insert Our Data
  $sql = "INSERT INTO table ( mydate ) VALUES ( '{$mysqli->real_escape_string($_POST['myDate'])}' )";
  $insert = $mysqli->query($sql);

  // Print Response from MySQL
  if ( $insert ) {
    echo "Success! Row ID: {$mysqli->insert_id}";
  } else {
    die("Error: {$mysqli->errno} : {$mysqli->error}");
  }

  // Close Connection
  $mysqli->close();
}
?>

HTML: Just a form

  <html>
  <head>
    <meta charset="utf-8">
    <title>User Form</title>
  </head>
  <script type="text/javascript" src="/displaytimer.js"></script>
  <body>
    <!-- HTML Form -->
    <form class="" action="/index.php" method="post">
      <input type="datetime-local" name="myDate" id="myDate"><br /><br />
      <button id="submit" onclick="clickButton()" value="submit">Submit</button><br /><br />
      <div id="showDate"></div>
    </form>
   </body>
  </html>

JAVASCRIPT: Generates a timer based on users inputed date. Also accessible on iPhone (found help here on SO for that). I am sure that there is a simpler way to do this, but I am mainly looking for how to still use the date inputed within var n.

// get the iso time string formatted for usage in an input['type="datetime-local"']
var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0,-1);
var localISOTimeWithoutSeconds = localISOTime.slice(0,16);

// select the "datetime-local" input to set the default value on
var dtlInput = document.querySelector('input[type="datetime-local"]');

// set it and forget it ;)
dtlInput.value = localISOTime.slice(0,16);

function clickButton() {
  var x = setInterval(function() {
    // Get Date Selected & Convert to ISO
    var n = document.getElementById("myDate").value;
    var d = new Date(n);
    var dISO = d.toISOString();

    // Get Today's Date
    var today = new Date();
    var tS = today.toDateString();
    var tISO = today.toISOString();

    // Calculate Time Left
    var dParse = Date.parse(dISO);
    var tParse = Date.parse(tISO);
    var distance = dParse - tParse;
    // days
    var days = Math.floor(distance / (1000 * 60 * 60 * 24));
    if (days > 0) {
      days = Math.floor(distance / (1000 * 60 * 60 * 24));
    } else {
      days = 0;
    }
    // hours
    var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    if (hours > 0) {
      hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    } else {
      hours = 0;
    }
    // minutes
    var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
    if (minutes > 0) {
      minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
    } else {
      minutes = 0;
    }
    // seconds
    var seconds = Math.floor((distance % (1000 * 60)) / 1000);
    if (seconds > 0) {
      seconds = Math.floor((distance % (1000 * 60)) / 1000);
    } else {
      seconds = 0;
    }

    // Print Distance or Expired Message
    if (days > 0 || hours > 0 || days > 0 || seconds > 0) {
      document.getElementById("showDate").innerHTML = days + " days " + hours + " hours " + minutes + " minutes " + seconds + " seconds ";
    } else {
      document.getElementById("showDate").innerHTML = "The time has expired";
    }
  }, 1000);
}
7
  • 3
    Um, once the form submits you JavaScript function vanishes into the aether. You can spit it back out in the php response, or you can use AJAX instead of submitting. Commented Nov 25, 2018 at 0:09
  • @JaredSmith, if I were to use AJAX instead of submitting, does that mean that the date would not be stored in my database table, or would the function run without submitting, or am I missing the point? I have been trying to find a way to perform the former with my understanding being that the data is submitted through the form > stored on the server > spit back out through a variable > echoed in the JS function. Am I sounding offbase on my understanding of either solution? Commented Nov 25, 2018 at 0:19
  • If you look at your form, the action is "/date_php/index.php" that means that once you submit the form you navigate to this url (which is the same url you are on) and because the $POST variable is populated the php code at the top of the page gets executed (because you have: if ( ! empty( $_POST ) ). However the javaScript clickedButton doesn't proceed because the page has been reloaded. By using AJAX to submit the form, the page won't reload and so the javaScript code will be executed and you can also store the data on the server. :) If you give me some time I will show you some code. :) Commented Nov 25, 2018 at 0:27
  • Hi @Sarah! I would very much appreciate anything that you could provide (: thank you! Commented Nov 25, 2018 at 1:22
  • @EataSandwhich No probs. I just posted some code. I tested it and it works for me. But I was just thinking you might need to "echo" back the date that was submitted instead of using document.getElementById("myDate").value; in the setInterval function as the user may have changed this input field in the meantime. But I know how you can echo back multiple variables from the PHP file in the ajax request so just let me know. :) Commented Nov 25, 2018 at 1:52

2 Answers 2

3

By using AJAX to submit the form (i.e store the date on the server), the page won't reload and so your javaScript code will be executed.
Here is a break down of how it can work:

  1. The clickButton() JavaScript function gets the values from the input fields of the form.
  2. It then performs the ajax request sending the data to a PHP file i.e store_data.php (this will contain the php code which was originally at the top of your page).
  3. The server processes whats in the PHP file. i.e inserts the date to the database
  4. The PHP file echos back whatever data you like to the client (in your case you have success or error).
  5. A callback is performed on the client side where the data (that was echoed) can be retrieved from the server and javaScript code can be executed. Note: The page hasn't reloaded so the myDate input field is still populated.

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>User Form</title>
<script type="text/javascript" src="/displaytimer.js"></script>
</head>
<body>
  <!-- HTML Form -->
  <form class="" action="" method="post">
    <input type="datetime-local" name="myDate" id="myDate"><br /><br />
      <button id="submit" onclick="clickButton()" type="button">Submit</button><br /><br />
      <div id="showDate"></div>
  </form>
</body>
</html>

displaytimer.js

 window.onload = function(){
      // get the iso time string formatted for usage in an input['type="datetime-local"']
      var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
      var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0,-1);
      var localISOTimeWithoutSeconds = localISOTime.slice(0,16);

      // select the "datetime-local" input to set the default value on
      var dtlInput = document.querySelector('input[type="datetime-local"]');

      // set it and forget it ;)
      dtlInput.value = localISOTime.slice(0,16);
    }


    function createXHR(){
      //This function sets up the XMLHttpRequest
      try{
        return new XMLHttpRequest();
      }catch(e){
        //to support older browsers
        try{
          return new ActiveXObject("Microsoft.XMLHTTP");
         }catch(e){
           return new ActiveXObject("Msxml2.XMLHTTP");
         }
      }
    }

    function clickButton(){
      //The form has been submitted.
      //Get the value of the myDate field from the form
      var myDate = document.getElementById('myDate').value;
      //set up the ajax request
      xmlhttp = createXHR();
      xmlhttp.onreadystatechange = ajaxCallback; //name of our callback function here
      //Ive called the php file store_data.php but you can call it whatever you like.
      xmlhttp.open("POST", "store_data.php" ,true);
      xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      //send our variables with the request
      xmlhttp.send("myDate=" + myDate);
    }

    function ajaxCallback(){
      //this function will be executed once the ajax request is completed
      if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
        //The ajax request was successful.
        //we can now get the response text using xmlhttp.responseText. This will be whatever was echoed in the php file
        var data = xmlhttp.responseText; 
        //In your case "data" will either be "Success! Row ID: ..." OR "Error: ....." so you can do checks here.
        //For demonstration I will just continue with the rest of your code.

        var x = setInterval(function() {
          // Get Date Selected & Convert to ISO
          var n = document.getElementById("myDate").value;
          var d = new Date(n);
          var dISO = d.toISOString();

          // Get Today's Date
          var today = new Date();
          var tS = today.toDateString();
          var tISO = today.toISOString();

          // Calculate Time Left
          var dParse = Date.parse(dISO);
          var tParse = Date.parse(tISO);
          var distance = dParse - tParse;
          // days
          var days = Math.floor(distance / (1000 * 60 * 60 * 24));
          if (days > 0) {
            days = Math.floor(distance / (1000 * 60 * 60 * 24));
          } else {
            days = 0;
          }
          // hours
          var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
          if (hours > 0) {
            hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
          } else {
            hours = 0;
          }
          // minutes
          var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
          if (minutes > 0) {
            minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
          } else {
            minutes = 0;
          }
          // seconds
          var seconds = Math.floor((distance % (1000 * 60)) / 1000);
          if (seconds > 0) {
            seconds = Math.floor((distance % (1000 * 60)) / 1000);
          } else {
            seconds = 0;
          }

          // Print Distance or Expired Message
          if (days > 0 || hours > 0 || days > 0 || seconds > 0) {
            document.getElementById("showDate").innerHTML = days + " days " + hours + " hours " + minutes + " minutes " + seconds + " seconds ";
          } else {
            document.getElementById("showDate").innerHTML = "The time has expired";
          }
        }, 1000);   

      }
    }

store_data.php

<?php
// ONLY Process Form if $_POST is NOT Empty
if ( ! empty( $_POST ) ) {

  // Connect to MySQL
  $mysqli = new mysqli( 'hn', 'un', 'pw', 'db' );

  // Check Our Connection
  if ( $mysqli->connect_error ) {
    die( 'Connect Error: ' . $mysqli->connect_errno . ': ' . $mysqli->connect_error );
  }

  // Insert Our Data
  $sql = "INSERT INTO table ( mydate ) VALUES ( '{$mysqli->real_escape_string($_POST['myDate'])}' )";
  $insert = $mysqli->query($sql);

  // Print Response from MySQL
  if ( $insert ) {
    echo "Success! Row ID: {$mysqli->insert_id}";
  } else {
    die("Error: {$mysqli->errno} : {$mysqli->error}");
  }

  // Close Connection
  $mysqli->close();
}
?>

UPDATE:

If you want to send multiple variables back from the PHP file you can create an associative array and use json_encode as follows:

store_data.php:

$responseData = array(); //create a PHP array
$responseData['status'] = "success"; 
$responseData['myDateSubmitted'] = $_POST['myDate']; //store the date that was submitted into a variable to send back
echo json_encode($responseData); //echo the response data back to the client

displaytimer.js

function ajaxCallback(){
  //this function will be executed once the ajax request is completed
  if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
    //The ajax request was successful.
    //we can now get the response text using xmlhttp.responseText. 
    //parse the response text as JSON because we used json_encode in our PHP file.
    var jsonData = JSON.parse(xmlhttp.responseText);
    console.log(jsonData.myDateSubmitted); //check one of our variables
    //Rest of your code here
  }

}

Sign up to request clarification or add additional context in comments.

5 Comments

Wow! I don't even know what to say.... thank you so much for helping me understand! I am so thankful! In your follow-up comment you mentioned that I should echo that data within the variable. What is the benefit for that?
@EataSandwhich No probs. Glad to help :) I mean you should echo back the myDate that was submitted because when the setInterval function is processed you retrieve the date from the input field (var n = document.getElementById("myDate").value;) however the user may change this date while the setInterval is running and so the output in showDate wont be the desired output.
How would I do so if you don't mind? I understand it may be a bit trickier to accomplish since it is a date and needs to stay the same format as it is currently being calculated.
@EataSandwhich I don't mind at all however I will get back to you tomorrow as its 3.00 a.m here lol :D Glad to have helped :)
@EataSandwhich I just added an update to my answer. :) Also I advise you to clear the interval you set as it will keep going unless you clear it which will cause problems. To do this, your setInterval variable x should be global. Then you can use clearInterval(x); It might be a good idea to do this everytime the form is submitted (e.g insert clearInterval(x); at the top of the clickButton() method) Hope that helps
0

You should avoid submitting data with a POST, this way the page will not reload, so you don't need spitting back anything.

Use AJAX to send myDate to the backend to make it persistent on the DB.

Simply speaking, you should convert your PHP code in a basic backend REST service; avoid sticking PHP code with the HTML page and process posted data, this is a very old way of doing things.

Use PHP for the backend and JS for the frontend.

4 Comments

1. What does the HTTP method have to do with anything? 2. What's wrong with using PHP and submitting forms? Not every site needs to be an SPA... as for old, old means 'proven'. Lots of sites (e.g. facebook, wayfair, etc) are still heavily PHP.
This is very helpful as well. I will definitely be doing more research into this!
@JaredSmith nothing against PHP, but today, the way (even for Facebook) is to split backend with any language and spit out JSON to the frontend, that is made in pure JS, no reloading. In few words REST and WebSocket communication. If you have only to make a simple web page there's nothing wrong using PHP mixed with JS. But IMHO, every time I start with a simple page, after a while people ask for changes, and that simple page will get complex. With the "modern" way, you implement changes smoothly and rapidly, with the old way the risk for a spaghetti code result is always behind the corner.
I have a lot of things against PHP, but at the same time I can't help but think building an SPA even in 2018 requires one to reinvent the wheel, badly. You need a third party router and a ton of boilerplate to get deep linking which you otherwise would get for free. State management is more complicated. Tooling is way more complicated. I mean, don't get me wrong I still build SPAs, but I wouldn't frame it as a one-sided tradeoff the way you seem to be doing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.