Jason Liu
Jason Liu

Reputation: 818

Display PHP data if an option is selected in a single HTML

I want to show the data from PHP if one of the object is selected. This is the HTML code I wrote but it doesn't work. I kind of know the reason is either because the PHP will get executed once, so it won't display anything after that. Or the PHP part down below did not receive the software object at all. Should I have a Javascript that does the display work? Is that necessary?

<select name="software" onchange="showSoftware(this.value)">
  <?php foreach ($softwareCollection as $software): ?>
  <option value="<?php echo $software ?>">
    <?php echo $software->date?>
  </option>
  <?php endforeach; ?>
</select>
<script>
  function showSoftware(software) {
    jQuery.ajax({
      type: "POST",
      data:  {software: software},
      success: function(data) {
        console.log(data);
      }
    });
  }
</script>

<?php if (isset($_POST['software'])): ?>
    <?php foreach ($software->links as $link): ?>
        <tr>
        <td>
            <?php echo $link->title; ?>
        </td>
        <td>
            <?php echo $link->url; ?>
        </td>
        </tr>
    <?php endforeach; ?>
<?php endif; ?>

Another way to solve it with single html file is to cache all the options and data to the front end like:

<script>
    require(['jquery'], function($) {
        jQuery(document).ready(function($) {
            /*
             * Cache the softwareCollection
             */
            var softwareCollection = [];
            <?php foreach ($softwareCollection = $this->getSoftware() as $software): ?>
            var links = [];
            var softwareId = '<?php echo $software->id ?>';
            var softwareDate = '<?php echo $software->date->date?>';
            <?php foreach ($software->links as $link): ?>
            links.push({
                title: '<?php echo $link->title ?>', description: '<?php echo $link->description?>',
                url: '<?php echo $link->url ?>'
            });
            <?php endforeach; ?>
            softwareCollection.push({id: softwareId, date: softwareDate, links: links});
            <?php endforeach; ?>
            softwareCollection.sort((a, b) => (a.date < b.date));
            const $this = $('select[name=software]');
            for (var i = 0; i < softwareCollection.length; i++) {
                $this.append(
                    '<option value=\"' + softwareCollection[i].id + '\">' + softwareCollection[i].date + '</option>'
                );
            }
        }
    }
</script>

Upvotes: 1

Views: 77

Answers (1)

Grant
Grant

Reputation: 6309

This code is untested, but this should work for what you are trying to achieve. Your changed select triggers the ajax call to a separate software.php file that contains your code and returns the data to the #softwareResponse div. Hopefully this helps you, also I used shortcode echoes to neaten this way of doing things a little.

index.html

<select id="softwareSelect" name="software">
    <?php foreach($softwareCollection as $software): ?>
        <option value="<?=$software;?>"><?=$software->date;?></option>
    <?php endforeach; ?>
</select>

<div id="softwareResponse"></div>

<script>
jQuery(document).ready(function($) {
    $( '#softwareSelect' ).change(function () {
        $.ajax({
            url: 'software.php'
            type: 'POST',
            data:  {software: $(this).val()},
            success: function(data) {
                $('#softwareResponse').html(data);
            }
        });
    });
});
</script>

software.php

<?php if(isset($_POST['software'])): ?>
    <table>
        <?php foreach ($software->links as $link): ?>
            <tr>
                <td><?=$link->title); ?></td><td><?=$link->url); ?></td>
            </tr>
        <?php endforeach; ?>
    </table>
<?php else: ?>
    <p>No software selected.</p>
<?php endif; ?>

Note: this does make the assumption that the $software->links object and the $softwareCollection object both work. If these are arrays, use associative lookups instead, for example $software['date']

Upvotes: 2

Related Questions