0

I'm trying to create a dynamic table with checkbox. The problem with my code now is that it only should insert the first data in year,code and age. Male and Female would be checkbox, but these two field seem unable to get the correct data, The checkbox should store 1 with it's check 0 if it's uncheck. Please let me know if you see the causes these error in my code, Thank You

POST PHP

if(isset($_POST['add'])){
    $h = $_POST['h'];

    if($h >= 0){
        for($i=0; $i<=$h; $i++){
            $year=intval($_GET['year']);
            $code=intval($_GET['code']);
            $age = $_POST['age'][$i];
            $male = $_POST['male'][$i];
            $female = $_POST['female'][$i];

            $sql = "delete from remark_details WHERE year=:year";
            $query = $dbh->prepare($sql);
            $query -> bindParam(':year',$year, PDO::PARAM_STR);
            $query -> execute();


            $sql2 = "INSERT INTO remark_details (year,code,age,male,female) VALUES('year','code','$age','$male','$female')";
            $query2 = $dbh -> prepare($sql2);
            $query2->execute();
        }
    }
}

PHP

<?php   
    foreach($results as $result){?>
       <tr data-row='0'>
          <td colspan="2"><input class="tableBody" type="text" name="age[]" value="<?php echo $result->age; ?>" autocomplete="off" /></td>
          <td colspan="2"><input class="tableBody" type="checkbox" name="male[]" value="1" autocomplete="off" /></td>
          <td colspan="2"><input class="tableBody" type="checkbox" name="female[]" value="1" autocomplete="off"/></td>
          <td>
          <a href='javascript:void(0);' class='remove' style='cursor:pointer'>
          <i class='material-icons' title='Delete item'>remove_circle_outline</i>
          </a>
          </td>
      </tr>
<?php }} ?>
<input name='h' type='text' id='h' value=0 readonly hidden />

JavaScript

<script>
    document.addEventListener('click', function(to) {
        var rows={};

const getparent=(e,tag)=>{
  let n=e.target;
  while( n.tagName.toUpperCase()!=tag.toUpperCase() ){
    if( n.nodeName==='BODY' )return false;
    n=n.parentNode;
  }
  return n;
};


const datedifference=(d1,d2)=>{
  return {
    y:Math.abs( d2.getFullYear() - d1.getFullYear() ),
    m:Math.abs( d2.getMonth() - d1.getMonth() +1 ),
    d:( Math.abs( ( d2 - d1 ) / ( 1000 * 60 * 60 * 24 ) ) )
  }
};


document.getElementById('tbl_history').addEventListener('change',function(e){
  if( e.target!=e.currentTarget && e.target.nodeType==1 && e.target.tagName=='INPUT' && e.target.type=='month' ){

    let parent=getparent(e,'tr');

    let duration=parent.querySelector('input[type="text"][name="duration[]"]');

    let row=parent.dataset.row;


    if( !rows.hasOwnProperty( row ) )rows[ row ]={};
    rows[ row ][ e.target.name ]=e.target.value;


    if( Object.keys( rows[ row ] ).length==2 ){
      let keys=Object.keys( rows[ row ] );
      let d1=new Date( rows[ row ][ keys[0] ] );
      let d2=new Date( rows[ row ][ keys[1] ] );

      let obj=datedifference(d1,d2);
      duration.value=[obj.y+' Years' , obj.m+' Months' ].join(' ');
    }
  }
});
document.getElementById('tbl_history').addEventListener('click',function(e){
  if( e.target!=e.currentTarget && e.target.nodeType==1 && e.target.tagName=='I' ){
    let p=getparent(e,'tr');
      p.parentNode.removeChild(p);
  }
});

    });

var h=0;
function history() {
  h++;
  var html = `
  <tr data-row='${h}'>
    <td colspan="2"><input class="tableBody" type="text" name="age[]" autocomplete="off" required /></td>
    <td colspan="2"><input class="tableBody" type="checkbox" name="male[]" value="1" autocomplete="off" /></td>
    <td colspan="2"><input class="tableBody" type="checkbox" name="female[]" value="1" autocomplete="off"/></td>
    <td>
      <a href='javascript:void(0);' class='remove' style='cursor:pointer'>
        <i class='material-icons' title='Delete item'>remove_circle_outline</i>
      </a>
    </td>
  </tr>`;

  document.getElementById('tbl_history').insertAdjacentHTML('beforeend',html);
  document.getElementById('h').value=h;
}


