0

I am still learning proper and more efficient ways of writing code - at the moment I am stuck on this current issue.

I have a form that currently works fine - writes to the sql database, then reloads the current page. I would like the form to NOT reload the page.

I know there is a way to do this with jQuery and Ajax -- honestly I'm not skilled yet with these.

  1. If there's a way to do this with PHP/HTML - I would love guidance on this method.

  2. If the only answer is Java and Ajax - I would love guidance for this specific instance of changing this form to not reload the page.

Screen shot of what the button looks like -- three colors to represent 3 stages of tracking payment on invoices. Red turns to yellow when clicked, yellow to green, green back to red (in case of a mistake click).

Button example

Here's front end code for my form:

    <form action="jump_invoicepaid.php" method="post">
    <input type="hidden" name="invoicepaid" value="'.$projectid.'">');                        
if ($projectpaid == 2) {
           echo('<button type="submit" name="action" class="greenbutton" value="unpaid">Paid</button></form>');
} else if ($projectpaid == 1) {
           echo('<button type="submit" name="action" class="yellowbutton" value="paid">Paid</button></form>');
    } else {
           echo('<button type="submit" name="action" class="redbutton" value="sent">Paid</button></form>');
}          

Here's the back end code for my form:

if ($_POST['action'] == paid) {
   ///marking project as paid       
include_once('toolbox.php');
$projectid = $_POST['invoicepaid'];
mysqli_query($con, "UPDATE kmis_projects SET project_paid='2' WHERE project_id= '$projectid'");
header('Location: ./?page=pastevents');

} else if ($_POST['action'] == sent) {
       ///marking project as sent       
include_once('toolbox.php');
$projectid = $_POST['invoicepaid'];
mysqli_query($con, "UPDATE kmis_projects SET project_paid='1' WHERE project_id= '$projectid'");
header('Location: ./?page=pastevents');

} else if ($_POST['action'] == unpaid) {
       ///marking project as unpaid       
include_once('toolbox.php');
$projectid = $_POST['invoicepaid'];
mysqli_query($con, "UPDATE kmis_projects SET project_paid='0' WHERE project_id= '$projectid'");
header('Location: ./?page=pastevents');
}

I do want to learn jQuery and ajax fully, it's next on my to learn list. I know they would make this issue a lot easier to solve.

UPDATE -- I spent some time with the link posted, suggesting it was a duplicate question of the link. I do see why... but it's not the same at the heart of what I'm asking or the answer that was given in the link. I think the link could be "an" answer to the issue - but I was interested in any ways of solving the issue without having to use jQuery and AJAX -- and if that was unavoidable, then specifically how AJAX would fit into my code and this specific situation. I equally think this is unique from the link, given that my buttons are populated with 3 different "if" checks, to write a different value depending on what button is populated and clicked.

UPDATE 2 -- Here's the current code I'm working with. The ajax isn't sending name or value of button though it seems.

<script>
$( document ).ready(function() {
    $("button").click(function(e) {
        e.preventDefault(); // prevent page refresh

        $.ajax({
            type: "POST",
            url: "jump_invoicepaid.php",
            data: $(this).serialize(),   // serialize form data
            success: function(data) {
                window.location.replace("?page=pastevents");
            },
            error: function() {
                // Error ...
            }
        });
    });
});
</script>

<form action="">
           <input type="hidden" name="invoicepaid" value="'.$projectid.'">

if ($projectpaid == 2) {
           echo('<button type="submit" name="action" class="greenbutton" value="unpaid">Paid</button></form>');
} else if ($projectpaid == 1) {
           echo('<button type="submit" name="action" class="yellowbutton" value="paid">Paid</button></form>');
    } else {
           echo('<button type="submit" name="action" class="redbutton" value="sent">Paid</button></form>');
}           
userK1400
  • 39
  • 1
  • 7
  • use `ajax` to submit and get the data from the server, also replace the `submit button` with normal button fires the `ajax` function(send and get data) or if you want override the default action of the `submit button` – xYuri Sep 26 '16 at 03:39
  • 2
    Possible Duplicate of http://stackoverflow.com/questions/18169933/submit-form-without-reloading-page @userK1400, your answer can be found here in this answer: http://stackoverflow.com/a/18170009/2280505 – Howzieky Sep 26 '16 at 03:41
  • 1
    What you want really isn't that hard, but there are some other issues with your code that need to be resolved. 1) `header('Location: ..);` has to be removed from your PHP code if you're going to use Ajax. 2) Your code is wide open to SQL injection. Learn to use [MySQLi Prepared Statements](http://php.net/manual/en/mysqli.prepare.php) to prevent this. 3) Its a better practise to seperate HTML from PHP: `if( .. ){ ?> ` – icecub Sep 26 '16 at 03:45
  • @Howzieky - Thank you for sharing that link. I'll look through it and see if it's the same issue - looking at it briefly, it may be an answer, but I was more inquiring if there was a php/hmtl version - and if not, then help on inserting ajax into my specific code. I'll spend more time with the link though to see if I can learn from it. Thank you! – userK1400 Sep 26 '16 at 04:12
  • @icecub Thank you for the information. preventing sql injection is one thing that I am still working on and learning the proper methods. Thank you for the link and advice. – userK1400 Sep 26 '16 at 04:13
  • To add my 2 cents, I strongly recommend reading through these two sources on [sql injection prevention](https://phpdelusions.net/sql_injection) and [proper pdo](https://phpdelusions.net/pdo) – Alex Sep 26 '16 at 16:17
  • 1
    If you wanted to avoid using AJAX, you could set the form target to a hidden ` – haliphax Sep 28 '16 at 04:57
  • @haliphax Thank you for the advice! I've pretty much settled on using ajax now that I understand it a little better. I'll have a look at iframe and see if that's something I want to do - I'd have to go the route of putting the whole form in the iframe if I did. Thanks again! – userK1400 Sep 28 '16 at 05:17
  • 1
    @userK1400 I would advocate for AJAX, personally - you can do some really neat stuff with it. I just saw in your OP that you were curious if there was a way to do it without AJAX. There is, but it has some serious limits. :) – haliphax Sep 28 '16 at 05:22
  • @haliphax Thanks again for the help! I updated my question and gave the code at the bottom for what I'm working with now - in terms of Ajax. Do you have any advice on how to get Ajax to send through the name, value, and hidden input projectid of the button? (there's three buttons but only one is generated based on the paid status of "1, 2, or 0"). – userK1400 Sep 28 '16 at 15:30
  • 1
    You may want to serialize the data by hand in that case, instead of using jQuery's `$.fn.serialize()` function. It can work like a normal POST request. Just send an associative array with keys/values for the form elements you wish to push. Edit: It looks like `serialize` should do that, though. I would see what `console.log($(this).serialize())` looks like to give you a better idea of the data structure that's going across the wire. – haliphax Sep 29 '16 at 17:03

