Combining Url variables

For a real estate website I’m working on the owners would like to combine certain property types (5) into one group for a quick search menu. But these property types need to be used separately in the site elsewhere as well. To indicate what I mean I made an example which you can find Here.

The left drop down indicates all property types. In the right drop down Apartments, Detached Houses, Luxury Homes, Maisonettes and Villas are combined into the tab houses.

Where I’m struggling with is how to declare the Url variable in such a way that on the result page it is clear that those 5 property types should be displayed. In other words is it possible to combine these 5 variable (property_type_id) for the sake of the link and on the result page separate them again

Any suggestions?

sure, just pick a url variable value that doesn’t exist as a property type, like “h5”

in the template which receives the url variable, interpret the value and create the query like


<CFQUERY ...
SELECT ...
<CFIF url.proptype EQ "h5">
WHERE properties.type IN ( 4, 6, 8, 9, 37 ) -- Apartments, Detached Houses, etc.
<CFELSE>
WHERE properties.type = #url.proptype#
</CFIF>
</CFQUERY>

Brilliant suggestion Rudy. thank you for that.

I love IIF’s

<cfquery ...>
SELECT...
WHERE properties.type #iif( url.proptype eq "h5", de( "IN (4, 6, 8, 9, 37 )" ), de( "= " & url.proptype ) )#
</cfquery>

Also, you’ll want to ensure to put all variables in the query into a cfqueryparam, ie:

<cfqueryparam cfsqltype="cf_sql_varchar" value="#url.proptype#" />

That is a nice one as well aaron. One last question about his subject. A visitor can also come to the result page using the search form. When they don’t choose a property type the value would be 0. How would I include the 0 value in this statement as well or is that not needed. Right now I start my WHERE/AND clauses with WHERE 0 = 0 and use <cfif … GT 0 in combination with the above where statements?

Setup CFPARAMS. These ensure that if a value is not explicitly set, then there will be a default value.

<cfparam name="url.number" value="0" />

Goto page.cfm => url.number = 0
Gogo page.cfm?number=10 => url.number = 10

This way you don’t have to worry about doing isDefined() checks or checking for NULL.

I usually use <cfparam> indeed but I can’t see to get it to work without the <cfif>


  WHERE 0 = 0
 	<cfif structKeyExists( Url, "proptype" ) And Url.proptype EQ "t5" >
  AND
			P.property_type_id IN ( <cfqueryparam cfsqltype="cf_sql_integer" value="1,2,6,7" list="true" /> )
  <cfelseif structKeyExists( Url, "proptype" ) And Url.proptype GT 0 >
  AND
			P.property_type_id IN ( <cfqueryparam cfsqltype="cf_sql_integer" value="#Trim( Url.proptype )#"  /> )      
	</cfif>

Having it this way give all the results expected:

  1. t5 returns the property types as in the list
  2. A property type provided in the search form returns a listing with the right property type
  3. When no property type is provided in the search form the listin returns all property types

As soon as I tried it without the <cfif> only the first two options where returned as expected.

Okay I ended up using the IIF in combination of <CFIF> like this:


WHERE
    0 = 0
<cfif Url.proptype GT 0>    
AND      
    P.property_type_id IN ( <cfqueryparam cfsqltype="cf_sql_integer" value="#iif( url.proptype eq 't5', de( '1,2,6,7'  ), de( Url.proptype ) )#" list="true" /> )
  </cfif>

This way, every possible option to arrive on this page, returns the right results!

I’m not sure If can continue my question here or that I should start a new post?

Anyway to make if just a little bit more complicated they also would like to have a from/to price range for certain property types (houses and holiday properties) in that same quick search menu, as you can see Here in the adjusted example!

My question here has to do, just like the former, with the Url.variable. On the search form I have two fields (price_from and price_to) so I need just two statements handling those two.

But what would be the best approach to handle these from/to values. Don’t understand me wrong! I know I can do this with a bunch of <cfif> <cfelse> but I was wondering if someone maybe have a better way of doing this

Ok how about a bit of future proofing for you :slight_smile:

What if I want to search on T10,T11,T12,T13… TXX through url? As much as you’re getting the job done in this instance you’re not future proofing that code for reuse.

Stuff like this is perfect for sitting in CFCs.

Set this up in a function, pass through an argument of the value you want to query against but if they don’t then the default is of value - 4, 6, 8, 9, 37

So the original code of

<CFQUERY ...
SELECT ...
<CFIF url.proptype EQ "h5">
WHERE properties.type IN ( 4, 6, 8, 9, 37 ) -- Apartments, Detached Houses, etc.
<CFELSE>
WHERE properties.type = #url.proptype#
</CFIF>
</CFQUERY>

Can become something like this:-


<cfcomponent>
<cffunction name="getPropertyByType" returnType="query">
<cfargument name="id" required=false type="string" default="4,6,8,9,37" />

<cfset var q = queryNew('propertyQuery') />

<cfquery datasource="#dsn#" name="q">
select ....
WHERE properties.type IN ( <cfqueryparam value="#arguments.id#" cfsqltype="CF_SQL_VARCHAR" list="true" /> )
</cfquery>

<cfreturn q />

</cffunction>

Nice clean code with no if statements, all reusable and self-contained :wink:

Call if would be something like:


<cfparam name="url.propType" default="" />

objProperties = createObject('component','path.to.my.CFC');

if(len(url.propType)){
// Pass in the URL var
qryProperty = objProperties.getPropertyByType(url.proptype);
}else{
// Gets the default query
qryProperty = objProperties.getPropertyByType();
}


Cheers,
James

Make sure you sanitize your URL variables as well. If you’re relying on a URl variable “age” and you’re performing mathematical operations on that value, someone can change the page to something like:

page.cfm?age=Ancient

This is a non-numerical value now and if your app ginks on it (and worse, spits out page code), then you’re going to have security issues.

Thank you both very helpful as usual :tup: