Arayüz Bileşenleri
Panelin kurulduğu dört yapı taşı. Eklediğiniz ekran, ürünle gelen ekranlar gibi görünür ve davranır.
Genel Bakış
Bileşen PHP'de kurulur ve şablonun içinde görünür: controller ne istediğini tarif eder, bileşen işaretlemeyi üretir. Sıralama, filtreleme, sayfalama ve sekme hafızası yeniden yazılmadan gelir.
Dördü de WISECP\Components altındadır ve new ile kurulur. Hepsi içeriğini konumsal argümanlarla değil bir seçenek dizisiyle alır.
Referans
Table
public function __construct(string $name, array $options = []); // $name = preset dosya adı
public function setColumns(array $columns): self;
public function setColumn(string $key, array $data): self;
public function deleteColumn(string $key): self;
public function setRows(array $rows): self;
public function setRowRender(callable $renderRow): self;
public function setFilters(array $filters): self;
public function setOptions(array $options): self;
public function getOptions(): array;
public function isRequestAjax(): bool;
public function ajaxControl(array $options = []): string;
public function allDataAjaxResponse(): string;
public function ajaxResponse(int $totalEntries = 0, int $totalSearchEntries = 0): string;
public function build(string $format = ''): string; // '' = tüm tablo, 'justBody' = yalnız satırlar
public function buildList(string $format = ''): string; // ızgara yerine kart satırları
public function container(string $content, array $attributes = []): string;
public function exportButton(array $options = []): string; // ['label', 'formats', 'class']
// Genel property'ler. İki model, bileşenin kendisinin çağırdığı closure'lardır.
public int $ajax_transition_limit = 500;
public mixed $totalModel; // fn (string $search = '', array $filters = []): int
public mixed $dataModel; // fn (string $search = '', string $order = '', string $direction = '', int $start = 0, int $end = -1): array
Kurucu seçenekleri, hepsi isteğe bağlı. Kurucu preset dosyasını kendisi include eder, controller başka hiçbir şeyi atamadan önce; bu yüzden preset seçenekleri getOptions() ile okur, satırları asla görmez.
'ticketList'.
true ilk sorguyu sekme açılana kadar erteler. Detay sekmesi için değil; pahalı kaynaklar için (dosya sistemi taraması, uzak katalog).
false kontrolü kaldırır; [10, 25, 50, 100, -1] sayfa boyutlarını verir, -1 tümü demektir.
'list' müşteri panelinin kullandığı kart düzenine geçirir. Başka her değer ızgara verir.
false kaldırır, bir yetki anahtarı daraltır, ad da dosya adı olur. Bunları controller'da verin: dışa aktarma isteği şablon çalışmadan sonlanır.
['data-url-sync' => 'true'].
ajaxControl() kendi dizisini alır; isteği zaten yanıtladıysa boş olmayan, aksi hâlde boş bir dize döner. Çağıran taraf onu olduğu gibi döndürür.
'partial' (varsayılan) sunucuda sayfalar; 'allData' tüm kümeyi tek yanıtta verir.
['type' => 'hosting'].
setRowRender() geri çağrınızın aldığı ve geri verdiği satırın üç parçası vardır:
$row = [
// Kaydın modelden geldiği hali. Salt-okunur girdi.
'model' => ['id' => 5, 'name' => 'example.com', 'status' => 'active'],
// Kolon anahtarı başına bir giriş. 'value' hücre işaretlemesi, 'attributes' <td>'ye iner.
// 'data-value' sıralamanın ve istemci tarafı filtrelemenin karşılaştırdığı HAM değerdir.
'data' => [
'id' => ['value' => '<a href="...">#5</a>', 'attributes' => ['data-value' => 5]],
'status' => ['value' => '<span class="badge">Aktif</span>', 'attributes' => ['data-value' => 'active']],
],
// <tr> attribute'ları. Satır seviyesi filtre değerleri buradan okunur.
'attributes' => ['class' => 'table-tr-bg-info', 'data-filter-status' => 'active'],
];
Tab ve Accordion
// Tab. $type 'horizontal' ya da 'vertical'. add() İKİ argüman alır:
// panel anahtarı, sonra bir seçenek dizisi. Panel gövdesi $options['content']'tir.
public function __construct($name = '', $type = 'horizontal');
public function add($name, $options = []): self;
public function set($name, $options = []): self; // add() ile aynı
public function get($name = '');
public function remove($name = ''): self;
public function noUrl(bool $noUrl = true): self;
public function render(array $options = [], string $header = '', string $contents = ''): string;
public function header($options = []): string;
public function contents(array $options = []): string;
// Accordion. Aynı fikir, tipli, ve dikey/yatay seçimi yok.
public function __construct(string $name = '');
public function add(string $name, array $options = []): self;
public function set(string $name, array $options = []): self;
public function get(string $name = '');
public function remove(string $name): self;
public function noUrl(): self;
public function render(array $options = []): string;
'bi bi-gear'. Yatay sekmede boşluk sınıfı iconClass'tan gelir ve varsayılanı 'me-2''dir.
'0' dahil.
true bu bölümü açık başlatır. Bölümler ortak bir ebeveyni paylaşır, biri açılınca diğerleri kapanır.
'h2') ve başlığın, tetikleyicinin (varsayılan 'bg-light', temizlemek için '') ve gövdenin sınıfları.
İkisi de açık paneli adreste, bileşenin kendi adı altında hatırlar: settings adlı bir sekme kümesi ?settings=general okur. Tek ekrandaki iki küme farklı ad ister.
Modal
// Her şey kurucuda verilir; setter'lar sonradan değiştirmek içindir
// ve void döndükleri için ZİNCİRLENMEZLER.
public function __construct(array $params);
public function setTitle(string $title): void;
public function setBody(string $body): void;
public function setFooter(string $footer): void;
public function setForm(?array $formAttributes): void; // attribute haritası, sarmayı kaldırmak için null
public function setHeaderClasses(array $classes): void;
public function render(): string;
'SampleModal', yani id'siz iki pencere çakışır.
<form> içine saran attribute haritası: ['action' => $url, 'method' => 'POST']. Her çift attribute olarak yazılır, footer'daki gönder butonu pencereyi gönderir. Salt-okunur pencerede vermeyin.
danger geçen bir değer kırmızı başlık, başkası birincil başlık verir. Kabuk sabittir, renkli bir şerit boyayamaz.
'modal-lg' gibi genişlik sınıfı ve ikisi de true varsayılanlı iki düzen anahtarı.
Örnek
Bir liste üç dosya alır: controller veriyi bağlar, preset kolonları tanımlar ve her satırı modelden kurar, sayfa şablonu sonucu gösterir.
$table = new \WISECP\Components\Table('widgetList', ['exportName' => 'widgets']);
// Operatörün seçtiği değerler. setFilters bunları veri isteğinde taşır;
// model ise yalnız bir isteği yanıtlarken alır.
$dynamic = [];
if ($status = Filter::init("REQUEST/filter/status", "route")) $dynamic['status'] = $status;
$table->setFilters($dynamic);
$filter = $table->isRequestAjax() ? $dynamic : [];
$table->totalModel = fn ($search = '', $filters = []) =>
$this->model->list(true, array_merge($filter, $filters, ['word' => $search]));
$table->dataModel = fn ($search = '', $order = '', $direction = '', $start = 0, $end = -1) =>
$this->model->list(false, array_merge($filter, ['word' => $search]), [$order => $direction], $start, $end);
// Boş olmayan dönüş, isteğin burada zaten yanıtlandığı anlamına gelir.
if ($response = $table->ajaxControl(['baseLink' => $links["controller"]])) return $response;
$this->addData('table', $table);
/** @var \WISECP\Components\Table $table */
if (!isset($table)) return;
$table->setColumns([
'id' => ['title' => 'ID', 'attributes' => ['class' => 'text-center'], 'sortable' => true],
'name' => ['title' => Language::gc("admin/widgets/th-name"), 'sortable' => true],
'status' => ['title' => Language::gc("admin/widgets/th-status"), 'sortable' => "asc"],
'email' => ['title' => Language::gc("admin/widgets/th-email"), 'exportOnly' => true],
]);
$table->setRowRender(function ($row) {
$id = (int) $row["model"]["id"];
$row["data"]["id"]["value"] = '<a href="?id=' . $id . '">#' . $id . '</a>';
$row["data"]["id"]["attributes"]["data-value"] = $id;
$row["data"]["name"]["value"] = htmlspecialchars($row["model"]["name"] ?? '');
// Filtrenin karşılaştırdığı ham değerdir; hücre rozeti gösterir.
$row["data"]["status"]["value"] = \WISECP\AdminComponents\Statuses::getInstance()->service($row["model"]["status"]);
$row["data"]["status"]["attributes"]["data-value"] = $row["model"]["status"];
// Ekranda çizilmez, indirmede vardır.
$row["data"]["email"]["value"] = $row["model"]["email"] ?? '';
$row["attributes"]["data-filter-status"] = $row["model"]["status"];
return $row;
});
// Sayfa şablonu basmadan hiçbir şey görünmez. Preset zaten kurucunun içinde çalıştı,
// bu çağrı yalnız controller ile preset'in kurduğunu render eder.
if (isset($table)) {
$table->setOptions(['containerExtraClass' => 'mt-3']);
echo $table->build();
}
Bir sekme kümesi ve bir pencere, ikisi de seçenek dizisiyle beslenir:
// footer.php $modals içinde ne varsa basar; şablon onu bir kez burada tanımlar
// ve sayfadaki her pencere üzerine ekler.
$modals = '';
$tab = new \WISECP\Components\Tab('widget-detail');
$tab->add('overview', [
'title' => Language::g('widgets-overview'),
'icon' => 'bi bi-grid-1x2',
'content' => $overviewHtml,
]);
// Koşul BURADA, bir kez. Paneli okuyan biri sekmenin bir şey düştüğü için değil
// bu kural yüzünden görünmediğini böylece bilir.
if ((int) Config::get('options/reselling/status') === 1)
$tab->add('reselling', [
'title' => Language::g('widgets-reselling'),
'badge' => $pendingCount,
'content' => $resellingHtml,
]);
echo $tab->render();
$modal = new \WISECP\Components\Modal([
'id' => 'widgetDeleteModal',
'title' => Language::g('needs/delete'),
'body' => '<p>' . Language::gc('admin/widgets/delete-confirm') . '</p>'
. '<input type="hidden" name="operation" value="delete_widget">',
'footer' => '<button type="submit" class="btn btn-danger">' . Language::g('needs/delete') . '</button>',
'headerClasses' => ['bg-danger'],
'modalDialogExtraClass' => 'modal-lg',
'form' => ['action' => $links["controller"], 'method' => 'POST'],
]);
$modals .= $modal->render();
Tuzaklar
add('overview', 'Genel Bakış', $html) yazmak, seçenek dizisinin beklendiği yere bir dize ve var olmayan bir üçüncü argüman geçirir. Panel, başlığı olarak anahtarını gösterir ve hiç içerik taşımaz, hata da vermez. Gövde $options['content']'tir.
Her setter void tiplidir. Birini diğerine zincirlemek null üzerinde ölümcül bir çağrıdır. Her şeyi kurucu dizisinde verin; setter'lar zaten verdiğiniz bir değeri değiştirmek içindir.
Bileşen, toplam eşiği aştığı anda sunucu tarafı sayfalamaya kendisi geçer. Bu kararı çağrı yerinde zorlarsanız ya elli bin satır tek belgeye girer ya da yirmi satır için fazladan bir tur ödersiniz.
Adrese yazan iki küme onun için çekişir, operatör geri döndüğünde yanlış çiftte açılır. İçteki küme noUrl() çağırır.
İlgili Makaleler
Geri bildiriminiz için teşekkürler!
Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.