</script>
4
  • I don't understand the question. What is happening currently? Why are you only parameterizing one of the queries? Is there an element named add? Also why have male and female as columns, just have a gender column....none of those are likely to address your current issue, just observations until more info is added Commented Jun 7, 2022 at 17:48
  • Because what Im doing here will be allowing user to select both male and female Commented Jun 8, 2022 at 13:35
  • Could have both, or 3 and have a genders table that maps labels to ids Commented Jun 8, 2022 at 14:00
  • Sorry but I don't think this method would suit my case Commented Jun 8, 2022 at 14:11

1 Answer 1

0

It seems, you should make yourself familiar with the checked attribute of the input[type=checkbox] element. See here: input checked

So I use a function like this:

function checked(bool $value): string
{
    return $value ? ' checked="checked"' : '';
}

And your code should look like this:

<input class="tableBody" type="checkbox" name="male[]" value="1" <?php echo checked($result->male) ?> />
<input class="tableBody" type="checkbox" name="female[]" value="1" <?php echo checked($result->female) ?> />

You can delete the autocomplete="off" attribute in checkboxes. It's not supported in checkboxes, so it is ignored by the browser anyway.

I also recommend to just use one DB field for gender.

If you really want to hide the "h" element, then instead of your code you could use the type="hidden" version:

<input name='h' type='hidden' id='h' value=0 />

Edit:

Ok, you told me in the comments that you still have issues when inserting data to the DB. And really, there are a lot of wierd things going on in your code.

First of all, (if it would work) you would in fact insert just one record with your loop, which would be the last one. The year doesn't change in your loop, because of:

$year = intval($_GET['year']);

maybe this one should be (?):

$year = intval($_GET['year'][$i]);

Then you try to delete the record for that year (or all records for that year, but I assume there should only be one, which you want to update). But you bind the WHERE condition with PDO::PARAM_STR. Is the "year" field really a string? You should use PDO::PARAM_INT instead or drop the whole bindParam line and just use:

$query->execute(['year' => $year]);

Next, if you are using MySQL you could drop the whole DELETE action and use REPLACE instead of INSERT. But this can only work, if your PRIMARY KEY is "year". The syntax is quite the same as in INSERT. Just replace the word INSERT with REPLACE in your query. The difference is, REPLACE deletes the existing record with the same PRIMARY KEY before it inserts the new one. INSERT would just do nothing or throw an error instead.

Last, your INSERT statement is also quite buggy. You do not parameterize your query like the DELETE statement, so you could throw away the prepare/execute stuff (which I urge you NOT TO DO!) and use just the query method. But this would put a wide open door for hacker attacks.

Next, you put in hard the strings 'year' and 'code' instead of the variables $year and $code. And you force the variables $age, $male and $female to be strings by putting them into single quotation marks. But the age sould be an integer, and I assume male and female as booleans.

I recommend using a parameterized statement and execute it with an array of parameters:

$sql2 = "INSERT INTO remark_details (year,code,age,male,female) VALUES(?,?,?,?,?)";
$query2 = $dbh->prepare($sql2);
$query2->execute([$year, $code, $age, $male, $female]);

In standard cases this works fine. PDO will sort out the appropriate datatypes for you.

And as final advice: Never trust any user input. You should do some validation/salvation stuff to your $_POST parameters. You will always hear this because it's really important.

Sign up to request clarification or add additional context in comments.

10 Comments

Seem liks I could not do <?php echo checked($result->male) ?>, because after including this code, my whole page was stucked to load
Do you have inserted the function, too? Maybe before then whole foreach($results as $result)? You also could do: <?php echo $result->male ? ' checked="checked"' : '' ?>.
Yes, I've added in the function in javascript
I've also tried to add in the <?php echo $result->male ? ' checked="checked"' : '' ?>, but its still the same
The function I wrote is a PHP function, not a JavaScript function. Do you get some error message? Do you have a proper error handling? For useful error handling in PHP see PHP error reporting.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.