The only way I knew of filtering MODx ressources, depending on multiple filters set by users, was the tvExplorer Snippet. However, recently I stumbled upon a russian MODx blog which showed another approach ( parts of it from the comments section of that blog post ) which will work for basic filtering with Ditto - see screenshot below:

tvExplorer still is the way to go for more extended filter options btw.
In order to setup a search mask as shown above, we'll create a ressource folder "Apartments" which will hold all our apartments ( and one ressource for each apartment ).

1. create TVs for different filter options:
Template Variable Name: tvcity
Input Type: DropDown List Menu
Input Option Values: Berlin==Berlin||Frankfurt==Frankfurt||Hamburg==Hamburg||Kiel==Kiel etc.
Template Variable Name: tvprice
Input Type: DropDown List Menu
Input Option Values: 100==100||200==200||400==400||600==600 etc.
Template Variable Name: tvroom
Input Type: DropDown List Menu
Input Option Values: one==one||two==two||three==three||four==four etc.
2. place the following code in your "Apartments" folder ( change "id=11" to the id of your folder ):
<form action="index.php?id=11" method="post"> City: <select name="city"> <option>all</option> <option value="Berlin">Berlin</option> <option value="Frankfurt">Frankfurt</option> <option value="Hamburg">Hamburg</option> <option value="Kiel">Kiel</option> </select> Price: <select name="price"> <option>all</option> <option value="100">100</option> <option value="200">200</option> <option value="400">400</option> <option value="600">600</option> </select> Rooms: <select name="room"> <option>all</option> <option value="one">one</option> <option value="two">two</option> <option value="three">three</option> <option value="four">four</option> </select> <input name="Submit" type="submit" value="Search" /> </form> [!dittofilter!]
3. create a new Snippet "dittofilter":
<?php
global $modx;
$filter = "";
if (!empty($_POST['city'])) $filter .= (empty($filter)?"":"|")."tvcity,".mysql_escape_string($_POST['city']).",1";
if (!empty($_POST['price'])) $filter .= (empty($filter)?"":"|")."tvprice,".mysql_escape_string($_POST['price']) .",1";
if (!empty($_POST['room'])) $filter .= (empty($filter)?"":"|")."tvroom,".mysql_escape_string($_POST['room']) .",1";
return $modx->runSnippet('Ditto', array('parents'=>'11', 'tpl'=>'apartments', 'display'=>'10', 'sortBy'=>'pub_date', 'dateSource'=>'pub_date', 'dateFormat'=>'%d.%m.%Y', 'paginate'=>'1', 'filter'=>$filter, 'noResults'=>'no results'));
?>
this example uses the Ditto parameter 'tpl'=>'apartments', so either create a Ditto template Chunk "apartments" or change the name in the array to your template Chunk. All Ditto parameters are set in that array.
/////// *important*
If you use other TV names and select names as in my example, change them accordingly in the Snippet code.
Now you should be ready to go :) set the different TV options for your apartment ressources and you'll be able to search them according to the form input. e.g. "Berlin" "200" "two" will schow all apartments in your folder with the TVs set to Berlin, 200 & two. The initial Ditto call will list all apartments.

/////// *tip*
if you don't want to loose the selected filter options after submitting the form, you could use a Snippet in order to return the option list. e.g. the Snippet for citys could look like this - Snippet "selectedcity":
<?php
$output="";
$values = array('Berlin','Frankfurt','Hamburg','Kiel');
$output='<select name="city">';
$output.='<option value="">all</option>';
for($x = 0; $x < count($values); $x++)
{
if($values[$x] == $_POST['city'])
{
$selected = 'selected';
}else{
$selected = '';
}
$output.='<option value="'.$values[$x].'"'.$selected.'>'.$values[$x].'</option>';
}
$output.='</select>';
return $output;
?>
/////// *important* please make sure that the POST variable is made secure / i'll update the snippet
...now place the form on your folder ressource as follows:
<form action="index.php?id=11" method="post"> City: [!selectedcity!] Price: [!selectedprice!] Rooms: [!selectedroom!] <input name="Submit" type="submit" value="Search" /> </form> [!dittofilter!]
If you got any suggestions, improvements etc. leave a comment, pm me on the forum (sharkbait).
/////// *added*
in order to keep pagination, the search parameters need to be passed via GET. Search form:
<form action="[~[*id*]~]" method="get"> City: [!selectedcity!] Price: [!selectedprice!] Rooms: [!selectedroom!] <input name="Submit" type="submit" value="Search" /> </form> [!dittofilter!]
and change all occurances of POST ( Snippet "dittofilter", "selectedcity" etc. ) to GET.
this will work, and i hope it's legit ... maybe you could reassure with a forum post :)
- Required fields are marked with *.