Exceeding Expectations

We go the extra mile in everything we do because our true passion is to deliver something real, meaningful and truly exceptional.

0+
Years
Legacy
0+ MSF
Completed
Portfolio
0+
Completed and
Delivered Projects
0+ MSF
of Ongoing and
Future Development

Let's find your project

Show all projects
<?php

// 1. DATA COLLECTION
// Fetch filter options (Taxonomies)
$types = get_terms(['taxonomy' => 'property-type', 'hide_empty' => false]);
$type_options = '';
if ( ! empty( $types ) && ! is_wp_error( $types ) ) {
    foreach ( $types as $typ ) {
        $type_options .= '<option value="' . esc_attr( $typ->slug ) . '">' . esc_html( $typ->name ) . '</option>';
    }
}

$locations = get_terms(['taxonomy' => 'project-location', 'hide_empty' => false]);
$location_options = '';
if ( ! empty( $locations ) && ! is_wp_error( $locations ) ) {
    foreach ( $locations as $loc ) {
        $location_options .= '<option value="' . esc_attr( $loc->slug ) . '">' . esc_html( $loc->name ) . '</option>';
    }
}

$availabilities = get_terms(['taxonomy' => 'project-status', 'hide_empty' => false]);
$availability_options = '';
if ( ! empty( $availabilities ) && ! is_wp_error( $availabilities ) ) {
    foreach ( $availabilities as $avail ) {
        $availability_options .= '<option value="' . esc_attr( $avail->slug ) . '">' . esc_html( $avail->name ) . '</option>';
    }
}

// Build Valid Combinations Map
// We cache this to avoid heavy database queries on every page load
$combinations = get_transient('dev_property_search_combinations_v3');

if (false === $combinations) {
    $combinations = [];
    
    // precise query only for IDs to be lightweight
    $posts = get_posts([
        'post_type' => 'any',
        'posts_per_page' => -1,
        'fields' => 'ids',
        'tax_query' => [
            'relation' => 'OR',
            ['taxonomy' => 'project-location', 'operator' => 'EXISTS'],
            ['taxonomy' => 'project-status', 'operator' => 'EXISTS'],
            ['taxonomy' => 'property-type', 'operator' => 'EXISTS'],
        ]
    ]);
    
    if ($posts) {
        $terms = wp_get_object_terms($posts, ['property-type', 'project-location', 'project-status']);
        $obj_map = [];
        
        if (!is_wp_error($terms)) {
            foreach ($terms as $term) {
                $obj_map[$term->object_id][$term->taxonomy][] = $term->slug;
            }
        }
        
        foreach ($obj_map as $pid => $data) {
            $p_types = isset($data['property-type']) ? $data['property-type'] : [];
            $p_locs = isset($data['project-location']) ? $data['project-location'] : [];
            $p_stats = isset($data['project-status']) ? $data['project-status'] : [];
            
            // Only combinations that form a complete set can be filtered strictly
            if (empty($p_types) || empty($p_locs) || empty($p_stats)) continue;

            foreach ($p_types as $t) {
                foreach ($p_locs as $l) {
                    foreach ($p_stats as $s) {
                        $combinations[] = ['type' => $t, 'location' => $l, 'status' => $s];
                    }
                }
            }
        }
        // Dedup
        $combinations = array_map("unserialize", array_unique(array_map("serialize", $combinations)));
        // Reset keys
        $combinations = array_values($combinations);
    }
    set_transient('dev_property_search_combinations_v3', $combinations, 12 * HOUR_IN_SECONDS);
}

// Prepare data for JS
$json_combinations = json_encode($combinations);
$unique_id = uniqid('dev_search_');

// Output Data for JS global usage
echo "<script>window.devSearchData = " . $json_combinations . "; window.devSearchId = '" . $unique_id . "';</script>";
?>

<!-- HTML Form -->
<form id="<?php echo $unique_id; ?>" class="dev-property-search" action="/projects" method="GET">
    <div class="dev-property-search__field">
        <div class="desc-big">Property type</div>
        <div class="dev-select-wrapper">
            <select name="property-type">
                <option class="p2-regular" value="">Select type</option>
                <?php echo $type_options; ?>
            </select>
            <svg class="dev-select-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
        </div>
    </div>

    <div class="dev-separator"></div>

    <div class="dev-property-search__field">
        <div class="desc-big">Location</div>
        <div class="dev-select-wrapper">
            <select name="project-location">
                <option class="p2-regular" value="">Select location</option>
                <?php echo $location_options; ?>
            </select>
            <svg class="dev-select-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
        </div>
    </div>

    <div class="dev-separator"></div>

    <div class="dev-property-search__field">
        <div class="desc-big">Status</div>
        <div class="dev-select-wrapper">
            <select name="project-status">
                <option class="p2-regular" value="">Choose status</option>
                <?php echo $availability_options; ?>
            </select>
            <svg class="dev-select-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
        </div>
    </div>

    <button type="submit" class="dev-property-search__submit">
        Search
        <svg class="dev-search-icon" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
    </button>
