Jump to content

How to filter by radio buttons or checkboxes values (page fields) and get the results via (sub-)links?


Christophe
 Share

Recommended Posts

Hello,

Let’s call a page « Directory », redirected - for the moment at least - to its first child page.

http://www.domainname.com/fr/directory/
 

So its children are something like:

mannequins-modeles/ → template : directory_listing_mm

autres-artistes/ → template : directory_listing_autres_artistes

 

With thumbnail images of the first image of their children pages (linking to these children page).

 

So for Models it’s listing all the models, and for Other artists all the artists.

And there is pagination (limit=12).

 

On the left panel/column, there is a link to Models and one to Other artists (it will possibly be on the directory children and their children pages).

 

It’s the first time I have this use case, so I don’t know how to do it at all, and what would be the best approach/technique (« search »/find functionality - and page, ajax-like…).

 

For Models, I need to use the civilite field (required page field with radio output) to have Women and Men sub-links to filter by gender.

So I have something like Miss, Mrs and Mr as radio buttons.

(Example path for a hidden page: /fr/outils/choix-civilite/mademoiselle/
It may be better to use page ids if needed if later other languages are activated. I don't remember if it's really necessary.)

 

For Other artists, I need to use the qui_2 field (required page field with checkboxes output) to get sub-links corresponding to each of the checkboxes and filter depending on these.

 

Here, at least now, I just want/need to filter by one checkbox at a time, and some artists can be listed in more than one place/sub-link page as they can have multiple skills (there is another field for their profession but it’s not important here). For the moment 15 skills exist.

(Example path for a hidden page: /fr/outils/choix-autre-artiste-vous-etes/musicien/)

 

Thank you for any help/advice!

Have a nice week!

Edit: NB: I can PM the website urls if needed...

Edit 2: ProcessWire 2.8.35

Link to comment
Share on other sites

I'm slowly trying to do it with some logic, the little knowledge I have, and looking at the skycrapers demo profile files (removing what doesn't seem to concern my use case to see things more clearly). The positive aspect is that I'm learning/progressing.

I don't know if I'll succeed, I guess I'll have to tell the client (the kind we all know that is always in a hurry when it benefits him/her, who thinks that adding this or that functionnality is easy, who asks for relatively complicated things/functionality at the last moment, and so on) to be more patient.

I'll post some code here as soon as I have enough of it to show.

Have a nice day!

  • Like 2
Link to comment
Share on other sites

I'm including _head.php, _foot.php, and also _left_menu.php now. I also use an _init.php file.

Here is the code that I have for the moment in the _left_menu.php file:

<?php
$mannequins_modeles = $pages->get(1050);
$autres_artistes = $pages->get(1051);
echo "<ul id='left_menu'><li><a href='" . $mannequins_modeles->url . "'>$mannequins_modeles->title</a>";
echo "<ul><li><a href='" . $mannequins_modeles->url . $woman ."/'>" . $woman . "</a></li>";
echo "<li><a href='" . $mannequins_modeles->url . $man . "/'>" . $man . "</a></li></ul></li>";
echo "<li><a href='" . $autres_artistes->url . "'>$autres_artistes->title</a><ul>";
foreach($choix_autre_artiste->children('include=hidden') as $skill) { 
  echo "<li><a href='" . $autres_artistes->url . $skill->name . "/'>$skill->title</a></li>";
}          
echo "</ul></li></ul>";
?>

I'm not sure it is correct. For example if civilite= put twice is ok.

I'm going to start working on the search.php file. I don't know exactly for the moment how I'm going to code all this and if I'm in the right direction.
I'm going to study the skycrapers demo profile search.php file to see if it can help me.

I'm not sure if _left_menu.php and search.php will be sufficient.
And if I need to separate with if else the parts for models and for other artists, and inside insert other if else conditions.

I just want to have the search page echo something different depending on the link or sub-link and the "query" in its URL.
It's my first time trying to do something like that, a sort of basic search form. Later I'll certainly have to create more complex/advanced ones.

I just need to figure out if this basic "search form" is "simple" to create or more complex.

One of the 2 websites I created with kraken css.
I'll redirect the directory to the women models after if possible.
(Website started a few days last year, and improved a bit during a few days now. I have a nice "conditional" form that now saves data as ProcessWire pages (Form Builder)...).

Edit2: I wouldn't mind a bit of help...

Link to comment
Share on other sites

This is the code for the  2 non-filtered "listing" pages:

<?php		
$children = $page->children("limit=12");
$pagination = $children->renderPager();								
foreach($children as $child) {
  if($child->joindre_au_maximum_4_photos->count) {
    $thumb = $child->joindre_au_maximum_4_photos->first()->size(200,200);				
    echo "<div><a href='$child->url'><img src='$thumb->url' width='$thumb->width' height='$thumb->height' /></a><p><strong><em>$child->votre_pseudo</em></strong><br />$child->pays</p></div>";				
  }
}
echo $pagination;					
?>

