Bootstrap modal rozbiji ajax
- Higr
- Člen | 16
Ahoj, snažím se vytvořit komponentu Picker(modal) která má v sobě
další komponentu data table. Po kliknutí na tlačítko se má modal otevřít
a v tabulce se načtou data. Koukal jsem do Chrome network tools a
data/snippety se přenášejí správně při každém kliku ikdyž modal
používám nebo ne.
Se zapnutým modalem to funguje tak, že při prvním kliknutí na tlačítko je
tabulka prázdná, při druhém kliknutí se zobrazí v tabulce data která se
měla zobrazit při prvním kliknutí, při třetím kliknutí se zobrazí data
z druhého kliknutí atd.
Když modal zakomentuju (nepoužívám) tak vše funguje v pořádku.
Presenter:
public function handleSetCategoryId($categoryId)
{
$this->getComponent('picker')->setFilter('category_id', $categoryId);
$this->redrawControl('picker');
}
public function createComponentPicker(): Picker
{
$picker = $this->pickerFactory->create();
$picker->addStorage(Picker::STORAGE_COMPONENT);
return $picker;
}
Presenter → default.latte
<div class="container d-flex flex-column align-items-center mt-3">
<a href="{plink setCategoryId! 1}" class="ajax" data-bs-toggle="modal" data-bs-target="#picker">category 1</a>
<a href="{plink setCategoryId! 2}" class="ajax" data-bs-toggle="modal" data-bs-target="#picker">category 2</a>
{snippet picker}
{control picker}
{/snippet}
</div>
Picker.php:
class Picker extends Control
{
const STORAGE_COMPONENT = 'component';
public function __construct(
private TranslatorFactory $translatorFactory,
private TableFactory $tableFactory,
private ComponentModel $componentModel,
private ?Closure $onPick = null,
private array $storages = [],
#[Persistent]
public array $filters = [
'active_storage' => null,
'search' => [
'category_id' => 0
]
],
)
{}
public function render()
{
$this->filters['active_storage'] = $this->filters['active_storage'] ?? key($this->storages);
$this->template->setTranslator($this->translatorFactory->create());
$this->template->setFile(__DIR__ . '/picker.latte');
$this->template->render();
}
public function createComponentPickerTable(): Table
{
$table = match($this->filters['active_storage']) {
self::STORAGE_COMPONENT => $this->tableFactory->createComponentsTable(),
};
$table->setDataFetch(fn($filters) => $this->storages[$this->filters['active_storage']]($this->filters));
return $table;
}
public function addStorage(string $type): void
{
$fetch = match ($type) {
self::STORAGE_COMPONENT => fn($filters) => $this->componentModel->getComponentsForPicker($filters),
};
$this->storages[$type] = $fetch;
}
public function setOnPick(Closure $onPick): void
{
$this->onPick = $onPick;
}
public function setFilter(string $searchKey, mixed $newValue, ?array &$array = null): mixed
{
if (!$array) {
$array = &$this->filters;
}
foreach ($array as $key => &$value) {
if ($key === $searchKey) {
$value = $newValue;
return true;
}
if (is_array($value) && !empty($value)) {
$result = $this->setFilter($searchKey, $newValue, $value);
if ($result) {
return true;
}
}
}
return false;
}
picker.latte: (když zakomentuju všechen modal nebo jen div #picker tak vše funguje)
<div class="modal fade" id="picker">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
{control pickerTable}
</div>
</div>
</div>
</div>
Editoval Higr (4. 9. 11:26)
- Higr
- Člen | 16
povedlo se mi to vyresit tak, ze modal oteviram javascriptem po skonceni ajaxu a zobrazena data jsou spravna:
default.latte:
<div class="container d-flex flex-column align-items-center mt-3">
<a href="{plink setCategoryId! 1}" class="ajax">category 1</a> // vypnout data atributy k otevirani
<a href="{plink setCategoryId! 2}" class="ajax">category 2</a>
{snippet picker}
{control picker}
{/snippet}
</div>
<script>
$(document).ajaxComplete(function() {
var pickerModal = new bootstrap.Modal(document.getElementById('picker'));
pickerModal.show();
});
</script>