Using ISSET with checkboxes

风流意气都作罢 提交于 2019-12-05 18:07:45

This seems a little backwards for creating a search form - it seems more like you're generating a form for each individual result? Annotated code and comments below. I've tried to keep to your coding style in my answer.

$amenity_array = array();
$id            = get_query_var('site');
// this first section gets the selected meta properties for the queried property (if available)
// [skipping for brevity ]
global $imic_options;
if (isset($imic_options['properties_amenities']) && count($imic_options['properties_amenities']) > 1) {
  // this loops over all of the globally defined properties
  foreach ($imic_options['properties_amenities'] as $properties_amenities) {
    // gets the name of the property
    $am_name = strtolower(str_replace(' ', '', $properties_amenities));
    // and sets up to check the box if the property has the defined amenity
    // if this is for a search form, why check boxes based on a result?
    $check   = '';
    if (in_array($properties_amenities, $amenity_array)) {
      // note: this only really needs to be 'checked'
      $check = 'checked="checked"';
    }

Here's where things go a little cross-purposes, though.

    if (isset($_GET['p_am'])) {
      $ams = $_GET['p_am'];

      echo '<div class="checkbox"><input type="checkbox" name="p_am" ' . $check . ' class="styled" value ="' . $properties_amenities . '"><label for="' . $am_name . '">' . $properties_amenities . '</label></div>';
    } else {
      echo '<div class="checkbox"><input type="checkbox" name="p_am" ' . $check . ' class="styled" value ="' . $properties_amenities . '"><label for="' . $am_name . '">' . $properties_amenities . '</label></div>';
    }

This says that all checkboxes have the same name ("p_am") instead of using the loop name for the amenity ($am_name) or some form combination if you want all amenities in the same search input array (e.g. "p_am[$am_name]").

Each checkbox would also change the value of $check if supplied to the $_GET array.

      $ams = $_GET['p_am'];
      if (isset($ams[$am_name])) {
        $check = 'checked';
      }

Each checkbox would have name="p_am['.$am_name.']" as the name.

      echo '<div class="checkbox"><input type="checkbox" name="p_am[' . $am_name . ']" ' . $check . ' class="styled" value ="' . $properties_amenities . '"><label for="' . $am_name . '">' . $properties_amenities . '</label></div>';

If you want each of the amenities to have unique names (looking at the original checkbox which isn't called p_am at all) and not be in an array in PHP, then you would just use the loop name for the amenity ($am_name), like so:

      if (isset($_GET[$am_name])) {
        $check = 'checked';
      }

Each checkbox would have name="'.$am_name.'" as the name.

UPDATE: after the OP was updated, it looks like every checkbox needs to have the same name, but not be keyed values. For this situation, your checkboxes should be called p_am[] (on both search page an original page), and you need to use something like in_array() instead of isset() to check the result, like so:

      if (in_array($properties_amenities, $_GET['p_am'])) {
        $check = 'checked';
      }

Additional note - you're also using $am_name for the label, without actually setting the id attribute on the checkbox to match to, as well as not stripping out non-id characters (like parentheses), so the label association won't work.

      echo '<div class="checkbox"><input type="checkbox" name="' . $am_name . '" ' . $check . ' class="styled" value ="' . $properties_amenities . '"><label for="' . $am_name . '">' . $properties_amenities . '</label></div>';

For the bootstrap select, you're just missing a check for which options are selected:

<select name="property_type[]" id="pt-multi" class="form-control multi-select2" multiple="multiple">
<?php
$terms = get_terms( "property-type", array( 'hide_empty' => 0 ) );
$count = count($terms);
if ( $count > 0  ){
  echo "<option value='Any'>All</option>";
  foreach ( $terms as $term ) {
    // if the option is 'checked', you need to add the 'selected' atttibute here
    echo "<option value='" . $term->slug . "'>" . $term->name . "</option>";
  }
}
?>
</select>

So the inside of the loop would look something like this instead:

    // for efficiency's sake should live outside the loop as a one-off, but here for illustrative purposes
    $types = $_GET['property_type'];
    $selected = isset($types[$term->slug]) ? 'selected' : '';
    echo "<option value='" . $term->slug . "'" . $selected . ">" . $term->name . "</option>";

If you're using an older version of bootstrap select, you may need to have the selected string be 'selected="selected" or data-selected="true", depending on the version you're using. For a current version, the above string should be fine.

If the <select> isn't meant to be an array of options either (i.e. not multiple), then the [] should be removed from the name, and would operate similarly to the checkbox code:

<select name="property_type" id="pt-multi" class="form-control multi-select2">
<?php
$terms = get_terms( "property-type", array( 'hide_empty' => 0 ) );
$count = count($terms);
if ( $count > 0  ){
  echo "<option value='Any'>All</option>";
  foreach ( $terms as $term ) {
    $type = $_GET['property_type'];
    $selected = isset($type) && $type == $term-slug ? 'selected' : '';
    echo "<option value='" . $term->slug . "'" . $selected . ">" . $term->name . "</option>";
  }
}
?>
</select>

The original HTML for the <select> doesn't actually 'work' as such either - all it's doing is adding a duplicate <option> to the top of the options list, and because nothing is selected, the form will treat the duplicate created at the top as 'selected' for the <select>.

UPDATE 2: the reason that the search function is breaking with an array of checkbox inputs is because you are using the LIKE comparison for your meta query. From the documentation on WordPress Meta Query:

It can be an array only when compare is 'IN', 'NOT IN', 'BETWEEN', or 'NOT BETWEEN'.

The documentation also shows examples of how to join these together. Since you haven't supplied how you're actually making the search query this is guessing a little, but it looks like for an array of checkboxes your code should be something similar to:

if (!empty($amenities)) {
  foreach ($amenities as $amenity) {
    array_push($meta_query, array(
      'key' => 'imic_property_amenities',
      'value' => $amenity,
      'compare' => 'LIKE'
    ));
  }
}

As with the examples in the documentation, you'll need to make sure there's a relation => 'OR' or relation => 'AND' to define how you want your search to operate.

what Fred's meant in the comment is something like this:

<input type="checkbox" value="condo" name="var_name[]">

the [] at the end of the name attribute is to tell PHP that it should treat the variable as an array.

and then in the PHP script, you can just check for the array length using somthing like:

$arr = $_POST['var_name']; echo count($arr);

based on leith's comment, if it is auto generated, then you should not be bothered to check the checkboxes manually.

instead, just make the selected options be selected, for example:

<?php
$selections = $_GET['property_type'];   // or something similar
?>
<select name="property_type[]" id="pt-multi" class="form-control multi-select2" multiple="multiple">
<?php
$terms = get_terms( "property-type", array( 'hide_empty' => 0 ) );
$count = count($terms);
if ( $count > 0  ){
    echo "<option value='Any'>All</option>";
    foreach ( $terms as $term ) {
        $selected = in_array($term->slug, $selections);
        echo "<option value='" . $term->slug . "' " . ($selected?' selected':'') . ">" . $term->name . "</option>";
    }
}
?>
</select>

see this fiddle https://jsfiddle.net/u1w158tp/

in it you just selected the options and it will automatically checked the checkboxes

Your checkboxes has the same name. Try to add different name or use "p_am[]" to treat them as array.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!