2

I have 2 dropdowns as below;

<div class="form-group">
<label>Category</label>
<select class="form-control bg-dark btn-dark text-white" id="drpcategory" name="drpcategory" onchange="submit()" required>
<?php
$category = ''.$dir.'/template/post/category.txt';
$category = file($category, FILE_IGNORE_NEW_LINES);

foreach($category as $category)
{
echo "<option value='".$category."'>$category</option>";
}
?>
</select>
</div>

<div class="form-group">
<label>Item</label>
<select class="form-control bg-dark btn-dark text-white" id="drpitem" name="drpitem">
<?php
$category = $_POST['drpcategory'];
$item = ''.$dir.'/template/post/'.$category.'/item.txt';
$item = file($item, FILE_IGNORE_NEW_LINES);

foreach($item as $item)
{
echo "<option value='".$item."'>$item</option>";
}
?>
</select>
</div>

The drpitem dropdown is populated according to the selection made by the drpcategory dropdown. Currently I can catch the $category variable in drpitem by $_POST['drpcategory'] and it works. But the problem is that I use submit() function for the onchange event in drpcategory, so that the whole page simply reloads and then drpitem gets populated as expected. This makes the drpcategory to reset back to it's default selection since it doesn't remember what was it's value before the page was reloaded.

How can I catch the $_POST['drpcategory'] in drpitem without reloading the page? I'm trying to stick with PHP and use minimum amount of JavaScript if required.

This question was later updated and answered here: AJAX POST & PHP POST In Same Page

haZh
  • 127
  • 2
  • 12
  • 2
    please add the `submit` function to the question – Professor Abronsius Mar 01 '19 at 07:09
  • how is the first dropdown supposed to affect the second? Does any data get sent to the server when the first select menu is changed? – Professor Abronsius Mar 01 '19 at 07:37
  • @RamRaider It takes the selected value from the 1st dropdown and apply it to the file path that's used to populate the 2nd dropdown. This is already tested and works for me as I was expecting, but the problem is that the page completely reloads after each selection and 1st dropdown lose memory about it's previous selection before page reload. – haZh Mar 01 '19 at 07:44
  • remove the `submit` function – Professor Abronsius Mar 01 '19 at 07:44
  • ok - I've not had my 2nd coffee yet this morning but I see now how I think it is supposed to work. You'll need to use ajax for this – Professor Abronsius Mar 01 '19 at 07:45
  • @RamRaider Exactly. Looking for a simple AJAX solution here. – haZh Mar 01 '19 at 07:49

3 Answers3

1

Once the vital piece of information is know it is quite simple and no doubt you could have found other examples of chained select using ajax but an untested example could be of use/interest.

The change event fires the ajax request to the same php page in this case - the php at the top of the script processes this POST request and uses the POST data to build the path to the next menu source file.

<?php
    /* top of same page to the javascript/html */
    if( $_SERVER['REQUEST_METHOD']=='POST' && !empty( $_POST['drpcategory'] ) ){
        ob_clean();

        $category=$_POST['drpcategory'];
        $path=$dir.'/template/post/'.$category.'/item.txt';
        $item = file($path, FILE_IGNORE_NEW_LINES);
        foreach( $item as $item ) printf('<option value="%s">%s',$item,$item);

        exit();
    }

?>
<!doctype html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>chained select</title>
        <script>
            const ajax=function( params ){
                let xhr=new XMLHttpRequest();
                with( xhr ){
                    onreadystatechange=function(e){
                        if( this.status==200 && this.readyState==4 ){
                            document.querySelector('select[name="drpitem"]').innerHTML=this.response
                        }                       
                    }
                    open( 'POST', location.href, true );
                    setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                    send( params );
                }
            }

            document.addEventListener('DOMContentLoaded', event=>{
                document.querySelector('select[name="drpcategory"]').addEventListener('change',e=>{
                    e.preventDefault();
                    ajax( 'drpcategory='+e.target.value );
                },false);
            },false );

        </script>
    </head>
    <body>
        <div class="form-group">
            <label>Category</label>
            <select class="form-control bg-dark btn-dark text-white" name="drpcategory" required>
            <?php

                $category = $dir.'/template/post/category.txt';
                $category = file($category, FILE_IGNORE_NEW_LINES);

                foreach($category as $category) {
                    printf('<option value="%s">%s',$category,$category);
                }
            ?>
            </select>
        </div>

        <div class="form-group">
            <label>Item</label>
            <select class="form-control bg-dark btn-dark text-white" name="drpitem"></select>
        </div>
    </body>
</html>
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46
  • You are on the right direction mentioning about AJAX here. But due to me being a noob at coding, just looking at this code is too complicated for me. What would be the shortest way that I can override the default page reload behavior of submit() function using AJAX without reloading the page? I mean the same default submit() without page reload. I'm also using JQUERY if that shortens the code even more. – haZh Mar 01 '19 at 08:12
  • well, I think the above is quite concise. There is nothing there that doesn't need to be there really to make this work. I don't know where you think you might be able to make shortcuts - you need PHP to read the textfile so either the page needs to reload or be done with ajax ( there are other possibilities ) - sure you could use the methods associated with jQuery ( don't use it myself so cannot help there ) but essentially it'll just be a different version of the above for the most part. the ajax function could be simplified - you only need to send 1 parameter I guess – Professor Abronsius Mar 01 '19 at 08:27
  • I think it's time for a new question. +1 for directing to the right track towards AJAX. – haZh Mar 01 '19 at 08:33
  • @haZh jQuery is not a necessity, Just try copy pasting this solution in your page and it should work. if not you can add details in the question. – techie_28 Mar 01 '19 at 08:45
  • @techie_28 I'm not saying this doesn't work, but I have tried this but can't get it to work probably because I don't understand standard JavaScript. I just can't paste this entire code and use it even if it actually works. Maybe JQUERY isn't necessary, but for newbies like me, I prefer to use it for the code to look more simpler. – haZh Mar 01 '19 at 08:56
  • @haZh Okay. Open your browser console(F12 key or right click > inspect) then again try running this code. You should see something under the `Console` or `Network` panel which would tell you why it is not working,Please post that in the question. – techie_28 Mar 01 '19 at 09:03
0

You can put the value of the first Dropdown in a session.

Then on submit you can simply set the first dropdown value to the value in the session.

No change on the submit handling required

Artur Leinweber
  • 256
  • 1
  • 6
0

You can have an if condition in the foreach statement.

foreach($category as $category_item)
{
    if ($_POST['drpcategory'] == $category_item) {
        echo "<option selected value='".$category_item."'>".$category_item."</option>";
    } else {
        echo "<option value='".$category_item."'>".$category_item."</option>";
    }
}

I see your foreach statement is not correct in syntax. Do not use the same variable name for the list and the item.