Skip to content

Commit

Permalink
refactor: improving region event
Browse files Browse the repository at this point in the history
  • Loading branch information
siganushka committed Oct 16, 2024
1 parent c691cf9 commit 46b8ef6
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 28 deletions.
44 changes: 44 additions & 0 deletions assets/controllers/region_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Controller } from '@hotwired/stimulus';

/*
* The following line makes this controller "lazy": it won't be downloaded until needed
* See https://github.com/symfony/stimulus-bridge#lazy-controllers
*/
/* stimulusFetch: 'lazy' */
export default class extends Controller {
static values = {
url: String,
cascader: String,
}

connect() {
this.element.addEventListener('change', this.handleChange.bind(this))
}

disconnect() {
this.element.removeEventListener('change', this.handleChange.bind(this))
}

handleChange(event) {
const cascaderEl = document.getElementById(this.cascaderValue)
if (!cascaderEl) return

fetch(`${this.urlValue}?parent=${event.target.value}`,{
headers: { Accept: 'application/json' },
}).then(response => {
return response.ok
? response.json()
: Promise.reject(`${response.status} ${response.statusText}`)
}).then(res => {
const options = res.map(el => `<option value="${el.code}">${el.name}</option>`)

const placeholder = cascaderEl.querySelector('option[value=""]')
if (placeholder) {
options.unshift(placeholder.outerHTML)
}

cascaderEl.innerHTML = options.join('')
cascaderEl.dispatchEvent(new Event('change'))
}).catch(err => alert(err))
}
}
49 changes: 23 additions & 26 deletions public/main.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
const siganushkaRegion = () => {
document.addEventListener('DOMContentLoaded', () => {
const change = async (event) => {
const { siganRegionTarget, siganRegionUrl } = event.target.dataset
const target = document.getElementById(siganRegionTarget)
if (target) {
const regions = []

const placeholder = target.querySelector('option[value=""]')
console.log('change...', event.target.dataset)
const { regionCascaderValue, regionUrlValue } = event.target.dataset
const cascaderEl = document.getElementById(regionCascaderValue)
if (!cascaderEl) return

fetch(`${regionUrlValue}?parent=${event.target.value}`,{
headers: { Accept: 'application/json' },
}).then(response => {
return response.ok
? response.json()
: Promise.reject(`${response.status} ${response.statusText}`)
}).then(res => {
const options = res.map(el => `<option value="${el.code}">${el.name}</option>`)

const placeholder = cascaderEl.querySelector('option[value=""]')
if (placeholder) {
regions.push({ code: '', name: placeholder.textContent })
}

if (event.target.value) {
const headers = { Accept: 'application/json' }
const response = await fetch(`${siganRegionUrl}?parent=${event.target.value}`, { headers })
regions.push(... await response.json())
options.unshift(placeholder.outerHTML)
}

const options = regions.map(el => `<option value="${el.code}">${el.name}</option>`)
target.innerHTML = options.join('')
target.dispatchEvent(new Event('change'))
}

cascaderEl.innerHTML = options.join('')
cascaderEl.dispatchEvent(new Event('change'))
}).catch(err => alert(err))
}

const elements = document.querySelectorAll('[data-sigan-region-target]')
const elements = document.querySelectorAll('[data-controller="region"]')
elements.forEach(element => element.addEventListener('change', change))
}

// Native event
document.addEventListener('DOMContentLoaded', siganushkaRegion)
// Hotwire turbo event
document.addEventListener('turbo:render', siganushkaRegion)
})
7 changes: 5 additions & 2 deletions src/Form/Extension/RegionTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
public function buildView(FormView $view, FormInterface $form, array $options): void
{
if ($options['cascader_target']) {
$view->vars['attr']['data-sigan-region-target'] = \sprintf('%s_%s', $view->parent->vars['id'] ?? '', $options['cascader_target']);
$view->vars['attr']['data-sigan-region-url'] = $this->urlGenerator->generate('siganushka_region_region_getcollection', [], UrlGeneratorInterface::ABSOLUTE_URL);
$controllerName = 'region';

$view->vars['attr']['data-controller'] = $controllerName;
$view->vars['attr']["data-{$controllerName}-url-value"] = $this->urlGenerator->generate('siganushka_region_region_getcollection', [], UrlGeneratorInterface::ABSOLUTE_URL);
$view->vars['attr']["data-{$controllerName}-cascader-value"] = \sprintf('%s_%s', $view->parent->vars['id'] ?? '', $options['cascader_target']);

Check warning on line 39 in src/Form/Extension/RegionTypeExtension.php

View workflow job for this annotation

GitHub Actions / Tests with PHP 8.1

PossiblyNullArrayAccess

src/Form/Extension/RegionTypeExtension.php:39:94: PossiblyNullArrayAccess: Cannot access array value on possibly null variable $view->parent->vars of type mixed|null (see https://psalm.dev/079)

Check warning on line 39 in src/Form/Extension/RegionTypeExtension.php

View workflow job for this annotation

GitHub Actions / Tests with PHP 8.1

PossiblyNullArgument

src/Form/Extension/RegionTypeExtension.php:39:94: PossiblyNullArgument: Argument 2 of sprintf cannot be null, possibly null value provided (see https://psalm.dev/078)
}
}

Expand Down

0 comments on commit 46b8ef6

Please sign in to comment.