Calling PHP function at the click of a button

Asked

Viewed 3,482 times

2

Good! I am trying to call a PHP function at the click of a button. My solution so far:

<?php
    $result = getResult($mysqli,"SELECT * from todos WHERE sender = '$username' AND status = '$value' AND journal = '$journal' ORDER BY expiration_date");

    while($row = $result->fetch_array()){
        $receiver = $row['receiver'];
        $sender = $row['sender'];
        $title = $row['title'];
        $todo_text = $row['todo_text'];
        $status = $row['status'];
        $expiration_date = $row['expiration_date'];
        $todo_id = $row['todo_id'];
?> 

<div class="toDo"><b><?php echo $title; ?></b> 
    <ul class='date'>
        <li><img src="icons/date.png" style="width:60px;"></li>
        <li><?php echo "Due " . $expiration_date ?></li>
    </ul>
    <ul>
        <li><?php echo $todo_text; ?></li>
        <li><i><?php echo "assigned to ".$receiver." by ".$sender;?></i></li>
    </ul>

    <?php if($value == 'pending'){?>
    <?php
            if(isset($_POST['delete_x'])){ 
                $todo_id = $_POST['todo_id'];
                deleteToDo($mysqli,$todo_id,$journal);
                exit();
            }

            if(isset($_POST['markAsDone_x'])){ 
                $todo_id = $_POST['todo_id'];
                markToDoAsDone($mysqli,$todo_id,$journal);
                exit();
            }
    ?>
    <form method ="POST" action="">
        <input type="hidden" name="todo_id" value="<?php echo $todo_id ?>"/>
        <input type="image" name = "delete" src="icons/delete.png" style="width:20px"/>
        <input type="image" name = "markAsDone" src="icons/done.png" style="width:20px"/>
    </form>

    <?php } ?>

</div>
<hr> 
<?php 
    } 

This works. I’m running a while loop, so this code is running several times. On my site, I have a page that lists different 'To Do’s', and each has a 'Delete' button and another 'Mark as Done'. However, when I click on one of these buttons, I have to update my page to give me the listing of To Do’s. For example: I want to delete the third To Do from the list. I click the 'Delete' button of the third To Do, but for some reason the page shows me the whole FIRST of the while cycle. If I refresh the page, I get the updated list without the same To Do. That is: the connection with the database is made successfully, but at the moment after clicking on the image should appear the updated listing of To Do’s, but simply appear to me the FIRST To Do do do while. The action is performed successfully, but the process is not 'Smooth' for the user! The page should be updated right after clicking the Delete button!

I still tried to use a header('Location:MINHA_PAGINA') before the exits, but without success.

Listing before performing the 'Delete' action': Listagem antes de realizar a ação 'Delete'

What appears after clicking the 'Delete' icon of the third Whole: O que aparece depois de clicar no icon 'Delete' Any suggestions? Thank you :)

  • Enter the function code...

  • Could you post the part where you effectively print the Whole ? Do you want to do this only with PHP itself ? The ideal would be to use Javascript and asynchronous requests to refresh the page.

  • I added the code with the while cycle, as well as the layout of the elements of Todo. I also thought to use Javascript, but I don’t know how to adapt it..

  • A @cortereal tip, is missing the while lock key in the code posted.

  • @Oliveira forgot that! I’ve updated :)

  • Well, you need to refresh after manually why you are deleting the record after you have already printed it, if you move the delete logic to start and then select will only print what you want. Then I try to post a more appropriate response.

Show 1 more comment

1 answer

1

Sem Ajax

Following your template (the page is updated when the button is clicked):

<?php
if(isset($_POST['delete_x'])) { 
    $todo_id = $_POST['todo_id'];
    deleteToDo($mysqli,$todo_id,$journal);
}
    
if(isset($_POST['markAsDone_x'])){ 
    $todo_id = $_POST['todo_id'];
    markToDoAsDone($mysqli,$todo_id,$journal);
}

$result = getResult($mysqli,"SELECT * from todos WHERE sender = '$username' AND status = '$value' AND journal = '$journal' ORDER BY expiration_date");

