10

I have a form that is echoed out from the database, but the issue is that when I try to submit, only the first echoed form submits and the rest doesn't. Below is my code.

editquestion.phh

<thead>
          <tr>
            <th style="width: 5%;">S/N</th>
            <th style="width: 20%;">QUESTION</th>
            <th style="width: 40%;">ANSWER</th>
            <th style="width: 30%;">KEYWORDS</th>
            <th style="width: 5%;">SAVE/UPDATE</th>
            </tr>
      </thead>
      <tbody>
        <?php
        $sql = $db->prepare("SELECT * FROM questions");
        $result = $sql->execute();

        while ($row = $result->fetchArray(SQLITE3_ASSOC))
        {
            $quiz_id = $row['quiz_id'];
            $question = $row['question'];
            $answer = $row['answer'];
            $keywords = $row['keywords'];

            echo '<form action="updatequestion.php" method="post" enctype="multipart/form-data">
            <tr>
            <td><input style="width: 50%" type="text" name="cid" id="cid" value="'.$quiz_id.'"></td>
            <td><input type="text" name="question" id="question" value="'.$question.'"></td>
            <td><input type="text" name="answer" id="answer" value="'.$answer.'"></td>
            <td><input type="text" name="keywords" id="keywords" value="'.$keywords.'"></td>
            <td><input type="submit" name="qupdate" class="qupdate" value="Update"></td>
            </tr>
            </form>';

        }
        ?>
        </tbody>
  </table>

qupdate.js

$(document).ready(function() {
$('.qupdate').click(function() {
    question = $('#question').val();
    answer = $('#answer').val();
    keywords = $('#keywords').val();
    id = $('#cid').val();

    $.ajax({
        type: "POST",
        url: "updatequestion.php",
        data: "cid="+id+"&question="+question+"&answer="+answer+"&keywords="+keywords,
        success: function(html){
            if(html = "true")
            {
                $('.qupdate').css("opacity", "1");
            }
            else
            {
                alert("not successful");
            }
        },
        beforeSend: function(){
            $('.qupdate').css("opacity", "0.5");
        }
    });
    return false;
});
});

Just added the code for updatequestion.php.

<?php
session_start();
require_once("db.php");
$db = new MyDB();


if (isset($_POST['question']) || isset($_POST['answer']) || isset($_POST['cid']))
{
$id = strip_tags(@$_POST['cid']);
$cname = strip_tags(@$_POST['question']);
$cunit = strip_tags(@$_POST['answer']);
$keywords = strip_tags(@$_POST['keywords']);

if (empty($cname) || empty($cunit))
{
    echo "fill";
}
else
{
    $sql = $db->prepare("UPDATE questions SET question = ?, answer = ?, keywords = ? WHERE quiz_id = ?");
    $sql->bindParam(1, $cname, SQLITE3_TEXT);
    $sql->bindParam(2, $cunit, SQLITE3_TEXT);
    $sql->bindParam(3, $keywords, SQLITE3_TEXT);
    $sql->bindParam(4, $id, SQLITE3_INTEGER);

    $result = $sql->execute();

    if ($result)
    {
        echo "true";
    }
    else
    {
        echo "false";
    }
}
}
?>

But the ajax seems to only work for the first echoed data and doesn't seem to submit the rest. How do I solve this?

Thanks in advance.

Erik Hesselink
  • 2,420
  • 21
  • 25
diagold
  • 493
  • 1
  • 7
  • 28
  • 1
    You have several elements with the same id, that doesn't work, since ids need to be unique. So js choses the first one (another browser might take the last one though...) – Jeff Jun 01 '18 at 12:13
  • Also you hhave the form element inside a loop, so when you submit the form it is only submitting one of the many forms you hvae. – Blinkydamo Jun 01 '18 at 12:15
  • the solution is somewhere around there: in your onClick function get the desired values via the clicked button's neighbour elements and their name, rather than via id. – Jeff Jun 01 '18 at 12:21
  • so you want to update all the question that echoed ? then the form tag and the submit button should have outside the loop, and the input tag's name set like this name="cid[]" so it will send array, take a look at this : https://stackoverflow.com/questions/3314567/how-to-get-form-input-array-into-php-array – Baim Wrong Jun 06 '18 at 07:57
  • Do you intend to submit all of them at one go or only the row which user submitted? – Tarun Lalwani Jun 06 '18 at 09:44
  • Only row sir. thanks – diagold Jun 07 '18 at 03:06
  • each row is having same form, identical `name and id` attribute for all the inputs repeat in each form which is indeed wrong and cause of the issue – Karan Thakkar Jun 11 '18 at 07:36

