Forum

Thread tagged as: Question, Problem

User-filterable form with multi-region array

I'm creating a user-filterable form with a multi-region array. The form is on a separate page to where the content regions are, but I've specified a page path to cover this. The regions are 'Development' and 'Properties' (Properties being a multi-item region), but only one of the filters in the form works so far (Property Type) and the results themselves are only outputting content from the 'Properties' region and not the 'Development' region as well.

This is my form code:

            <perch:form id="property_filter" method="get" class="form-horizontal">
              <div class="form-group">
                <perch:label for="min_price" class="col-sm-3 col-md-2 control-label">Min Price</perch:label>
                <div class="col-sm-3 col-md-4">
                  <perch:input type="select" id="min_price" class="form-control input-sm" options="No min|0,£100,000|100000,£125,000|125000,£150,000|150000,£200,000|200000,£250,000|250000,£300,000|300000,£350,000|350000,£400,000|400000,£450,000|450000,£500,000|500000" />
                </div>
                <perch:label for="max_price" class="col-sm-3 col-md-2 control-label">Max Price</perch:label>
                <div class="col-sm-3 col-md-4">
                  <perch:input type="select" id="max_price" class="form-control input-sm" options="No max|999999,£500,000|500000,£450,000|450000,£400,000|400000,£350,000|350000,£300,000|300000,£250,000|250000,£200,000|200000,£150,000|150000,£125,000|125000,£100,000|100000" />
                </div>
              </div>
              <div class="form-group">
                <perch:label for="min_beds" class="col-sm-3 col-md-2 control-label">Min Bedrooms</perch:label>
                <div class="col-sm-3 col-md-4">
                  <perch:input type="select" id="min_beds" class="form-control input-sm" options="No min|0,1,2,3,4,5" />
                </div>
                <perch:label for="max_beds" class="col-sm-3 col-md-2 control-label">Max Bedrooms</perch:label>
                <div class="col-sm-3 col-md-4">
                  <perch:input type="select" id="max_beds" class="form-control input-sm" options="No max|99,5,4,3,2,1" />
                </div>
              </div>
              <div class="form-group">
                <perch:label for="property_type" class="col-sm-3 col-md-2 control-label">Property Type</perch:label>
                <div class="col-sm-3 col-md-4">
                  <perch:input type="select" id="property_type" class="form-control input-sm" options="All|0,Apartment,Detached,Semi-detached,Mid Terrace,End Terrace,Town House,Bungalow" />
                </div>
                <perch:label for="property_location" class="col-sm-3 col-md-2 control-label">Location</perch:label>
                <div class="col-sm-3 col-md-4">
                  <perch:input type="select" id="property_location" class="form-control input-sm" options="All|0,Sunderland" />
                </div>
              </div>
              <div class="form-group">
                <div class="col-sm-offset-3 col-md-offset-2 col-sm-10">
                  <perch:input type="submit" value="Search" class="btn btn-primary" />
                </div>
              </div>
            </perch:form>

And this is the code used in the filter page:

            <?php
                perch_form('_property_filter.html');
            ?>

        <?php
        // Create an empty array ready to add our filters to
        $filters = array();

        if (perch_get('min_price')) {
            // if 'min_price' is on the URL, add a filter for min price
            $filters[] = array(
                'filter' => 'property_details_price',
                'match'  => 'gte',
                'value'  => perch_get('min_price'),
            );
        }

        if (perch_get('max_price')) {
            // if 'max_price' is on the URL, add a filter for max price
            $filters[] = array(
                'filter' => 'property_details_price',
                'match'  => 'lte',
                'value'  => perch_get('max_price'),
            );
        }

        if (perch_get('min_beds')) {
            // if 'min_beds' is on the URL, add a filter for min bedrooms
            $filters[] = array(
                'filter' => 'property_details_bedrooms',
                'match'  => 'gte',
                'value'  => perch_get('min_beds'),
            );
        }

        if (perch_get('max_beds')) {
            // if 'max_beds' is on the URL, add a filter for max bedrooms
            $filters[] = array(
                'filter' => 'property_details_bedrooms',
                'match'  => 'lte',
                'value'  => perch_get('max_beds'),
            );
        }

        if (perch_get('property_type')) {
            // if 'property_type' is on the URL, add a filter for property type
            $filters[] = array(
                'filter' => 'property_details_type',
                'match'  => 'eq',
                'value'  => perch_get('property_type'),
            );
        }

        if (perch_get('property_location')) {
            // if 'location' is on the URL, add a filter for location
            $filters[] = array(
                'filter' => 'development_details_address_city',
                'match'  => 'eq',
                'value'  => perch_get('property_location'),
            );
        }

        // Add property status to filters
        $filters[] = array(
            'filter' => 'property_status',
            'match'  => 'neq',
            'value'  => 'sold',
        );

        // If no filters are set, return this
        if (!count($filters)) {

        perch_content_custom(array('Properties','Development'), array(
            'page'=>'/developments/*',
            'template'=>'search/_properties.html',
            'filter'=>'property_status',
            'match'=>'neq',
            'value'=>'sold',
            'sort'=>'property_details_price',
            'sort-order'=>'DESC',
            'paginate'=>'true',
            'count'=>'15',
        ));

        }

        else {

        // If filters are set, return this
        perch_content_custom(array('Properties','Development'), array(
            'page'       => '/developments/*',
            'template'   => 'search/_properties.html',
            'sort'       => 'property_details_price', 
            'sort-order' => 'DESC',
            'paginate'   => 'true',
            'count'      => '15',
            'filter'     => $filters,
        ));

        }

        ?>