(The image field is mandatory but I left the if condition. I'm going to remove it in search.php.)

Link to comment
Share on other sites

I don't quite understand you're explanation ???.

So let's see if i got it right, you have a directory page where you display pages from different templates (directory_listing_mm, directory_listing_autres_artistes) and in the sidebar you want to have links that filter the results based on some fields (which are checkboxes).

/fr/annuaire-des-books/mannequins-modeles/ and /fr/annuaire-des-books/mannequins-modeles/ have their own template files right?

Link to comment
Share on other sites

Hello @fbg13,

I hope you are doing well!

/fr/annuaire-des-books/mannequins-modeles/ and /fr/annuaire-des-books/autres-artistes/ have their own template files (even if the code is the same, at least for the moment).

I'm trying to create the search.php file starting from the skycrapers demo profile search.php file, removing, adding, and changing things, but as it's my first time I don't really know what I'm doing. I can only imagine/guess some things for the moment. I'm turning a bit around. I think I understand most of the file but I don't really know how to convert it for my use case.

And I guess that for the "Autres artistes" filtered children pages It can be more "automated", and that for the "Mannequins Modèles" filtered children pages it is a bit different as there is Miss & Mrs (Women/Femmes) or Mr (Men/Hommes).

(At the end I'll also need to include the corresponding sub-link texts as h2 tags in the results pages.)

Capture du 2016-11-10 22-21-30.png

Link to comment
Share on other sites

Just now it's like this:

<?php include('./_head.php'); // include header markup ?>

		<!-- main content -->
		<div id='content'>
			
		  <h1 class='text-center'><?php echo $title; ?></h1>
      <div id="directory_listing" class="row">
        <div class="grid-fourth">      
        <?php include('./_left_menu.php'); ?>
        </div>

			  <div class="grid-three-fourths">	

        <?php

	      // look for a GET variable named 'q' and sanitize it
	      $q = $sanitizer->text($input->get->q); 

	      // did $q have anything in it?
	      if($q) { 

		      // Sanitize for placement within a selector string. This is important for any 
		      // values that you plan to bundle in a selector string like we are doing here.
		      $q = $sanitizer->selectorValue($q); 

		      // Search the title and body fields for our query text.
		      $selector = "title|body~=$q";

		      // If user has access to admin pages, lets exclude them from the search results.
		      // Note that 2 is the ID of the admin page, so this excludes all results that have
		      // that page as one of the parents/ancestors. This isn't necessary if the user 
		      // doesn't have access to view admin pages. So it's not technically necessary to
		      // have this here, but we thought it might be a good way to introduce has_parent.
		      if($user->isLoggedin()) $selector .= ", has_parent!=2"; 

		      // Find pages that match the selector
		      $matches = $pages->find($selector); 

		      // did we find any matches? ...
		      if($matches->count) {

			      // we found matches
			      echo "<h2>" . __("Nous avons trouvé") . $matches->count . __("page(s) correspondant à votre requête:") . "</h2>";
			
			      // output navigation for them (see TIP below)
			      echo "<ul class='nav'>";

			      foreach($matches as $match) {
				      echo "<li><a href='$match->url'>$match->title</a>";
				      echo "<div class='summary'>$match->summary</div></li>";
			      }

			      echo "</ul>";

		      } else {
			      // we didn't find any
			      echo "<h2>" . __("Désolé, aucun résultat n'a été trouvé.") . "</h2>";
		      }

	      } else {
		      // no search terms provided
		      echo "<h2>" . __("Please enter a search term in the search box (upper right corner)") . "</h2>";
	      }

	      ?>
	   
        <?php		
			  $children = $page->children("limit=12");
			  $pagination = $children->renderPager();								
			  foreach($children as $child) {				  
                $thumb = $child->joindre_au_maximum_4_photos->first()->size(200,200);				
                echo "<div><a href='$child->url'><img src='$thumb->url' width='$thumb->width' height='$thumb->height' /></a><p><strong><em>$child->votre_pseudo</em></strong><br />$child->pays</p></div>";	
			  }
			  echo $pagination;					
			  ?>	
       </div>
      </div>
		</div>

<?php include('./_foot.php'); // include footer markup ?>

I'll update the code here when/if I make progress.

Link to comment
Share on other sites

You can use url segments (need to enable them for each template you need to have them).

Then the Femmes link will be /fr/annuaire-des-books/mannequins-modeles/femmes and in the template file for directory_listing_mm you do this

$filter = "";
if($input->urlSegment1 == "femmes")
{
	$filter = ", civilite=value_representing_femmes";
}
if($input->urlSegment1 == "hommes")
{
	$filter = ", civilite=value_representing_hommes";
}
$results = $pages->find("template=directory_listing_mm {$filter}");

/fr/annuaire-des-books/mannequins-modeles/femmes

/fr/annuaire-des-books/mannequins-modeles/hommes

the red part  will be $input->urlSegment1, so if $input->urlSegment1 is femmes you change the selector to search for pages where your civilite is femmes.

You have quite a few filters so this might not be the best solution.

I say you change the civilite to page fields the the code becomes:

$filter = "";
if($input->urlSegment1)
{
	$filter = ", civilite={$input->urlSegment1}";
}
$results = $pages->find("template=directory_listing_mm {$filter}");

If changing fields to page field is an option i can explain further.

  • Like 2
Link to comment
Share on other sites

@fbg13,

I'm not sure how to apply all this. I'm not experienced enough.

civilite with the following radio buttons is a page field: Mademoiselle, Madame, Monsieur(Title)/monsieur(name).
One difficulty being that "Femmes" (Mademoiselle + Madame) and "Hommes" (Monsieur) don't really exist.
I'm not sure that this is correct (perhaps it needs to be different, I'm not sure using & is correct or | instead...):

echo "<ul><li><a href='$search->url?civilite=mademoiselle&amp;civilite=madame'>" . __("Femmes") . "</a></li>";

qui_2 with the 15 (skill) checkboxes is also a page field.

Perhaps I can use URL segments only for Mannequins-Modèles. If I find how to make it work.

(Later I'll have to adapt some things as the website will certainly have another language activated.)

I'm starting to think it's too big for me in so little time. It's the first time I'm stuck like this.

I'm starting to think that I'll pay someone to resolve all this even if I "loose" money. Or I'll ask more to the client.

NB: I guess (I don't know why I didn't use it...) ! a mister/sir could be used somewhere... (?), at least here, if the rest of the line is correct/useful:

echo "<ul><li><a href='$search->url?civilite!=monsieur'>" . __("Femmes") . "</a></li>";

Edit: I don't know what I"m thinking... I don't need this if I use URL segments. But I'm not sure how to modify my code in directory_listing_mm to make it work, how/if I need to change:

<?php		
			  $children = $page->children("limit=12");
			  $pagination = $children->renderPager();								
			  foreach($children as $child) {				  
                $thumb = $child->joindre_au_maximum_4_photos->first()->size(200,200);				
                echo "<div><a href='$child->url'><img src='$thumb->url' width='$thumb->width' height='$thumb->height' /></a><p><strong><em>$child->votre_pseudo</em></strong><br />$child->pays</p></div>";	
			  }
			  echo $pagination;					
			  ?>	

I'm not thinking in good conditions, I'm putting pressure on myself...

Edited by Christophe
Link to comment
Share on other sites

On the template responsible for this page /fr/annuaire-des-books/mannequins-modeles/ enable url segments

then change

echo "<ul><li><a href='$search->url?civilite=mademoiselle&amp;civilite=madame'>" . __("Femmes") . "</a></li>";

to 

echo "<ul><li><a href='/fr/annuaire-des-books/mannequins-modeles/femmes'>" . __("Femmes") . "</a></li>";

and add this

$filter = "";
if($input->urlSegment1)
{
	$filter = "civilite={$input->urlSegment1}";
}
$results = $pages->find("{$filter}");

at top of the template file responsible for this page /fr/annuaire-des-books/mannequins-modeles/

Now when you go to /fr/annuaire-des-books/mannequins-modeles/femmes it should get all pages with field civilite=femmes

Link to comment
Share on other sites

@fbg13,

Sorry, perhaps it's because it's late and I have forgotten to eat (It's not serious I know), but the page femmes (name) doesn't exist, only the pages with the names mademoiselle, madame, and monsieur.
And the page hommes (name) either. 
(If it was the case, it would be femme and homme for them to be "similar".)
We perhaps have to use variables, but how...

Their parent page being available at /fr/outils/choix-civilite/ or with the id 1085 (perhaps better for a multilingual website).

So I'm a bit lost. 

NB: I'm going to eat a little...

Link to comment
Share on other sites

@fbg13,

But if I need the results to be the results of mademoiselle + the results of madame?

And if I want femmes and hommes (instead of monsieur) to appear in the url?

I'm sorry... I can't think properly.
I think I'm going to take a break.

Edit: and where do I echo/how do I integrate $results as there is already some code to output all the Mannequins-Modèles?

NB: I think I'll try to give the project to somebody else when the client later wants to use an advanced search form...

Link to comment
Share on other sites

Then you need to add extra checks

if($input->urlSegment1 == "femmes")
{
	$filter = "civilite=mademoiselle|madame";
}
if($input->urlSegment1 == "hommes")
{
	$filter = "civilite=monsieur";
}

// or
if($input->urlSegment1 == "mademoiselle" || $input->urlSegment1 == "madame")
{
	$filter = "civilite=mademoiselle|madame";
}
if($input->urlSegment1 == "monsieur")
{
	$filter = "civilite=monsieur";
}

 

  • Like 1
Link to comment
Share on other sites

@fbg13

I guess I have to rest. 

I suppose that what I do with $results will be echoed intead of the code already in place when there are url segments added in the url(?).
It's what I wasn't sure about.
Edit: I'll see "tomorrow". I'm starting to think what I've just written is wrong.

Have a great evening/night!

Link to comment
Share on other sites

I didn't see you code

$filter = "";
if($input->urlSegment1 == "femmes")
{
	$filter = ", civilite=mademoiselle|madame";
}
if($input->urlSegment1 == "hommes")
{
	$filter = ", civilite=monsieur";
}
// you just add $filter to your selector
// $filter is empty unless you have an url segment
$children = $page->children("limit=12 {$filter}");
$pagination = $children->renderPager();								
foreach($children as $child) {				  
	$thumb = $child->joindre_au_maximum_4_photos->first()->size(200,200);				
	echo "<div><a href='$child->url'>";
	echo "<img src='$thumb->url' width='$thumb->width' height='$thumb->height' /></a>";
	echo "<p><strong><em>$child->votre_pseudo</em></strong><br />$child->pays</p></div>";	
}

I used $results just as an example, in your code you extend your default selector with some extra checks based on the url segment.

If you have multiple fields you need to filter by you could use two url segments like this

$filter = "";
if($input->urlSegment1 && $input->urlSegment2)
{
	// first segment is the field name
	// second segment is the value
	// so the url might be like /fr/annuaire-des-books/mannequins-modeles/civilite/madame
	// or like /fr/annuaire-des-books/mannequins-modeles/other_field/some_value
	$filter = ", $input->urlSegment1=$input->urlSegment2";
}
// you just add $filter to your selector
// $filter is empty unless you have an url segment
$children = $page->children("limit=12 {$filter}");
$pagination = $children->renderPager();								
foreach($children as $child) {				  
	$thumb = $child->joindre_au_maximum_4_photos->first()->size(200,200);				
	echo "<div><a href='$child->url'>";
	echo "<img src='$thumb->url' width='$thumb->width' height='$thumb->height' /></a>";
	echo "<p><strong><em>$child->votre_pseudo</em></strong><br />$child->pays</p></div>";	
}

Of course you can check for specific values of the segments and build the selector accordingly.

  • Like 1
Link to comment
Share on other sites

@fbg13,

I've woke up late. I went to bed too late/"early".

I was just going to post this:

   <?php
        $filter = ""; 
        if($input->urlSegment1 == "femmes") {
          $filter = ", civilite=mademoiselle|madame";
        }
        if($input->urlSegment1 == "hommes") {
	        $filter = ", civilite=monsieur";
        }
        $results = $pages->find("template=directory_listing_mm{$filter}, limit=12");
        $pagination = $results->renderPager();	
        foreach($results as $child) {			
          if($child->joindre_au_maximum_4_photos->count) {	  
					  $thumb = $child->joindre_au_maximum_4_photos->first()->size(200,200);				
					  echo "<div><a href='$child->url'><img src='$thumb->url' width='$thumb->width' height='$thumb->height' /></a><p><strong><em>$child->votre_pseudo</em></strong><br />$child->pays</p></div>";
          }
			  }
        echo $pagination;	
			  ?>

I'm having an empty page (nothing output) in Mannequins-Modèles, Femmes, or Hommes.
And (in Mannequins-Modèles) if I change some things in order to resolve this issue I have error messages like:
Notice: Trying to get property of non-object in if removing or changing something to if($child->joindre_au_maximum_4_photos->count).
If I remove ->count I have an empty results/content area (no error message)
or
Fatal error: Call to a member function first() on null if I add ->first() (with or without ->count()).

I'm going to take a close look at what you've just posted.

Link to comment
Share on other sites

@fbg13,

Thank you again for your help.

I've put your code.

There are no error messages and something is output but Femmes doesn't seem to filter anything, it outputs the same thing as its "parent" Mannequins-Modèles.
It keeps the two images with mustaches (corresponding to the 2 only pages where Monsieur is chosen for Civilité).

And Hommes outputs the 2 men but also 5 mademoiselles (I've checked and saved again these pages).
(There are at least 15 mademoiselles in Mannequins-Modèles.)

Edit: I hadn't noticed the post above...

Edited by Christophe
Link to comment
Share on other sites

Check if the if statements are working

if($input->urlSegment1 == "femmes")
{
	$filter = ", civilite=mademoiselle|madame";
}

echo $filter;

go to /fr/annuaire-des-books/mannequins-modeles/femmes and you should see ", civilite=mademoiselle|madame" somewhere.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...