</form>
        .dev-property-search, .dev-property-search * {
            box-sizing: border-box;
        }
        .dev-property-search {
            display: flex;
            align-items: center;
            background: transparent;
            padding: 20px;
            width: 100%;
            max-width: 100%;
        }
        .dev-property-search__field {
            display: flex;
            flex-direction: column;
            flex: 1;
            position: relative;
            min-width: 150px;
        }
        .dev-select-wrapper {
            position: relative;
            display: flex;
            align-items: center;
        }
        /* Visual feedback for disabled options */
        .dev-property-search__field select option:disabled {
            color: #ccc;
            background-color: #f9f9f9;
        }
        .dev-property-search__field select {
            appearance: none;
            -webkit-appearance: none;
            -moz-appearance: none;
            border: none;
            background: transparent;
            color: #000;
            width: 100%;
            cursor: pointer;
            padding-right: 30px;
            outline: none;
        }
        .dev-select-arrow {
            position: absolute;
            right: 0;
            pointer-events: none;
            width: 20px;
            height: 20px;
        }
        .dev-separator {
            width: 2px;
            height: 40px;
            background-color: #e0e0e0;
            margin: 0 25px;
        }
        .dev-property-search__submit {
            background-color: #000;
            color: #fff;
            border: none;
            padding: 15px 40px;
            font-size: 18px;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 10px;
            margin-left: 20px;
        }
        .dev-search-icon {
            width: 20px;
            height: 20px;
            stroke: #fff;
            stroke-width: 2;
            fill: none;
        }
        
        @media (max-width: 844px) {
            .dev-property-search {
                flex-direction: column;
                align-items: stretch;
                gap: 15px;
                padding: 15px;
            }
            .dev-property-search__field {
                width: 100%;
                min-width: 0;
            }
            .dev-separator {
                display: none;
            }
            .dev-property-search__submit {
                margin-left: 0;
                justify-content: center;
                width: 100%;
            }
        }
(function() {
        var formId = '{$unique_id}';
        var combinations = {$json_combinations};

        // Safety check
        if (!combinations || !Array.isArray(combinations)) {
            console.warn('DevSearch: No combinations loaded.');
            combinations = [];
        }

        function initDevSearch() {
            var form = document.getElementById(formId);
            if (!form) return;
            
            // If already initialized, stop
            if (form.dataset.initialized === 'true') return;
            form.dataset.initialized = 'true';
            
            var typeSelect = form.querySelector('select[name=\"property-type\"]');
            var locSelect = form.querySelector('select[name=\"project-location\"]');
            var statSelect = form.querySelector('select[name=\"project-status\"]');
            
            function getAvailable(targetColumn, constraints) {
                var validValues = new Set();
                
                for (var i = 0; i < combinations.length; i++) {
                    var combo = combinations[i];
                    var isMatch = true;
                    
                    // Check all constraints
                    for (var key in constraints) {
                        var requiredVal = constraints[key];
                        // If constraint is empty string, we ignore it (match all)
                        if (requiredVal && combo[key] !== requiredVal) {
                            isMatch = false;
                            break;
                        }
                    }
                    
                    if (isMatch) {
                        validValues.add(combo[targetColumn]);
                    }
                }
                return validValues;
            }

            function updateSelect(selectInfo) {
                var el = selectInfo.el;
                if (!el) return;
                
                var validSet = selectInfo.validSet;
                var options = el.querySelectorAll('option');
                
                options.forEach(function(opt) {
                    // Always allow placeholder (empty value)
                    if (!opt.value) return; 
                    
                    if (validSet.has(opt.value)) {
                        opt.disabled = false;
                        opt.style.color = ''; 
                    } else {
                        opt.disabled = true;
                        opt.style.color = '#ccc'; 
                        // Optional: if currently selected is disabled, reset to empty?
                        // if (el.value === opt.value) el.value = '';
                    }
                });
            }

            function updateAll() {
                var curType = typeSelect ? typeSelect.value : '';
                var curLoc = locSelect ? locSelect.value : '';
                var curStat = statSelect ? statSelect.value : '';

                // 1. Available Types, given Loc + Stat
                var types = getAvailable('type', { location: curLoc, status: curStat });
                updateSelect({ el: typeSelect, validSet: types });
                
                // 2. Available Locations, given Type + Stat
                var locs = getAvailable('location', { type: curType, status: curStat });
                updateSelect({ el: locSelect, validSet: locs });
                
                // 3. Available Status, given Type + Loc
                var stats = getAvailable('status', { type: curType, location: curLoc });
                updateSelect({ el: statSelect, validSet: stats });
            }

            // Listeners
            if (typeSelect) typeSelect.addEventListener('change', updateAll);
            if (locSelect) locSelect.addEventListener('change', updateAll);
            if (statSelect) statSelect.addEventListener('change', updateAll);
            
            // Initial run
            updateAll();
        }

        // Try to init immediately
        initDevSearch();
        
        // Also wait for DOM if not ready
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', initDevSearch);
        }
    })();

Embassy Lake Terraces

YOUR SIGNATURE
LUXURY

Signature Residences are thoughtfully crafted to offer a refined, effortless lifestyle, from wrap-around terraces to private pools and personalized services, redefining luxury living.

Explore more

News & Announcements

Embassy Developments’ pre-sales set to hit Rs 5,000 cr in FY26, top official says

View Details

Embassy Developments pre-sales to jump 2.5-fold to ₹5,000 crore

View Details

Embassy Developments Pre-Sales To Jump 2.5-Fold To Rs 5,000 Crore On Strong Housing Demand

View Details
View all news

Learn more about
Embassy Group

Visit now