1

I have tried the javascript refresh options on submit (on the <form> but none of them work. If I put the javascript refresh with the submit function, then every time it refreshes, the item gets sent to the database (do not want that).

What I have tried onsubmit="location.reload()"
onsubmit="window.location.reload()"
onsubmit="setTimeout(function () { window.location.reload(); }, 10)"

It currently renders an array of items with a checkbox. When I click the checkbox, the item gets sent to the database as read -- but it stays on the screen (unless I revisit the page manually in the address bar). I am developing in WordPress using PHP.

Perhaps there is a small trick we can use just to remove the array that is sent on submit out of the books_array as soon as the submit button is clicked? Or reload the books_array after submission?

Here is my code: form function

<form action="<?php user_add_new();?>" method="post">
<?php
foreach($books_array as $index => $i ) {
    $s = $i->title;
    $o = $i->listID;
    $r = $i->submittedBy;
    $d = $i->bookDESC;
    $t = $i->id;
    $current_user = wp_get_current_user();
    $current_id = $current_user->ID;

    if ($r == $current_user->ID || $r == 'administrator') {
        echo '<div class="user-wrap">';
            echo '<div class="inner-wrap">';
                echo '<!---entire checkbox--->';
                echo '<div><span class="check">';
                    echo "<input type='checkbox' name='checkbox[]' value='$index' onChange='this.form.submit()'>";
                    echo "<input type='hidden' name='item$index' value='$t'>";
                    echo "<input type='hidden' name='listID$index' value='$o'>";
                    echo "<input type='hidden' name='userID$index' value='$current_id'>";
                echo '</span></div>';
                echo '<!---entire checkbox--->';
                echo '<!---info from book--->';
                echo "<div><b>$s</b><br>$d</div>";
                echo "<!---info from book--->";
            echo '</div>';
        echo '</div>';
    }
};
?>
</form>

foreach loop

function user_add_new() {
    global $wpdb;

    $value = $_POST["checkbox"][0];
    $bookTOadd = $_POST["item" . $value];
    $listTOadd = $_POST["listID" . $value];
    $userID = $_POST["userID" . $value];

    $addTABLE = $wpdb->prefix . 'plugin_read';

    $wpdb->insert(
        $addTABLE,
        array(
            'bookID' => $bookTOadd,
            'userID' => $userID,
            'listID' => $listTOadd,
        )
    );
}

I keep running into issues, but I am so grateful to anyone who can give a little insight on how to approach this best. Thank you for taking the time to read this!

CodeChic
  • 71
  • 10
  • You could try redirecting the user with PHP. `header("Location: https://example.com/myOtherPage.php"); die();` That would go in the function, after the database insert. The URL would be the existing page so it would just reload. – leighboz Nov 06 '22 at 02:47
  • It just keeps the page reloading if I put it there after the database insert – CodeChic Nov 06 '22 at 03:01
  • `action=""` - You can't add a PHP function in the `action`-attribute. The `action`-attribute should contain a URL where the form will be submitted to. Right now, you're calling the `user_add_new()` function when the page renders on the server (before the browser even gets it). Read [What is the difference between client-side and server-side programming?](https://stackoverflow.com/questions/13840429/what-is-the-difference-between-client-side-and-server-side-programming) for more info. While reading, remember that PHP is server side and HTML/JavaScript is client side. – M. Eriksson Nov 06 '22 at 03:30
  • Hi! @M.Eriksson That doesn't work for wordpress, I tried it before. If I put the function in a php file, it tries to go to the .php file as a page. Would there be a way of calling it only when the form requests it without it loading on the page outright and without putting it in a .php file? – CodeChic Nov 06 '22 at 03:37
  • And then if I do that, would a way to fix the problem in the question be possible? @M.Eriksson perhaps the `header("Location: https://example.com/myOtherPage.php"); die();` would then work? – CodeChic Nov 06 '22 at 03:37
  • _"That doesn't work for wordpress, I tried it before."_ - Yes it does. My comment (and the info in it) is completely unrelated to Wordpress. It's simply how internet works and isn't something Wordpress can change. If you want to submit a form without redirecting/reloading the page, you need to use Ajax (which also makes a new request to a separate URL, but it does it in the background). – M. Eriksson Nov 06 '22 at 03:41
  • @M.Eriksson Can you put in an answer how to make it work with wordpress, I haven't had it work before and instead it redirects to the php file the action is in. If you can I would absolutely appreciate it, I must have been doing it very wrong before. Thank you! Or a way to do this with ajax? Whichever you think might work. I'll try any of it! – CodeChic Nov 06 '22 at 03:45
  • First read the link I posted so you understand how things work. Then read up on how forms work. After that, read up on Ajax to understand what it is and then how to make Ajax requests in Wordpress (which has helpers for it). I don't remember it of the top of my head. – M. Eriksson Nov 06 '22 at 03:47
  • @M.Eriksson I just read the edit of the comment above, you had said " If you want to submit a form `without` redirecting/reloading the page" but the problem I posted about in the question is to make the page reload. I want it to reload, otherwise my data array on the page does not refresh. I truly do appreciate it though. I thought if I looked up ajax that would be the solution, but if it doesn't refresh the page, it won't fix my problem. I'll still look it up though because maybe I can work a refresh in there regardless. – CodeChic Nov 06 '22 at 04:32
  • 1
    If you put a URL in `action`, the page will redirect (or reload if you put the current URL in there). If you redirect to a PHP file that only does what you need, you can then redirect back to the current URL (which is what the first comment explained). If you don't what it to reload, you can use Ajax to send the request in the background (using JavaScript) and update the page based on the response without refreshing page (also using JavaScript). Those are the choices, which both would solve your issue. Please do more research about this (as I suggested in my last comment) as that's web 101. – M. Eriksson Nov 06 '22 at 09:16
  • You could try `unset($_POST) ` in the function, after the database insert. – leighboz Nov 06 '22 at 11:30
  • 1
    @M.Eriksson Thank you for the suggestions! I figured out a way myself, using WordPress functionality by creating a WP action and having it execute only when the form is submitted. I thankfully didn't need ajax or a .php file to go in `action` on the form. Although your comments would have helped if I needed ajax or were coding in regular php without WordPress functionality, thank you for commenting. – CodeChic Nov 06 '22 at 16:27
  • 1
    @leighboz Thank you so much for brainstorming with me and helping with ideas, I truly appreciate all of the time you spent helping. I have finally found a solution, but I am extremely grateful for your help! – CodeChic Nov 06 '22 at 16:29

1 Answers1

1

Problem fixed by creating a WordPress action and calling/rendering it only when the form is clicked (since before the action was rendered on page load just not executed until the click, which was 1 thing causing my issue re the not refreshing the entire page after form submission). No ajax (though its great with wordpress) nor .php files (that would just be a workaround).

Removed the action="" from my form, since we'll be using wordpress to do this.

Added this line <?php wp_nonce_field('book_send', 'book_send_nonce', true, true);?> to my form, you can see that below (this will help call my action in my WordPress file, associating it with this form)

<form method="post">
<?php wp_nonce_field('book_send', 'book_send_nonce', true, true);?>
<?php
foreach($books_array as $index => $i ) {
    $s = $i->title;
    $o = $i->listID;
    $r = $i->submittedBy;
    $d = $i->bookDESC;
    $t = $i->id;
    $current_user = wp_get_current_user();
    $current_id = $current_user->ID;

    if ($r == $current_user->ID || $r == 'administrator') {
        echo '<div class="user-wrap">';
            echo '<div class="inner-wrap">';
                echo '<!---entire checkbox--->';
                echo '<div><span class="check">';
                    echo "<input type='checkbox' name='checkbox[]' value='$index' onChange='this.form.submit()'>";
                    echo "<input type='hidden' name='item$index' value='$t'>";
                    echo "<input type='hidden' name='listID$index' value='$o'>";
                    echo "<input type='hidden' name='userID$index' value='$current_id'>";
                echo '</span></div>';
                echo '<!---entire checkbox--->';
                echo '<!---info from book--->';
                echo "<div><b>$s</b><br>$d</div>";
                echo "<!---info from book--->";
            echo '</div>';
        echo '</div>';
    }
};
?>
</form>

And this is my action (steps are described in the notes within the code) which makes the post when the action is called upon submit. It only submits the data after form validation. Once the data has been submitted, it then reloads the page using a built in WP function:

add_action('book_check', function() {
   if ( ( is_single() || is_page() ) &&
        isset($_POST[book_send_nonce]) &&
        wp_verify_nonce($_POST[book_send_nonce], 'book_send')
    ) {
      // form validation
    function validate_book_data(){
        $errors = new WP_Error();

        if (isset($_POST[ 'item' ]) && $_POST[ 'item' ] !== '') {
            $errors->add('item_error', 'Book not selected');
        }

        if (isset($_POST[ 'listID' ]) && $_POST[ 'listID' ] == '') {
            $errors->add('list_error', 'No valid list this belongs to.');
        }

        if (isset($_POST[ 'userID' ]) && $_POST[ 'userID' ] == '') {
            $errors->add('user_error', 'Not signed in');
        }
        return $errors;
    }
      // If form validation passes, send the info
      $pass_validation = validate_book_data($_POST);
      if ( $pass_validation ) {
        $value = $_POST["checkbox"][0];
        $data = array(
          'userID' => $_POST["userID" . $value],
          'bookID' => $_POST["item" . $value],
          'list' => $_POST["listID" . $value],
        );
        global $wpdb;
        // Select the table to post the data to
        $book_checked = $wpdb->prefix . 'plugin_read';
        // Insert the data to the table
        $wpdb->insert($book_checked, $data, '%s'); 
        // Set page refresh
        $refresh_page = wp_redirect($_SERVER['HTTP_REFERER']);
        // After data is inserted, refresh the page
        wp_safe_redirect( $refresh_page );
        // and exit
        exit();
      }
   }
});

Using this action solves the issue of the page not refreshing because the action is only called when the checkmark is clicked and within the action, I refresh the page only after the data has sent.

I hope this will help anyone else with the issue. Coding from 8am-2am lately really had my brain become mush so the solution took me a short bit.

CodeChic
  • 71
  • 10
  • _"Problem fixed by creating an action and calling it only when the form is clicked"_ - If you actually read the link I posted, and did the research I suggested, you would understand why that statement makes zero sense. An action will _always_ only be used when the form is submitted. The issue with the original code had _absolutely nothing_ to do with the `action` attribute, or your HTML. If you would have added that `` _anywhere_ on your page, it would have the exact same effect. – M. Eriksson Nov 06 '22 at 16:59
  • If you're going to comment on issues people are having, it's best to approach the exact issue instead of assuming I didn't want the page to reload (when I clearly stated what I needed to achieve in my question) or that a .php file works in regular internet 101 (but not giving an example of it working in wordpress). Just that it works in internet 101. I've been coding for 10+ years. I know some things, just not everything. I've had senior devs help me understand better and also approached things much nicer than you did. @M.Eriksson – CodeChic Nov 06 '22 at 17:15
  • And those senior devs were actually constructive and informative with their advice instead of "search this" which had nothing to do with my exact issue within this exact stack. Just a very vague completely off of my path needed to find the exact solution I was looking for or to fix my issue at all. – CodeChic Nov 06 '22 at 17:17