表单复选框值将转到动态URL

时间:2021-02-18 作者:Cheo Molina

嗯,我有一个数据库,主要是在我网站的一个页面上用“高级自定义字段”创建的,该数据库应该可以获取一个城市的所有商店(自定义帖子类型)并向我显示,通过动态更改URL,我可以使其获得流派、类型等;www.urltoshow。com/ville/Paris?流派=男人;。。。

我之前的工作方式是使用这段简单的代码

$genre = $_GET[\'genre\'];
if(empty($genre))$genre = array(\'Woman\',\'Man\'); //For getting all of them when opening the page
                               
if(have_posts() ):
$args = array( \'post_type\' => \'store\', 
              \'meta_key\' => \'store_client_type\' ,
             \'meta_query\' => array(
                                 array(
                                \'relation\' => \'AND\',
                                \'genre_clause\' => array(
                                    \'key\' => \'store_genre\', 
                                    \'value\' => $genre,
                                    ), 
                                )
                            ),  
             );
$loop = new WP_Query( $args );
为了筛选客户,我会使用如下表单:

<form class="sample-form"
method="GET"
action="#"
target="_top">
      <select name="genre"
       id="genre">
        <option value="" disabled selected>Genre</option>
        <option value="woman">Woman</option>
        <option value="man">Man</option>
      </select>
      <input type="submit"
             value="GO"
             class=" button-rules">
</form>
它通常工作得很好。。。但是,当谈到复选框时,当我想选择一种风格(有些商店会有多种风格,比如复古和经典,或者豪华和复古,或者可能只是豪华),我需要它显示一个或多个值,我需要使用复选框,一个简单的例子是

<input type="checkbox" id="test1" name="style"
value="Streetwear/Sportwear"/><label for="test1">Streetwear/Sportwear</label>
<br>
<input type="checkbox" id="test4" name="style"
value="Casual/Décontracté"/><label for="test4">Casual/Décontracté</label>
但是查询不起作用,并且在添加该查询的结果时不显示任何内容。。。这是我的完整代码

<!-- THE FORM -->

    
<form class="sample-form"
method="GET"
action="#"
target="_top">
<select name="genre"
    id="genre">
        <option value="" disabled selected>Genre</option>
        <option value="woman">Woman</option>
        <option value="man">Man</option>
</select>
<select name="type"
    id="type">
        <option value="" disabled selected>type</option>
        <option value="friperie">Second hand</option>
        <option value="ressourcerie">Artisan</option>