6 Answers6

5

Add class dynamic-form to form tag and remove id from all fields:

echo '<form class="dynamic-form"  action="updatequestion.php" method="post" enctype="multipart/form-data">
            <tr>
            <td><input style="width: 50%" type="text" name="cid" value="'.$quiz_id.'"></td>
            <td><input type="text" name="question" value="'.$question.'"></td>
            <td><input type="text" name="answer" value="'.$answer.'"></td>
            <td><input type="text" name="keywords" value="'.$keywords.'"></td>
            <td><input type="submit" name="qupdate" class="qupdate" value="Update"></td>
            </tr>
            </form>';

Update in JS

$(document).ready(function () {
    $('.dynamic-form').on('submit', function () {
        var formdata = $(this).serialize();
        $.ajax({
            type: "POST",
            url: "updatequestion.php",
            data: formdata,
            success: function (html) {
                //success
            }
        });
        return false;
    });
});
Lovepreet Singh
  • 4,792
  • 1
  • 18
  • 36
4

Here is solution of your problem :-

$('.qupdate').click(function() {   
        var question = $(this).closest("form").find('input[name=question]').val();      
        var answer = $(this).closest("form").find('input[name=answer]').val();
       var keywords = $(this).closest("form").find('input[name=keywords]').val();
       var id = $(this).closest("form").find('input[name=cid]').val();                  
    });
Sanjay Kumar
  • 424
  • 5
  • 15
2

It seems everyone here gave you almost the same answer, but it does not entirely satisfy your problem.

To give you the simplest answers:

  • What you are doing is bad practice by principle, because you should not echo "forms"
  • Each form on the page has the same information besides the inputs, which is wrong.

The correct solution:

  • Start using ajax post only for this purpose
  • Don't use FORM, instead just create a div for each question and have the inputs there with the question id
  • Use a modal to edit the questions, that way when you close the modal you reset the inputs in the modal, giving you the ability to edit again a question and save it.

The solution you want right now:

editquestion.php

        <thead>
              <tr>
                <th style="width: 5%;">S/N</th>
                <th style="width: 20%;">QUESTION</th>
                <th style="width: 40%;">ANSWER</th>
                <th style="width: 30%;">KEYWORDS</th>
                <th style="width: 5%;">SAVE/UPDATE</th>
                </tr>
          </thead>
          <tbody>
            <?php
            $sql = $db->prepare("SELECT * FROM questions");
            $result = $sql->execute();

            while ($row = $result->fetchArray(SQLITE3_ASSOC))
            {
                $quiz_id = $row['quiz_id'];
                $question = $row['question'];
                $answer = $row['answer'];
                $keywords = $row['keywords'];

                echo '<tr>';
                    echo '<td><input style="width: 50%" type="text" name="cid" id="cid" value="'.$quiz_id.'"></td>';
                    echo '<td><input type="text" name="question" id="question" value="'.$question.'"></td>';
                    echo '<td><input type="text" name="answer" id="answer" value="'.$answer.'"></td>';
                    echo '<td><input type="text" name="keywords" id="keywords" value="'.$keywords.'"></td>';
                    echo '<td><input type="button" name="qupdate" class="qupdate" value="Update" onclick="doEdit('.$quiz_id.');"></td>';
                echo '</tr>';
            }
            ?>
        </tbody>
     </table>
<!-- Modal -->
<div id="myModal" class="modal fade" role="dialog">
  <div class="modal-dialog">

    <!-- Modal content-->
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">&times;</button>
        <h4 class="modal-title">Edit Question</h4>
      </div>
      <div class="modal-body">
        <p>Edit your question:</p>
        <p><input type="hidden" id="question_id" id="question_id" value=""></p>
        <p><input type="text" id="question_text" value=""></p>
        <p><input type="text" id="question_answer" value=""></p>
        <p><input type="text" id="question_keywords" value=""></p>

      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" id="doupdate" class="btn btn-default">Update Question</button>
      </div>
    </div>

  </div>
</div>

qupdate.js:

