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)
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;