</select>
<select name="prix"
id="prix"
class="bars">
<option value="" disabled selected>prix</option>
<option value="€">€</option>
<option value="€€">€€</option>
<option value="€€€">€€€</option>
</select>
<--! AREA TO SOLVE -->
<input type="checkbox" id="test1" name="style"
value="Streetwear/Sportwear"/><label for="test1">Streetwear/Sportwear</label>
<br>
<input type="checkbox" id="test4" name="style"
value="Casual/Décontracté"/><label for="test4">Casual/Décontracté</label>
<br>
<input type="checkbox" id="test5" name="style"
value="Luxe"/><label for="test5">Luxe</label>
<br>
<input type="checkbox" id="test6" name="style"
value="Classique"/><label for="test6">Classique</label>
<br>
<input type="submit"
value="GO"
class=" button-rules">
<div submit-success>
Success!
</div>
<div submit-error>
Error!
</div>
<!-- THE QUERY AND POST -->

 <?php 
 $prix = $_GET[\'prix\'];
 $genre = $_GET[\'genre\'];
 $type = $_GET[\'type\'];
 $style = $_GET[\'style\'];
  if(empty($prix))$prix = array(\'€€€\',\'€€\',\'€\');
  if(empty($genre))$genre = array(\'Woman\',\'Man\');
  if(empty($type))$type = array(\'friperie\',\'ressourcerie\',\'dépôt-vente\');
  if(empty($style))$style = array(\'Casual/Décontracté\',\'Classique\',\'Luxe\',\'Vintage\',\'Street/Sports\',\'Gothic/Underground\' );  ?>
        

<div class="row">         
                            if(have_posts() ):
$args = array( \'post_type\' => \'store\', 
              \'meta_key\' => \'store_client_type\' ,
             \'meta_query\' => array(
                                 array(
                                \'relation\' => \'AND\',
                                \'price_clause\' => array(
                                    \'key\' => \'store_prix\', 
                                    \'value\' => $prix,
                                    ),
                                \'genre_clause\' => array(
                                    \'key\' => \'store_genre\', 
                                    \'value\' => $genre,
                                    ),
                                \'type_clause\' => array(
                                    \'key\' => \'store_type\', 
                                    \'value\' => $type,
                                    ),
                                \'style_clause\' => array(
                                    \'key\' => \'store_style\', 
                                    \'value\' => $style,
                                    ),  
                                )
                            ),
              \'orderby\' => array(
                            \'city_clause\'  => \'desc\',
                            \'price_clause\'  => \'desc\',
                            \'genre_clause\'  => \'desc\',
                            \'type_clause\'  => \'desc\',
                            \'style_clause\'  => \'desc\', 
                        )       
             );
$loop = new WP_Query( $args );
    while($loop->have_posts()):  $loop->the_post(); ?>
                <div class="col-12">
                    <h4><?php the_title(); ?></h4>
                  </div>
                            <?php     
    endwhile;  
    endif;
    wp_reset_query(); ?> 
如果不使用$样式使用此代码,它会很好地工作并显示所有内容,但如果添加$样式,则不会显示任何内容

1 个回复
最合适的回答,由SO网友:joshmoto 整理而成

I am no expert but you are submitting multiple checkboxes with the same name attribute.

Your current form GET action will return the url params like this for example...

http://www.urltoshow.com/ville/paris?style=Classique&syle=Luxe

So because there are 2 usages of param style in the url above, it means PHP $_GET[\'style\'] will only return the last getted param value.

$_GET[\'style\'];
/* only returns Luxe from url above */

Annoying I there is no way to covert multiple url parameter instances into a single value with PHP...




So a work around is use some javascript to handle your form submission field data, and any multiple field name checkbox usages, accumulate these checkbox values to an array, and then convert that array to comma separated value which can be passed into a single style url parameter value.

For example, your form... (form attributes modified)

<form id="sample-form" method="GET" action="/ville/paris">

  <select name="genre">
    <option value="">Select genre...</option>
    <option value="woman">Woman</option>
    <option value="man">Man</option>
  </select>

  <select name="type">
    <option value="">Select type...</option>
    <option value="friperie">Second hand</option>
    <option value="ressourcerie">Artisan</option>
  </select>

  <select name="prix">
    <option value="">Select prix...</option>
    <option value="€">€</option>
    <option value="€€">€€</option>
    <option value="€€€">€€€</option>
  </select>

  <br />

  <input type="checkbox" id="test1" name="style" value="Streetwear/Sportwear" />
  <label for="test1">Streetwear/Sportwear</label>
  
  <br />

  <input type="checkbox" id="test4" name="style" value="Casual/Décontracté" />
  <label for="test4">Casual/Décontracté</label>
  
  <br />

  <input type="checkbox" id="test5" name="style" value="Luxe" />
  <label for="test5">Luxe</label>
  
  <br />

  <input type="checkbox" id="test6" name="style" value="Classique" />
  <label for="test6">Classique</label>

  <br />

  <input type="submit" value="Go" />

</form>

Some jQuery javascript to handle the form submission... (read comments)

// sample form on submit
$(\'#sample-form\').on(\'submit\', function(e) {

  // prevent default
  e.preventDefault();

  // set empty submission object
  let submission = {};

  // for each of this form submit event target object entries as key/field
  for (const [key, field] of Object.entries(e.target)) {

    // if object entry (field) has a name attribute
    if (field.name) {

      // if field type is
      if (field.type === \'checkbox\') {

        // if checkbox is checked
        if (field.checked) {
        
          // if submission does not have syle property
          if (!submission.hasOwnProperty(\'style\')) {

            // set field name as array
            submission[field.name] = [];

          }

          // add name/value to submission object
          submission[field.name].push(field.value);

        }

      } else if (field.value) {

        // add name/value to submission object
        submission[field.name] = field.value;

      }

    }

  }

  // now let loop through our submission and check for arrays
  for (const [name, value] of Object.entries(submission)) {

    // if submission value is array
    if (Array.isArray(value)) {

      // let convert array to string
      submission[name] = value.join(\',\');

    }

  }
  
  // convert submission object to url safe params string
  let submission_url_params = $.param(submission);
  
  // if we have submission params
  if(submission_url_params) {
  
    // success actions
  
    // create our submission action url
        let submission_url_action = this.action + (submission_url_params ? \'?\' + submission_url_params : \'\');
    
    // un-comment this to actually fire the form submission
    window.location.href = submission_url_action;

  // else no submission params
  } else {
  
    // no submission data actions
  
  }

});

Here is fiddle of the above form submit script...

So what this script does when the form is submitted is...

  • initially loops through all the form fields that have a name attribute.
  • it also checks if the field type is checkbox. If it is a checkbox with the same name it converts checkbox values into an array.

Example form field selection... (screenshot)

enter image description here

Initial loop in script returns this... (currently style is array)

{
  genre: "woman",
  prix: "€€",
  style: [
    "Casual/Décontracté", 
    "Classique"
  ],
  type: "ressourcerie"
 }

But then at the end of the script it loops any submission value which is_array and coverts to a comma separated string... (style is now a comma separated string)

{
  genre: "woman",
  prix: "€€",
  style: "Casual/Décontracté,Classique",
  type: "ressourcerie"
}

So now our submission has no arrays and all parameters are strings, the script then turns the submission into url params...

?genre=woman&type=ressourcerie&prix=%E2%82%AC%E2%82%AC&style=Casual%2FD%C3%A9contract%C3%A9%2CClassique



Now the PHP part, we can use these url params to build your $query PHP args for your wordpress product loop...

Here is little helpful get_var function to handle $GET usages...

function get_var($name = false, $default = false) {
  if($name === false) {
    return $_REQUEST;
  }
  if(isset($_REQUEST[$name])) {
    return $_REQUEST[$name];
  }
  return $default;
}

Get and set our URL vars using get get_var helper function...

// get and set url params to varibles
$genre  = get_var(\'genre\',[\'Woman\',\'Man\']);
$type   = get_var(\'type\',false);
$prix   = get_var(\'prix\',false);
$style  = get_var(\'style\',false);

Meta Relation Query Option

Now lets build our meta query arguments...

// begin our query args
$args = [
  \'post_type\'       => \'store\',
  \'post_status\'     => \'publish\',
  \'posts_per_page\'  => 40,
  \'orderby\'         => \'ASC\',
  \'meta_query\'       => [
    \'relation\' => \'AND\'
  ]
];

// if genre url param
if($genre) {

  // this genre is_array check/loop might not be necessary, you could set the above $genre default as false which should return all genres anyway
  // but i\'ve included your default `[\'Woman\',\'Man\']` arrat meta query for example...
 
  // if genre is array [\'woman\',\'man\']
  if(is_array($genre)) {

    // convert genre to genres
    $genres = $genre;
    
    // foreach genre
    foreach($genres as $genre) {
       
      // add genre meta query to our args
      $args[\'meta_query\'][] = [
        \'genre_clause\' => [
          \'key\'   => \'store_genre\', 
          \'value\' => $genre
        ]
      ];
      
    }
  
  // else genre is singular (not array)
  } else {
  
    // add genre meta query to our args
    $args[\'meta_query\'][] = [
      \'genre_clause\' => [
        \'key\'   => \'store_genre\', 
        \'value\' => $genre
      ]
    ];

  }

}

// if type url param
if($type) {
  
  // add type meta query to our args
  $args[\'meta_query\'][] = [
    \'type_clause\' => [
      \'key\'   => \'store_type\', 
      \'value\' => $type
    ]
  ];

}

// if prix url param
if($prix) {
  
  // add prix meta query to our args
  $args[\'meta_query\'][] = [
    \'type_clause\' => [
      \'key\'   => \'store_prix\', 
      \'value\' => $prix
    ]
  ];

}

// if style url param
if($style) {

  // we need to explode our comma separated styles param into an array
  $styles = explode(\',\',$style);
  
  // foreach styles param array
  foreach($styles as $style) {
       
    // add style meta query to our args
    $args[\'meta_query\'][] = [
      \'style_clause\' => [
        \'key\'   => \'store_style\', 
        \'value\' => $style
      ]
    ];
      
  }

}

Taxonomy Relation Query Option

Now lets build our taxonomy query arguments...

// begin our query args
$args = [
  \'post_type\'       => \'store\',
  \'post_status\'     => \'publish\',
  \'posts_per_page\'  => 40,
  \'orderby\'         => \'ASC\',
  \'tax_query\'       => [
    \'relation\' => \'AND\'
  ]
];

// if genre url param
if($genre) {

  // add genre tax query to our args
  $args[\'tax_query\'][] = [
    \'taxonomy\'  => \'genre\', // your genre taxonomy name
    \'field\'     => \'slug\',
    \'terms\'     => is_array($genre) ? $genre : [ $genre ],
  ];

}

// if type url param
if($type) {
  
  // add type tax query to our args
  $args[\'tax_query\'][] = [
    \'taxonomy\'  => \'type\', // your type taxonomy name
    \'field\'     => \'slug\',
    \'terms\'     => [ $type ],
  ];

}

// if prix url param
if($prix) {
  
  // add prix tax query to our args
  $args[\'tax_query\'][] = [
    \'taxonomy\'  => \'prix\', // your prix taxonomy name
    \'field\'     => \'slug\',
    \'terms\'     => [ $prix ],
  ];

}

// if style url param
if($style) {

  // we need to explode our comma separated styles param into an array
  $styles = explode(\',\',$style);
  
  // add style tax query to our args
  $args[\'tax_query\'][] = [
    \'taxonomy\'  => \'style\', // your style taxonomy name
    \'field\'     => \'name\', // changed to name as your style checkbox values are names (not slugs)
    \'terms\'     => [ $styles ],
  ];

}

Now using our $args we simply loop...

$loop = new WP_Query($args);
    while($loop->have_posts()):  $loop->the_post();
       the_title();   
    endwhile;  
endif;

相关推荐

按字母顺序对填充的GravityForms列表进行排序

希望有人能帮助一个新手,因为我不知道该怎么做。我的函数中有以下代码。填充GravityForms表单产品“复选框列表”的php。用户使用复选框在网站上选择GF表单中的产品。每个拉入复选框列表的产品都是一个单独的WordPress帖子。我很难按字母顺序对复选框进行排序,以便用户可以在100多个不同的产品(帖子)中轻松找到产品。我找不到任何其他看起来有点相似的论坛帖子,所以我可以自己解决如何排序。第一部分是按字母顺序对复选框进行排序,我需要的第二部分是排除两个标记为“系统”的帖子,或者排除这两个帖子,因为它们