<script>
$(document).ready(function() {

    function doEdit(question_id) {
        /** POPULATE THE MODAL WITH THE QUESTION DATA **/
        $.ajax({
                type: "POST",
                url: "getquestiondata.php", /** create this file, and return the question data from the database based on the "cid" **/
                data: "cid="+question_id+",
                success: function(response){

                        $('#question_id').val(response.cid);
                        $('#question_text').val(response.text);
                        $('#question_answer').val(response.answer);
                        $('#question_keywords').val(response.keywords);
                }
        });
    }

    /** DO THE ACTUAL UPDATE **/
    $('#doupdate').click(function() {

        var question_id = $('#question_id').val();
        var question_text = $('#question_text').val();
        var question_answer = $('#question_answer').val(),
        var question_keywords = $('#question_keywords').val(),

        $.ajax({
            type: "POST",
            url: "updatequestion.php",
            data: "cid="+question_id+"&question="+question_text+"&answer="+question_answer+"&keywords="+question_keywords,
            success: function(html){
                if(html = "true")
                {
                    $('.qupdate').css("opacity", "1");

                    $('#myModal').modal('toggle');

                    // Reset the modal inputs
                    $('#question_id').val("");
                    $('#question_text').val("");
                    $('#question_answer').val("");
                    $('#question_keywords').val("");

                }
                else
                {
                    alert("not successful");
                }
            },
            beforeSend: function(){
                $('.qupdate').css("opacity", "0.5");
            }
        });
        return false;
    });
});
</script>

This code is untested, as I do not have your database or any information about the questions you store, however I am 90% positive that if you use this method it will work for you better than any other answer.

If I made some small typo or mistake, the code is very easy to edit and fix it.

FINAL NOTE: "updatequestion.php" is not the problem here, was never the problem.

Good luck!

Mecanik
  • 1,539
  • 1
  • 20
  • 50
1

As was mentioned by other people ID should be unique on the page. In your case you can get whole form and serialize it's data:

$(document).ready(function() {
    $('.qupdate').click(function() {
        // Clicked $('.qupdate') is now $(this)
        // But we should define $this variable if we want to be able to use it in callbacks.
        // This is more efficient way instead of searching for $('.qupdate') in DOM again and again.
        // Unless you want to set CSS for ALL .qupdate buttons in ALL forms.
        var $this = $(this);

        $.ajax({
            type: "POST",
            url: "updatequestion.php",
            // find closest to .qupdate form and serialize it's data
            data: $this.closest('form').serialize(),
            success: function(html) {
                // use double (or even tripple) equals operator if you want to compare, otherwise you'll just set html as "true"
                // and it'll be always successful
                if(html == "true") {
                    // We use $this variable here which we've defined earlier, and which, as we remember,
                    // stands for clicked $('.qupdate') button
                    $this.css("opacity", "1");
                } else {
                    alert("not successful");
                }
            },
            beforeSend: function() {
                // We use $this variable here which we've defined earlier, and which, as we remember,
                // stands for clicked $('.qupdate') button
                $this.css("opacity", "0.5");
            }
        });
        return false;
    });
});

Update

Perhaps you send in response not exactly "true" or "false"? In order to be sure that you don't send back any extra characters you should call exit after echo:

if ($result)
{
    echo "true";
    exit;
}
else
{
    echo "false";
    exit;
}

If you aren't sure you can simply remove this html check from JS since it never worked actually in your example:

// remove this if-else block
if(html = "true")
{
    $('.qupdate').css("opacity", "1");
}
else
{
    alert("not successful");
}

You can also check what you send and what you get using browser developer tools. For example in chrome press F12 and in the opened panel select Network tab. Now click button in any form and you'll see that new request was sent. Wait for it to complete - Status column should receive some number (200 if everything was ok). Now you can click on this request and see details. There is even video example =) https://www.youtube.com/watch?v=WOQDrGrd9H8

Djengobarm
  • 398
  • 3
  • 7
1

I try to help using Sanjay Kumar answer since you want to save per row

editquestion.php

<thead>
    <tr>
        <th style="width: 5%;">S/N</th>
        <th style="width: 20%;">QUESTION</th>
        <th style="width: 40%;">ANSWER</th>
        <th style="width: 30%;">KEYWORDS</th>
        <th style="width: 5%;">SAVE/UPDATE</th>
    </tr>