while ($row = $result->fetch_array()):
        $receiver = $row['receiver'];
        $sender = $row['sender'];
        $title = $row['title'];
        $todo_text = $row['todo_text'];
        $status = $row['status'];
        $expiration_date = $row['expiration_date'];
        $todo_id = $row['todo_id'];
?> 

<div class="toDo"><b><?php echo $title; ?></b> 
    <ul class='date'>
        <li><img src="icons/date.png" style="width:60px;"></li>
        <li><?php echo "Due " . $expiration_date ?></li>
    </ul>
    <ul>
        <li><?php echo $todo_text; ?></li>
        <li><i><?php echo "assigned to ".$receiver." by ".$sender;?></i></li>
    </ul>

    <?php if($value == 'pending'): ?>
    <form method ="POST" action="">
        <input type="hidden" name="todo_id" value="<?php echo $todo_id ?>"/>
        <input type="image" name = "delete" src="icons/delete.png" style="width:20px"/>
        <input type="image" name = "markAsDone" src="icons/done.png" style="width:20px"/>
    </form>
    <?php endif; ?>

</div>
<hr> 
<?php endwhile; ?>

I just moved the markToDoAsDone and deleteToDo top of the code, before to carry out the consultation again.

With Ajax

It would be interesting to use ajax, so the page would not need to update, but would involve javascript (in case I’m using jQuery).

The form would look like this:

<form>
    <input type="hidden" name="action" value="" />
    <input type="hidden" name="todo_id" value="<?php echo $todo_id; ?>" />
    <input type="image" name="delete" src="icons/delete.png" style="width:20px"/>
    <input type="image" name="markAsDone" src="icons/done.png" style="width:20px"/>
</form>

When the buttons were clicked:

$(document).on('click', '[name=delete], [name=markAsDone]', function(e) {
    // Capturamos o valor de name do botão.
    var actionValue = $(this).attr('name');

    // Atualizamos o valor do action.
    $(this).siblings('[name=action]').val(actionValue);

    // Enviamos o form.
    $(this).parent().submit();

    e.preventDefault();
});

// Quando o form for enviado.
$(document).on('submit', '.toDo form', function(e) {
    var form = $(this);

    $.ajax({
        url: 'url.php',
        method: 'POST',
        data: form.serialize(),
        dataType: 'json',
    }).done(function(r) {
        // resposta aqui.. exemplo:
        if (r.type == 'delete') {
            form.parents('div.toDo').fadeOut(300, function() {
                // Ele vai desaparecer em 300ms e depois
                // será removido.
                $(this).remove();
            });
        }
    });

    // Impedimos o envio padrão.
    e.preventDefault();
});

You could create a php file only to do the Handling of the ajax calls (my preference), or use the same page:

<?php
    if (isset($_POST['action'])) {
        $todo_id = $_POST['todo_id'];
        $resp = array(
            'type' => ''
        );

        switch ($_POST['action']) {
            case 'delete':
                $resp['type'] = 'delete';
                deleteToDo($mysqli, $todo_id, $journal);
            break;

            // Outros cases aqui...
        }

        echo json_encode($resp);
        die();
    }
?>

Remember that jQuery.ajax has two other callbacks: fail and always. The callback fail, as its name says, will be called if any error occurs.

The callback always will be called always, with or without error. You can read more about the ajax api here.

I’ve been doing the head code, and I’ve reviewed it and I think it’s going to work, it’s just that now there’s no way I can test it and,e.

  • Good! Thanks for the answer! The first solution actually works, and it’s logical. Now I’m trying to adapt the second code! However, it’s not working.. I tried to make a print of actionValue from the first part and it actually detects the variable name. It also goes into '$(Document). on('Submit', '.todo form', Function(e) {', but I don’t think it makes it to 'done(Function(r) {'. Thanks and cumps!

  • Forgive me, it’s not type: 'POST' and yes method: 'POST'. I updated the answer.

  • Thanks again! You can delete Todo now, but you need to refresh the manual to update the list. I mean, it doesn’t fadeOut the whole div.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.