So my questions are:

  1. How can I filter by both regions?
  2. How can I filter between values with perch_get if it's part of a filter array? e.g.:
        if (perch_get(array('min_price','max_price'))) {
            $filters[] = array(
                'filter' => 'property_details_price',
                'match'  => 'eqbetween',
                'value'  => perch_get('min_price'),perch_get('max_price')
            );
        }
Philip Gwynne

Philip Gwynne 1 points

  • 7 years ago
Drew McLellan

Drew McLellan 2638 points
Perch Support

Are the fields the same in both regions?

No, they are different fields - do they need to be the same?

Drew McLellan

Drew McLellan 2638 points
Perch Support

If you're asking for items where property_status is sold it won't return any items that don't have property_status set, because it won't be equal to sold.

Gotcha! I've now set up property_status on the Development region exactly the same as I have on the Properties region, but the content from the Development region still isn't displaying on the items, so I then tried removing all filters for property_status for the filter page and its template, but any content item that is called from Development is still not showing up.

Is there anything else you can think of that may be causing this?

Drew McLellan

Drew McLellan 2638 points
Perch Support

How about the field you're sorting on?

Removing the sort parameter displays an extra result on the page with the Development region details called in the template by themselves. Is there a way to share data from the Development region to the Properties multi-item region? Or is this something Perch Runway will be better equipped to handle?

Basically, I want to have it so the client only needs to set up the Development details once (address, local area info, site plan, etc), so they don't have to enter any of those details again for each of the Properties multi-item regions, since the properties will belong to that development anyway.

Currently, it's working fine as it is for the list and detail views on the content page(s) that feature these regions, as I'm displaying them separately using multiple content templates and different layouts for each view. But I'm having problems when it comes to this search/filter page, as I need to display the development title and location for the properties within the results to differentiate them from other developments and locations, and allow me to also filter properties by location.

Although a bit more long-winded for the client to set up each time, I wonder if Categories would've been better to create sets for location and development title and assign those in the regions using a dataselect?

Drew McLellan

Drew McLellan 2638 points
Perch Support

I think the issue is just that you're trying to pull two differently shaped datasets into one.

What end goal are you trying to reach?

The end goal is to allow the client, who is a residential builder, to add development sites, and then add properties (plots) to these developments. (I have this part working using a normal region for the development site, and a multi-region for the properties to be added to it - combined with a different layout for both the list and the detail view)

All the properties no matter which development they belong to, then need to be listed on a separate search page, which can be filtered by min/max price, min/max bedrooms, property type and development location. (The issue on this page is that since it's not showing the properties within a specific development page, I need to display extra information on each property in the list showing the title of the development that property is from, and the development's location)

I hope that makes sense?

Drew McLellan

Drew McLellan 2638 points
Perch Support

How about loading the Development detail in to each Property as you display it using an each callback function?

That sounds like just the job, though I'm a novice when it comes to PHP - is there a similar example of this that I can learn from or experiment with?

Drew McLellan

Drew McLellan 2638 points
Perch Support

Have a look at the "Specifying an item callback function" section https://docs.grabaperch.com/docs/content/perch-content-custom/

Thanks for that Drew. I've added the following each callback to my page:

        perch_content_custom(array('Properties','Development'), array(
            'page'       => '/developments/*',
            'template'   => 'search/_properties.html',
            'each' => function($item) {
                $item['development_title'] = perch_content_custom($item['development_details_title'], array(
                  'template'=>'search/_development_title.html'
                ), true);
                $item['development_location'] = perch_content_custom($item['development_details_address_city'], array(
                  'template'=>'search/_development_location.html'
                ), true);
                return $item;
                },
            'sort'       => 'property_details_price', 
            'sort-order' => 'DESC',
            'paginate'   => 'true',
            'count'      => '15',
            'filter'     => $filters,
        ));

In the listing template search/_properties.html, I have this:

<perch:if id="property_status" match="neq" value="sold">
              <div class="col-sm-6 col-md-4">
                <div class="property-listing">
                  <div class="photo">
                    <a href="<perch:content id="_page" />?s=<perch:content id="slug" type="slug" />-<perch:content id="_id" type="hidden" />"><img src="<perch:content id="header_image" type="image" label="Main Image" width="355" height="236" crop="true" output="path" />" class="img-responsive" alt="Property image"></a>
                  </div>
                  <div class="details">
                    <h4><perch:content id="property_details_title" /></h4>
                    <p class="plot">Plot <perch:content id="property_details_plot_number" /></p>
                    <perch:content id="development_title" /><perch:content id="development_location" />
                    <span class="price">
                      <h4>£<perch:content id="property_details_price" format="#:0|," /></h4>
                      <p><perch:content id="property_details_bedrooms" /> bedroom</p>
                    </span>
                    <p><perch:content id="property_details_summary" /></p>
                    <a href="<perch:content id="_page" />?s=<perch:content id="slug" type="slug" />-<perch:content id="_id" type="hidden" />" class="btn btn-primary">View home <i class="fa fa-angle-right"></i></a>
                  </div>
                </div>
              </div>
</perch:if>

In _development_title.html I have this in the template:

<perch:if exists="development_details_title"><p><perch:content id="development_details_title" /><perch:else /><p></perch:if>

And in _development_location.html I have this in the template:

<perch:if exists="development_details_address_city"><perch:content id="development_details_address_city" /></p><perch:else /></p></perch:if>

However, it's not outputting any content from the Development region for development_title and development_location, is there a parameter I'm missing?