1 Answers1

2

In order to execute the server-side script (PHP) from the client side (static HTML and JavaScript), you need to use the Ajax technology. In essence, Ajax will allow you to send and/or retrieve data from the server "behind the scenes" without affecting your page.

JavaScript, a client-side scripting language used to add interactivity to your webpage, already supports Ajax. However, the syntax is rather verbose, because you need to account for differences across browsers and their versions (Internet Explorer version 5 up to 11 in particular have their own implementation different from Chrome or Mozilla).

You, as a developer, can avoid these technicalities by using a front-end framework such as jQuery (other good examples are Angular.js, Vue.js, and others). jQuery is essentially a library of code written in vanilla JavaScript that simplifies common tasks such as querying DOM. It also provides expressive syntax for using Ajax. It will resolve browser incompatibilities internally. This way you can focus on your high-level logic, rather than low-level issues like that.

Once again, jQuery code is also JavaScript code. So place the following <script> tag, as you would normally do with JS, somewhere in your page.

<script>
$( document ).ready(function() {
    $("form").submit(function(e) {
        e.preventDefault(); // prevent page refresh

        $.ajax({
            type: "POST",
            url: "jump_invoicepaid.php",
            data: $(this).serialize(), // serialize form data
            success: function(data) {
                // Success ...
            },
            error: function() {
                // Error ...
            }
        });
    });
});
</script>

First, this code will run once the page is loaded. Second, it will attach a submit event handler to every <form> in your HTML page. When you click on the <button type='submit'>, this event will fire. e.preventDefault() will halt the normal submission of the form and prevent page refresh. Note that e is the event object that contains info about the submit event (such as which element it originated from).

Next, we are sending the actual Ajax request using $.ajax method from jQuery library. It is a generic method, and we could as well have used $.post, since we are specifically doing the POST request. It will be received by your PHP file jump_invoicepaid.php.

Now, in your PHP file, you have the following line: header('Location: ./?page=pastevents'); which forces a redirect to the home page with a GET parameter. If you want to have the same behavior, then you would need to remove that line, and put window.location.replace("/?page=pastevents") to your JavaScript code:

// in your Ajax request above...
success: function(data) {
    window.location.replace("/?page=pastevents");
},

This would refresh the page however, because you are essentially requesting the home page with a GET method. I am guessing that this is done in order to update information on the page. You could do so without redirecting, by adding / changing / removing elements on your page (i.e. in DOM). This way, you would send data from the server back to the client, and if the response is received successfully, in your JavaScript you can obtain that response and manipulate your webpage accordingly.

If the latter interests you, then consider using JSON format. You just need to do json_encode in your PHP, and then on the client-side, parse the JSON string using JSON.parse(...). Read on here for example.

Hope this helps!

Community
  • 1
  • 1
Alex
  • 3,719
  • 7
  • 35
  • 57
  • 2
    thank you so much for the detailed response. I figured ajax was the only way - unfortunately I don't know enough about ajax and jquery to use them effectively just yet. I'm not sure where, or how, to use the code you posted or JSON - but I do appreciate it very much. I have a feeling it would be too detailed to give me specific instruction on this issue, so I'll set out to learn these next so I can fix this issue with your suggestions. – userK1400 Sep 26 '16 at 04:17
  • Alex, thank you so much for taking time to explain in detail and help!! That's very thorough and I understand a little better. I'm going to set out to learn proper JavaScript so I can fully comprehend this method and do it correctly. Thanks again for taking time to help so thoroughly!! – userK1400 Sep 26 '16 at 23:45
  • So I've been working with this - Successfully getting window.location.replace to work (haven't added json yet, so page is reloading but staying on same page). Current Issue - not getting the button to write to the sql. I believe it's because the ajax isn't sending the name="action" value="paid". -- As you can see, I don't have 3 buttons all at once, it's just the one button that is displayed depending on the paid status (0,1, or 2). So I only need to have ajax send the one name & value that is clicked. Any thoughts on this? -- I've updated my question to show current code. Thank you! – userK1400 Sep 28 '16 at 04:11
  • Also it needs to pass the hidden input of $projectid. I forgot about that one as well since the jump_invoicepaid needs the projectid to know where to update the paid status. Thank you again for any help! – userK1400 Sep 28 '16 at 04:23
  • Hey, if you'd like to store data in a button, just use `` and it should work (don't forget `` does NOT have a closing tag, just like `
    `). But you could as well store that same data in yet another hidden input.
    – Alex Oct 17 '16 at 22:16