PageSourceSearch

https://careers.stanwell.com/assets/sites/controllers/jobs/search_controller-f0103ba8.js

js stanwell.com collected 2026-10-02 06:57:03 UTC 4,256 bytes, 129 lines download raw bytes

1import BaseController from 'common/controllers/base_controller'
2import URI from 'urijs'
3
4export default class extends BaseController {
5  static targets = ['pageBlock', 'form', 'checkbox', 'dropdown', 'sort', 'activeFilter', 'freetext', 'jobsSearchResults']
6
7  connect() {
8    window.addEventListener('popstate', (e) => {
9      if (e.state && e.state.newHtml) {
10        Turbo.renderStreamMessage(e.state.newHtml)
11      }
12      requestAnimationFrame(() => {
13        this.updateFilterCheckboxes()
14      })
15    })
16    this.markConnected()
17  }
18
19  clearFilters() {
20    this.freetextTarget.value = ''
21    for (const checkboxTarget of this.checkboxTargets) {
22      checkboxTarget.checked = false
23    }
24    for (const dropdownTarget of this.dropdownTargets) {
25      dropdownTarget.options.selectedIndex = 0
26    }
27    this.filterChange()
28  }
29
30  clearMobileFilters() {
31    for (const dropdownTarget of this.dropdownTargets) {
32      for (const option of dropdownTarget.options) option.selected = false
33    }
34    this.filterChange()
35  }
36
37  sortJobs(event) {
38    this.sortTarget.value = event.target.value
39    this.findSearchJobResults(() => this.refocusSearchJobResults())
40  }
41
42  filterChange() {
43    this.findSearchJobResults()
44  }
45
46  submitForm(e) {
47    e.preventDefault()
48    this.findSearchJobResults()
49  }
50
51  findSearchJobResults(callback) {
52    const jobSearchParams = this.convertFormDataToQueryParams(new FormData(this.formTarget))
53    const jobSearchUrl = this.formTarget.action
54    const jobSearchUrlWithParams = URI(jobSearchUrl).search(jobSearchParams).toString()
55    fetch(jobSearchUrlWithParams, {headers: {Accept: 'text/vnd.turbo-stream.html'}}
55)
56      .then(response => response.text())
57      .then(html => this.replaceSearchPage(jobSearchUrl, html, callback))
58
59    document.dispatchEvent(new CustomEvent('clinch:job_search_results_updated', {detail: {jobSearchParamsAsJson: JSON.stringify(jobSearchParams)}}))
60  }
61
62  closeActiveFilters(event) {
63    const activeFilter = event.target.closest(".active-filter")
64    const checkbox = this.checkboxTargets.find((a) => a.id === activeFilter.dataset.filterId)
65    if (checkbox) {
66      checkbox.checked = false
67    }
68    activeFilter.classList.add("d-none")
69  }
70
71  replaceSearchPage(baseUrl, newHtml, callback) {
72    Turbo.renderStreamMessage(newHtml)
73    this.recordLocalHistoryState(baseUrl, newHtml)
74    if (callback) {
75      callback()
76    }
77  }
78
79  //there's a lot of manual coding going on here - think we could do better with some simpler Turbo stream code
80  recordLocalHistoryState(baseUrl, newHtml) {
81    const blockUid = this.pageBlockTarget.dataset.uid
82    const historyUrl = URI(baseUrl).search(this.serializeFormHistoricalInputs()).toString()
83    history.pushState({
84      uid: blockUid,
85      newHtml: newHtml,
86    }, document.title, historyUrl)
87  }
88
89  serializeFormHistoricalInputs() {
90    const formData = new FormData()
91    for (const input of this.formTarget.querySelectorAll("input[type='hidden'].historical,input[type='text'].historical,input[type='checkbox'].historical:checked")) {
92      formData.append(input.name, input.value)
93    }
94    for (const input of this.formTarget.querySelectorAll("select.historical")) {
95      if (input.value !== '') {
96        formData.append(input.name, input.value)
97      }
98    }
99    return this.convertFormDataToQueryParams(formData)
100  }
101
102  convertFormDataToQueryParams(form) {
103    const formQueryParams = {}
104    for (const [key, value] of form.entries()) {
105      if (!Reflect.has(formQueryParams, key)) {
106        formQueryParams[key] = value
107      } else {
108        //convert the existing value to an array and add the new one
109        if (!Array.isArray(formQueryParams[key])) {
110          formQueryParams[key] = [formQueryParams[key]]
111        }
112        formQueryParams[key].push(value)
113      }
114    }
115    return formQueryParams
116  }
117
118  refocusSearchJobResults() {
119    // requestAnimationFrame is used to ensure document updates occur before focusing
120    requestAnimationFrame(() => {
121      this.jobsSearchResultsTarget.focus()
122    })
123  }
124
125  updateFilterCheckboxes() {
126    const params = new URLSearchParams(window.location.search)
127    this.checkboxTargets.forEach((checkbox) => {checkbox.checked = params.getAll(checkbox.name).includes(checkbox.value)})
128  }
129}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.