</thead>
<tbody>
<?php
    // assuming your database already connected here
    $sql = $db->prepare("SELECT * FROM questions");
    $result = $sql->execute();

    while($row = $result->fetchArray(SQLITE3_ASSOC))
    {
        $quiz_id = $row['quiz_id'];
        $question = $row['question'];
        $answer = $row['answer'];
        $keywords = $row['keywords'];

        // enctype="multipart/form-data" is used if the form contains a file upload, and echo per line for clarity
        echo '<form action="updatequestion.php" method="post">';
        echo '<tr>';
        echo '<td><input style="width: 50%" type="text" name="cid" value="'.$quiz_id.'"></td>';
        echo '<td><input type="text" name="question" value="'.$question.'"></td>';
        echo '<td><input type="text" name="answer" value="'.$answer.'"></td>';
        echo '<td><input type="text" name="keywords" value="'.$keywords.'"></td>';
        echo '<td><input type="submit" name="qupdate" class="qupdate" value="Update"></td>';
        echo '</tr>';
        echo '</form>';
    }
    ?>
    </tbody>
</table>

qupdate.js

// assuming you already loaded jquery library
$(document).ready(function()
{
    $('.qupdate').click(function()
    {
        var id = $(this).closest("form").find('input[name=cid]').val(); 
        var question = $(this).closest("form").find('input[name=question]').val();      
        var answer = $(this).closest("form").find('input[name=answer]').val();
        var keywords = $(this).closest("form").find('input[name=keywords]').val();

        var postData = {'cid' : id, 'question' : question, 'answer' : answer, 'keywords' : keywords};

        $.ajax(
        {
            type: "POST",
            url: "updatequestion.php",
            data: postData,
            success: function(response)
            {
                // note the '==' operator
                if(response == "true")
                {
                    $('.qupdate').css("opacity", "1");
                }
                else
                {
                    console.log(response);
                    alert("not successful");
                }
            },
            error: function(e)
            {
                console.log(e);
            },
            beforeSend: function()
            {
                $('.qupdate').css("opacity", "0.5");
            }
        });
        return false;
    });
});

updatequestion.php

<?php
    session_start();
    require_once("db.php");
    $db = new MyDB();

    if(isset($_POST['cid']) && isset($_POST['question']) && isset($_POST['answer']) && isset($_POST['keywords']))
    {
        $id = filter_input(INPUT_POST, 'cid', FILTER_SANITIZE_STRING);
        $cname = filter_input(INPUT_POST, 'question', FILTER_SANITIZE_STRING)
        $cunit = filter_input(INPUT_POST, 'answer', FILTER_SANITIZE_STRING)
        $keywords = filter_input(INPUT_POST, 'keywords', FILTER_SANITIZE_STRING)

        if($id == '' || $cname == '' || $cunit == '' || $keywords == '')
        {
            echo "one or more parameter is empty";
        }
        else
        {
            $sql = $db->prepare("UPDATE questions SET question = ?, answer = ?, keywords = ? WHERE quiz_id = ?");
            $sql->bindParam(1, $cname, SQLITE3_TEXT);
            $sql->bindParam(2, $cunit, SQLITE3_TEXT);
            $sql->bindParam(3, $keywords, SQLITE3_TEXT);
            $sql->bindParam(4, $id, SQLITE3_INTEGER);

            $result = $sql->execute();

            if ($result)
            {
                echo "true";
            }
            else
            {
                echo "false";
            }
        }
    }
    else
    {
        echo "wrong parameter";
    }
?>

I add some comment in the code.

You can inspect element and check in console tab for additional message if something not working, and i add filter input function for some security and change the comparison for empty variable.

I hope this give you some idea.

Baim Wrong
  • 478
  • 1
  • 10
  • 14
1

You can use in some other way may be it works

$(document).on('click','.qupdate',function() {   
        var question = $(this).closest("form").find('input[name=question]').val();      
        var answer = $(this).closest("form").find('input[name=answer]').val();
       var keywords = $(this).closest("form").find('input[name=keywords]').val();
       var id = $(this).closest("form").find('input[name=cid]').val();                  
    });

//or

jQuery('body').on('click', '.qupdate', function (){
    var form = $(this).closest("form");
    var forminput = form.serialize();
});
Arjun Choudhary
  • 203
  • 3
  • 16