# Filter CMS Form Select Options

**URL:** <https://forum.finsweet.com/t/filter-cms-form-select-options/806>\
**Category:** Attributes\
**Created:** [May 26, 2023, 9:44am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806 "2023-05-26T09:44:07Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Marko](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/marko/32/592_2.png) [@Marko](https://forum.finsweet.com/u/Marko)\
**Post date:** [May 26, 2023, 9:44am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/1 "2023-05-26T09:44:07Z")

</div>

Hi Everyone,

Is there a way to filter the options in a form select, which are populated with CMS items?

For example:

Select 1: Contains a list of countries.  
Select 2: Contains a list of cities.

If ‘New Zealand’ is chosen as a country in the first select field, could we then filter the options in the ‘Cities’ select field to include only cities within New Zealand?

Both of these selections are populated by CMS items.

Thanks,  
Marko

---

<div class="post-metadata">

**Author:** ![josephmukunga](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/josephmukunga/32/522_2.png) [@josephmukunga](https://forum.finsweet.com/u/josephmukunga)\
**Post date:** [May 26, 2023, 2:28pm UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/2 "2023-05-26T14:28:22Z")

</div>

Hello @Marko, this is not possible with the CMS attribute. Anyway, it can be achieved using a custom script.  
Could you define to me how you determine which Cities are under a certain country, are they nested within the CMS item and I’ll see how we can come up with a custom script

---

<div class="post-metadata">

**Author:** ![Marko](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/marko/32/592_2.png) [@Marko](https://forum.finsweet.com/u/Marko)\
**Post date:** [May 26, 2023, 3:11pm UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/3 "2023-05-26T15:11:15Z")

</div>

Thanks @josephmukunga! The cities are catagorised using a reference field in the cms collection. The reference field is linked to the country collection. Let me know if you have any other questions. Thanks so much for taking a look.

---

<div class="post-metadata">

**Author:** ![josephmukunga](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/josephmukunga/32/522_2.png) [@josephmukunga](https://forum.finsweet.com/u/josephmukunga)\
**Post date:** [May 29, 2023, 11:05am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/4 "2023-05-29T11:05:05Z")

</div>

Could you please share the published site and read-only links

---

<div class="post-metadata">

**Author:** ![Marko](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/marko/32/592_2.png) [@Marko](https://forum.finsweet.com/u/Marko)\
**Post date:** [June 25, 2023, 11:25am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/5 "2023-06-25T11:25:48Z")

</div>

@josephmukunga My apologies for the late reply. I became unwell and was away from my computer for quite some time. I’m a lot better now and glad to get back into it. Here are the links:

[https://cms-filter-select.webflow.io/](https://cms-filter-select.webflow.io/)

[https://preview.webflow.com/preview/cms-filter-select?utm\_medium=preview\_link&utm\_source=designer&utm\_content=cms-filter-select&preview=b7c41aee670fe51820ce37c3fcd90193&workflow=preview](https://preview.webflow.com/preview/cms-filter-select?utm_medium=preview_link&utm_source=designer&utm_content=cms-filter-select&preview=b7c41aee670fe51820ce37c3fcd90193&workflow=preview)

Any questions, please let me know.

---

<div class="post-metadata">

**Author:** ![josephmukunga](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/josephmukunga/32/522_2.png) [@josephmukunga](https://forum.finsweet.com/u/josephmukunga)\
**Post date:** [June 26, 2023, 4:53pm UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/6 "2023-06-26T16:53:39Z")

</div>

1st you’ll have to remove all the `CMS Select` implementation.

Have this setup:

1. For the department collection list wrapper, give it the attribute `department="cms"`
2. For the department text that you need to populate the dropdown, give it the attribute `department="text"`
3. For the roles collection list wrapper, give it the attribute `role="cms"`
4. For the roles text that you need to populate the dropdown, give it the attribute `role="text"`
5. For the department that the role exist to give it the attribute `role="department"` and ensure this is within each role cms collection item
6. Give the department select field the attribute `department="select"`
7. Give the role select field the attribute `role="select"`

Then add the scripts below:

```auto
<script>
const departments = document.querySelectorAll('[department="cms"] [department="text"');
const rolesCMSItems = document.querySelectorAll('[role="cms"');
const roles = rolesCMSItems.map(cmsItem => {
  const role = {
    role: document.querySelector('[role="text"'),
    department: document.querySelector('[role="department"')
  }
})

        let departmentDropdown = document.querySelector('[department="select"]');
        for (var i = 0; i < departments.length; i++) {
            let option = document.createElement("option");
            option.value = departments[i];
            option.textContent = departments[i];
            departmentDropdown.appendChild(option);
        }
        
        // Function to filter roles based on department selection
        function filterRoles() {
            let departmentDropdown = document.querySelector('[department="select"]');
            let roleDropdown = document.querySelector('[role="select"]');;
            let selectedDepartment = departmentDropdown.value;
            
            // Clear previous options
            roleDropdown.innerHTML = "";
            
            // Filter roles based on selected department
            let filteredRoles = roles.filter(function(role) {
                return selectedDepartment === "all" || role.department === selectedDepartment;
            });
            
            // Populate role dropdown with filtered roles
            for (var i = 0; i < filteredRoles.length; i++) {
                var option = document.createElement("option");
                option.value = filteredRoles[i].role;
                option.textContent = filteredRoles[i].role;
                roleDropdown.appendChild(option);
            }
        }

      departments.addEventListener('change', () => {
        filterRoles()
     })

       
</script>

```

---

<div class="post-metadata">

**Author:** ![Marko](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/marko/32/592_2.png) [@Marko](https://forum.finsweet.com/u/Marko)\
**Post date:** [June 27, 2023, 6:38am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/7 "2023-06-27T06:38:56Z")

</div>

Thanks @josephmukunga! I really appreciate it! I’ve implemented the changes but have made a mistake somewhere as it’s not quite working. Can you see where I went wrong? Updated links are below:

[https://preview.webflow.com/preview/cms-filter-select?utm\_medium=preview\_link&utm\_source=designer&utm\_content=cms-filter-select&preview=b7c41aee670fe51820ce37c3fcd90193&workflow=preview](https://preview.webflow.com/preview/cms-filter-select?utm_medium=preview_link&utm_source=designer&utm_content=cms-filter-select&preview=b7c41aee670fe51820ce37c3fcd90193&workflow=preview)

[https://cms-filter-select.webflow.io/](https://cms-filter-select.webflow.io/)

---

<div class="post-metadata">

**Author:** ![josephmukunga](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/josephmukunga/32/522_2.png) [@josephmukunga](https://forum.finsweet.com/u/josephmukunga)\
**Post date:** [June 27, 2023, 1:02pm UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/8 "2023-06-27T13:02:01Z")

</div>

2 things

1. The roles cms wrapper does not have the attribute ``
2. Replace the previous script with this

```auto
<script>
const departments = document.querySelectorAll(
  '[department="cms"] [department="text"]'
);
const rolesCMSItems = document.querySelectorAll('[role="cms"]');
const roles = rolesCMSItems.map((cmsItem) => {
  const role = {
    role: cmsItem.querySelector('[role="text"]'),
    department: cmsItem.querySelector('[role="department"]')
  };
  return role;
});

let departmentDropdown = document.querySelector('[department="select"]');
for (var i = 0; i < departments.length; i++) {
  let option = document.createElement("option");
  option.value = departments[i];
  option.textContent = departments[i];
  departmentDropdown.appendChild(option);
}

// Function to filter roles based on department selection
function filterRoles() {
  let departmentDropdown = document.querySelector('[department="select"]');
  let roleDropdown = document.querySelector('[role="select"]');
  let selectedDepartment = departmentDropdown.value;

  // Clear previous options
  roleDropdown.innerHTML = "";

  // Filter roles based on selected department
  let filteredRoles = roles.filter(function (role) {
    return (
      selectedDepartment === "all" || role.department === selectedDepartment
    );
  });

  // Populate role dropdown with filtered roles
  for (var i = 0; i < filteredRoles.length; i++) {
    var option = document.createElement("option");
    option.value = filteredRoles[i].role;
    option.textContent = filteredRoles[i].role;
    roleDropdown.appendChild(option);
  }
}

departments.addEventListener("change", () => {
  filterRoles();
});

</script>

```

---

<div class="post-metadata">

**Author:** ![Marko](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/marko/32/592_2.png) [@Marko](https://forum.finsweet.com/u/Marko)\
**Post date:** [July 5, 2023, 1:35am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/9 "2023-07-05T01:35:06Z")

</div>

> [@josephmukunga](#):
>
> `

Thanks, Joseph! I updated the site but I’m still missing something, please see here:

[https://cms-filter-select.webflow.io/](https://cms-filter-select.webflow.io/)

[https://preview.webflow.com/preview/cms-filter-select?utm\_medium=preview\_link&utm\_source=designer&utm\_content=cms-filter-select&preview=b7c41aee670fe51820ce37c3fcd90193&workflow=preview](https://preview.webflow.com/preview/cms-filter-select?utm_medium=preview_link&utm_source=designer&utm_content=cms-filter-select&preview=b7c41aee670fe51820ce37c3fcd90193&workflow=preview)

---

<div class="post-metadata">

**Author:** ![josephmukunga](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/josephmukunga/32/522_2.png) [@josephmukunga](https://forum.finsweet.com/u/josephmukunga)\
**Post date:** [July 5, 2023, 7:02am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/10 "2023-07-05T07:02:24Z")

</div>

```auto
    <script>
      const departments = document.querySelectorAll(
        '[department="cms"] [department="text"]'
      );
      const rolesCMSItems = document.querySelectorAll(
        '[role="cms"] [role="listitem"]'
      );
      const roles = Array.from(rolesCMSItems).map((cmsItem) => {
        const role = {
          role: cmsItem.querySelector('[role="text"]').innerText,
          department: cmsItem.querySelector('[role="department"]').innerText,
        };
        return role;
      });

      let departmentDropdown = document.querySelector('[department="select"]');
      for (var i = 0; i < departments.length; i++) {
        const department = departments[i];
        const departmentText = department.innerText;
        let option = document.createElement("option");
        option.value = departmentText;
        option.textContent = departmentText;
        departmentDropdown.appendChild(option);
      }

      // Function to filter roles based on department selection
      function filterRoles() {
        let roleDropdown = document.querySelector('[role="select"]');
        let selectedDepartment = departmentDropdown.value;
        // Clear previous options
        roleDropdown.innerHTML = "";
        // Filter roles based on selected department
        let filteredRoles = roles.filter((role) => {
          return (
            selectedDepartment === "all" ||
            role.department === selectedDepartment
          );
        });

        // Populate role dropdown with filtered roles
        for (var i = 0; i < filteredRoles.length; i++) {
          var option = document.createElement("option");
          option.value = filteredRoles[i].role;
          option.textContent = filteredRoles[i].role;
          roleDropdown.appendChild(option);
        }
      }

      departmentDropdown.addEventListener("change", () => {
        filterRoles();
      });
    </script>

```

---

<div class="post-metadata">

**Author:** ![josephmukunga](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/josephmukunga/32/522_2.png) [@josephmukunga](https://forum.finsweet.com/u/josephmukunga)\
**Post date:** [July 5, 2023, 7:02am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/11 "2023-07-05T07:02:41Z")

</div>

This should now be ok

---

<div class="post-metadata">

**Author:** ![Marko](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/marko/32/592_2.png) [@Marko](https://forum.finsweet.com/u/Marko)\
**Post date:** [August 28, 2023, 2:02am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/12 "2023-08-28T02:02:05Z")

</div>

@josephmukunga Hi, how are you? I apologise for the delayed response; I was preoccupied with another job. Thank you for sending the updated code! Very appreciated!

It seems to work for some items but not for all. Could you help me identify where I might be going wrong? For instance, it works for ‘Camera’.

[https://cms-filter-select.webflow.io/](https://cms-filter-select.webflow.io/)

EDIT: I’ve noticed that only the first set of pagination roles are loading in the ‘Role’ dropdown menu. How can I modify it to load all the roles? So far, I have added FinSweet’s CMS Load attribute with a render all added.

---

<div class="post-metadata">

**Author:** ![Marko](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/marko/32/592_2.png) [@Marko](https://forum.finsweet.com/u/Marko)\
**Post date:** [September 4, 2023, 3:28am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/13 "2023-09-04T03:28:11Z")

</div>

Hi everyone,

Does anyone have any ideas on how I can implement the above? Any help would be much appreciated!

Cheers!

---

<div class="post-metadata">

**Author:** ![Support-Luis](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/support-luis/32/53_2.png) [@Support-Luis](https://forum.finsweet.com/u/Support-Luis)\
**Post date:** [September 4, 2023, 9:10am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/14 "2023-09-04T09:10:53Z")

</div>

Hey @Marko! I hope you are doing great!

If you have used CMS Load to load your CMS Collection where you are generating the options you can wait until all items have finished loading and execute the script above inside the Attributes callback. The code would look something like this

```auto
<script>
  window.fsAttributes = window.fsAttributes || [];
  window.fsAttributes.push([
    'cmsload',
    (listInstances) => {
      console.log('cmsload has finished laoding!');
      const departments = document.querySelectorAll('[department="cms"] [department="text"]');
      const rolesCMSItems = document.querySelectorAll('[role="cms"] [role="listitem"]');
      const roles = Array.from(rolesCMSItems).map((cmsItem) => {
        const role = {
          role: cmsItem.querySelector('[role="text"]').innerText,
          department: cmsItem.querySelector('[role="department"]').innerText,
        };
        return role;
      });

      let departmentDropdown = document.querySelector('[department="select"]');
      for (var i = 0; i < departments.length; i++) {
        const department = departments[i];
        const departmentText = department.innerText;
        let option = document.createElement('option');
        option.value = departmentText;
        option.textContent = departmentText;
        departmentDropdown.appendChild(option);
      }

      // Function to filter roles based on department selection
      function filterRoles() {
        let roleDropdown = document.querySelector('[role="select"]');
        let selectedDepartment = departmentDropdown.value;
        // Clear previous options
        roleDropdown.innerHTML = '';
        // Filter roles based on selected department
        let filteredRoles = roles.filter((role) => {
          return selectedDepartment === 'all' || role.department === selectedDepartment;
        });

        // Populate role dropdown with filtered roles
        for (var i = 0; i < filteredRoles.length; i++) {
          var option = document.createElement('option');
          option.value = filteredRoles[i].role;
          option.textContent = filteredRoles[i].role;
          roleDropdown.appendChild(option);
        }
      }

      departmentDropdown.addEventListener('change', () => {
        filterRoles();
      });
    },
  ]);
</script>

```

Let me know if this fixes your issues! 🙂

---

<div class="post-metadata">

**Author:** ![Marko](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/marko/32/592_2.png) [@Marko](https://forum.finsweet.com/u/Marko)\
**Post date:** [September 6, 2023, 2:49am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/15 "2023-09-06T02:49:42Z")

</div>

Thanks @Support-Luis, this worked! Thanks a bunch.

---

<div class="post-metadata">

**Author:** ![Support-Luis](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/support-luis/32/53_2.png) [@Support-Luis](https://forum.finsweet.com/u/Support-Luis)\
**Post date:** [September 6, 2023, 7:56am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/16 "2023-09-06T07:56:25Z")

</div>

You are welcome! 💪

---

<div class="post-metadata">

**Author:** ![de.skaaa](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/de.skaaa/32/3766_2.png) [@de.skaaa](https://forum.finsweet.com/u/de.skaaa)\
**Post date:** [March 31, 2026, 8:15am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/17 "2026-03-31T08:15:12Z")

</div>

Hello @Support-Luis , I badly need this functionality but I can’t seem to make it work. May have to do something with the new V2 attributes added.

I processed your code solution through Claude like this and something’s happening but I’m not quite there. Could you please have a look at the staging link [here](https://lavenir.webflow.io/fietsen/calculator-test) and the read-only [here](https://preview.webflow.com/preview/lavenir?utm_medium=preview_link&utm_source=designer&utm_content=lavenir&preview=7398df0cc1a7185721ae5b496de659ac&pageId=5ffc7f5f9aba719794fabb3d&itemId=69ca7685ea785319c266747c&workflow=preview)? [Here’s](https://www.loom.com/share/abc000bb899b4748813b1b82f26edf17) a Loom as well.

Many thanks.

> **Summary**
>
> /\* Location Double Filters \*/  
> document.addEventListener(‘DOMContentLoaded’, () =\> {  
> const citySelect = document.querySelector(‘[fs-cmsselect-element=“select”]’);  
> const bikeShopSelect = document.querySelector(‘[fs-cmsselect-element=“select-2”]’);  
> if (!citySelect || !bikeShopSelect) return;
> 
> // Wait for Finsweet to populate the selects  
> setTimeout(() =\> {  
> // Read all bike shop CMS items and store shop + city pairs  
> const bikeShopItems = document.querySelectorAll(‘[fs-cmsselect-element=“text-value-2”]’);  
> const bikeShops = ;
> 
> ```auto
> bikeShopItems.forEach((item) => {
> const shopName = item.textContent.trim();
> // The city reference is a sibling/nearby element in the same CMS item
> const parent = item.closest('[fs-list-element="list"] > *') || item.parentElement;
> const cityRef = parent.querySelector('[fs-list-field="location"]')?.textContent?.trim();
> 
> if (shopName && cityRef) {
> bikeShops.push({ shop: shopName, city: cityRef });
> }
> });
> 
> // Save original options as backup
> const originalOptions = Array.from(bikeShopSelect.options);
> 
> function rebuildBikeShops() {
> const selectedCity = citySelect.value;
> const placeholder = bikeShopSelect.querySelector('option[value=""]');
> bikeShopSelect.innerHTML = '';
> if (placeholder) bikeShopSelect.appendChild(placeholder);
> 
> const seen = new Set();
> bikeShops.forEach(({ shop, city }) => {
> if (selectedCity && selectedCity !== '' && city !== selectedCity) return;
> if (seen.has(shop)) return;
> seen.add(shop);
> 
> const option = document.createElement('option');
> option.value = shop;
> option.textContent = shop;
> bikeShopSelect.appendChild(option);
> });
> 
> bikeShopSelect.value = '';
> bikeShopSelect.dispatchEvent(new Event('change', { bubbles: true }));
> }
> 
> citySelect.addEventListener('change', rebuildBikeShops);
> 
> ```
> 
> }, 1500); // Give Finsweet time to initialize  
> });

---

<div class="post-metadata">

**Author:** ![jesse.muiruri](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/jesse.muiruri/32/6611_2.png) [@jesse.muiruri](https://forum.finsweet.com/u/jesse.muiruri)\
**Post date:** [April 3, 2026, 3:45pm UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/18 "2026-04-03T15:45:08Z")

</div>

Hi @de.skaaa

The setup is almost there!  
The main issue is the mixup of both Finsweet Attributes `v1` & `v2`

We need to get rid of the `v1` attributes  
On the `City` select remove the attribute `fs-cmsselect-element="select"`  
`v2` uses the `fs-list-field="location"`

On the `Shop` select remove the attribute `fs-cmsselect-element="select-2"`  
Add a unique attribute or id  
e.g. `id="bike-shop-select"`

Then on the divs with the texts `Brussels` & `Antwerpen`  
Update the attribute `fs-cmsselect-element="text-value"` on both  
To `fs-list-field="location"`

Then update the code accordingly

```auto
/* Location Double Filters */
document.addEventListener('DOMContentLoaded', () => {
  const citySelect = document.querySelector('[fs-list-field="location"]');
  const bikeShopSelect = document.querySelector('#bike-shop-select');
  if (!citySelect || !bikeShopSelect) return;

  // Wait for Finsweet to populate the selects
  setTimeout(() => {
    // Read all bike shop CMS items and store shop + city pairs
    const bikeShopItems = document.querySelectorAll('div[fs-list-field="location"]');
    const bikeShops = [];
    ...

```

---

<div class="post-metadata">

**Author:** ![de.skaaa](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/de.skaaa/32/3766_2.png) [@de.skaaa](https://forum.finsweet.com/u/de.skaaa)\
**Post date:** [April 7, 2026, 9:03am UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/19 "2026-04-07T09:03:58Z")

</div>

Hello @jesse.muiruri , many many thanks for your help. I think we’re close but the filtered bike shop items still won’t show up properly in the 2nd select field. [Here’s](https://www.loom.com/share/074a1e1a9f2f43cc80112ebdf71b88ac) a short loom, here’s the [staging link](https://lavenir.webflow.io/fietsen/calculator-test) and here’s a [read-only](https://preview.webflow.com/preview/lavenir?utm_medium=preview_link&utm_source=designer&utm_content=lavenir&preview=7398df0cc1a7185721ae5b496de659ac&pageId=5ffc7f5f9aba719794fabb3d&itemId=69ca7685ea785319c266747c&workflow=preview) again.

Could you please have a look and let me know what I’m getting wrong? Thank you so much.

---

<div class="post-metadata">

**Author:** ![jesse.muiruri](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.finsweet.com/jesse.muiruri/32/6611_2.png) [@jesse.muiruri](https://forum.finsweet.com/u/jesse.muiruri)\
**Post date:** [April 7, 2026, 3:41pm UTC](https://forum.finsweet.com/t/filter-cms-form-select-options/806/20 "2026-04-07T15:41:04Z")

</div>

Hi @de.skaaa

You can use this code, it gets the correct `bikeShop` divs  
PS: You could give the `cityRef` a more descriptive class or `custom attribute` e.g. `data="city-ref"`  
Then replace this line of code

```auto
const cityRef = parent.querySelector('.hide')?.textContent?.trim();

```

With

```auto
const cityRef = parent.querySelector('[data="city-ref"]')?.textContent?.trim();

```

Here’s the entire code

```auto
/* Location Double Filters */
document.addEventListener('DOMContentLoaded', () => {
  const citySelect = document.querySelector('[fs-list-field="location"]');
  const bikeShopSelect = document.querySelector('#bike-shop-select');
  if (!citySelect || !bikeShopSelect) return;

  // Wait for Finsweet to populate the selects
  setTimeout(() => {
    // Read all bike shop CMS items and store shop + city pairs
    const bikeShopItems = document.querySelectorAll('div[fs-list-field="bike-shop"]');
    const bikeShops = [];

    bikeShopItems.forEach((item) => {
      const shopName = item.textContent.trim();
      // The city reference is a sibling/nearby element in the same CMS item
      const parent = item.parentElement;
      const cityRef = parent.querySelector('.hide')?.textContent?.trim();

      if (shopName && cityRef) {
        bikeShops.push({ shop: shopName, city: cityRef });
      }
    });

    // Save original options as backup
    const originalOptions = Array.from(bikeShopSelect.options);

    function rebuildBikeShops() {
      const selectedCity = citySelect.value;
      const placeholder = bikeShopSelect.querySelector('option[value=""]');
      bikeShopSelect.innerHTML = '';
      if (placeholder) bikeShopSelect.appendChild(placeholder);

      const seen = new Set();
      bikeShops.forEach(({ shop, city }) => {
        if (selectedCity && selectedCity !== '' && city !== selectedCity) return;
        if (seen.has(shop)) return;
        seen.add(shop);

        const option = document.createElement('option');
        option.value = shop;
        option.textContent = shop;
        bikeShopSelect.appendChild(option);
      });

      bikeShopSelect.value = '';
      bikeShopSelect.dispatchEvent(new Event('change', { bubbles: true }));
    }

    citySelect.addEventListener('change', rebuildBikeShops)
  }, 1500); // Give Finsweet time to initialize
});

```

[Next page](https://forum.finsweet.com/t/filter-cms-form-select-options/806.md?page=2)
