Embassy, Exceeding Expectations

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

30
Years
Legacy
21 MSF
Completed
Portfolio
30+
Completed and
Delivered Projects
49+ 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);
        }
    })();

Bespoke Services & Exclusive Engagement Programmes

True value lies in adding more than expected.

World at your service

We handle everything from home maintenance to personal assistance, making your everyday life easier.

Embassy priority

Exclusive crafted privileges to make your association with Embassy more rewarding. 

Get to know
us better

Here

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 promoters infuse ₹1,160 crore to strengthen balance sheet and fuel expansion

View Details

Blackstone backed Embassy Developments Taps Another Alt Investor For Fresh Capital

View Details

Embassy developments delivers six long-stalled projects, hands over homes to 3,000 families

View Details
View all news

Learn more about
Embassy Group

Visit now