• 8
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

Form echoed with PHP not submitting using ajax

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.

      • 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...)
    • 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.
      • 1
    • 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.

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;
    });
});
  • 5
Reply Report

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();                  
    });
  • 4
Reply Report

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!

  • 2
Reply Report

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

  • 1
Reply Report

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.

  • 1
Reply Report

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();
});
  • 1
Reply Report

Warm tip !!!

This article is reproduced from Stack Exchange / Stack Overflow, please click

Trending Tags

Related Questions