PHPackages                             gakowalski/gk-form-toolkit - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. gakowalski/gk-form-toolkit

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

gakowalski/gk-form-toolkit
==========================

CRUD and form related utilities for Laravel

037[5 issues](https://github.com/gakowalski/gk-form-toolkit/issues)PHP

Since Nov 21Pushed 1y ago1 watchersCompare

[ Source](https://github.com/gakowalski/gk-form-toolkit)[ Packagist](https://packagist.org/packages/gakowalski/gk-form-toolkit)[ RSS](/packages/gakowalski-gk-form-toolkit/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (2)Used By (0)

GK Form Toolkit
===============

[](#gk-form-toolkit)

Instalacja
----------

[](#instalacja)

### Wymagania i zgodność

[](#wymagania-i-zgodność)

Pakiet przetestowany na:

- PHP 8.0
- Laravel 8

Teoretycznie powinien działać też na PHP 7.4. W przypadku Laravel 7 mogą wystapić problemy związane ze zmianą struktury folderów oraz (co za tym idzie) przestrzeni nazw.

### Świeży serwis

[](#świeży-serwis)

```
sudo /usr/local/bin/composer self-update && composer --version
composer update
composer require gakowalski/gk-form-toolkit
```

### Aktualizacja serwisów korzystających z rozproszonych plików zamiast pakietu

[](#aktualizacja-serwisów-korzystających-z-rozproszonych-plików-zamiast-pakietu)

```
rm -v app/Html.php app/Smartcrop.php app/Http/Controllers/GenericAppController.php app/Http/Requests/ModelBasedFormRequest.php
sudo /usr/local/bin/composer self-update && composer --version
composer update
composer require gakowalski/gk-form-toolkit
```

Użytkowanie
-----------

[](#użytkowanie)

### Obsługa błędów

[](#obsługa-błędów)

Aby korzystać z alternatywnej metody raportowania błędów do pliku dziennika, należy w pliku `app\Exceptions\Handler.php` metodę `report()` zmienić na:

```
public function report(Throwable $exception)
{
  \Kowalski\Laravel\App\Exceptions\Handler::report($exception);
}
```

### Html

[](#html)

#### Wprowadzenie

[](#wprowadzenie)

Klasa `\App\Html` jest zbiorem rozwiazań wspomagającym **na poziomie podstawowym** wytwarzanie kodu HTML tworzenie a **na pozimie rozszerzonym** obsługę formularzy.

Jakkolwiek klasa posiada konstruktor, to tworzenie jej obiektów ma miejsce tylko przy bardzo podstawowym wytwarzaniu pojedynczych znaczników HTML. W 99% praca dzieje się na wyższym pozimie abstrakcji opartym o wywołania jednej z wielu metod statycznych. Niemalże wszystkie zwracają wartość typu `string` lub obiekt bezpośrednio konwertowany na `string` a wynik jest przeznaczony do użytku w plikach widoku, więc wygląda to zazwyczaj tak:

```
{!! \App\Html::some_function('some_arg', $some_arg_2) !!}
```

Istotne jest użycie `{!! !!}` zamiast typowego `{{ }}` aby treści znakowe zostały przekazane do widoku bez filtrowania.

Dla czytelności wprowadzono możliwość stosowania dedykowanej dyrektywy Blade: `@html`. Wówczas kod wygląda tak:

```
@html(some_static_function('some_arg', $some_arg_2))
```

Migracja na dyrektywę za pomocą search &amp; replace:

- `{!! \App\Html::` na `@html(`
- ` !!}` oraz `!!}` na `)`

#### Tworzenie prostych znaczników

[](#tworzenie-prostych-znaczników)

```
{!! new \App\Html('p', 'Hello world!', [
  'align' => 'center',
  'id' => 'my-hello',
]) !!}
```

Powyższy kod generuje następujący HTML:

```
Hello world!
```

W przypadku niektórych znaczników nie jest generowany tag zamykający, gdy treść znacznika jest równa `null`:

```
{!! new \App\Html('input', null, [ 'type' => 'submit' ]) !!}
```

Lista takich znaczników znajduje się w `\App\Html::$_self_closing_tags`.

#### Tworzenie linków

[](#tworzenie-linków)

```
1 @html(link('http://domain.com'))
2 @html(link('http://domain.com', 'Moja domena'))
3 @html(new_tab('http://domain.com'))
4 @html(new_tab('http://domain.com', 'Moja domena'))
5 @html(email('info@domain.com'))
6 @html(email('info@domain.com', 'Napisz do mnie'))
7 @html(phone('123456789'))
8 @html(phone('123456789', 'Zadzwoń!'))
```

Odpowiadają mniej więcej:

```
1 http://domain.com
2 Moja domena
3 http://domain.com
4 Moja domena
5 info@domain.com
6 Napisz do mnie
7 123456789
8 Zadzwoń do mnie
```

#### Tworzennie pól typu select oraz grup radio

[](#tworzennie-pól-typu-select-oraz-grup-radio)

##### Grupa radio

[](#grupa-radio)

Grupa w układzie pionowym

```
@html(form_group('select_radio', 'answer', $category_id, null, [
  'options' => [
    0 => 'NIE',
    1 => 'TAK',
    2 => 'NIE WIEM',
  ],
]))
```

W przypadku Bootstrap, aby uzyskać układ poziomy należy zawrzeć pole w kontenerze i następnie użyć reguł CSS opartych o flex:

```
.kontener .form-control {
  display: flex;
  gap: 2em;
  font-size: 1em;
}
```

W przypadku JetStream oraz Tailwind możliwe jest przekazanie odpowiedniego stylu poprzez `options_group_classes`:

```
@html(form_group('select_radio', 'answer', $category_id, null, [
  'options' => [ 0 => 'NIE', 1 => 'TAK', ],
  'options_group_classes' => 'flex',
]))
```

##### Select wielopoziomowy

[](#select-wielopoziomowy)

```
@html(form_group('select_multilevel', 'zwierzeta', 'rodzaj', 'Rodzaj zwierzęcia', [
  'options' => json_decode(json_encode([
    [
      'label' => 'Ssaki',
      'value' => '2',
      'children' => [
        [ 'value' => 'pies', 'label' => 'Pies', 'children' => null ],
        [ 'value' => 'kot', 'label' => 'Kot', 'children' => null ],
        [ 'value' => 'kon', 'label' => 'Koń', 'children' => null ],
      ],
    ],
    [
      'label' => 'Ptaki',
      'value' => '1',
      'children' => [
        [ 'value' => 'slowik', 'label' => 'Słowik', 'children' => null ],
        [ 'value' => 'golab', 'label' => 'Gołąb', 'children' => null ],
        [ 'value' => 'wrona', 'label' => 'Wrona', 'children' => null ],
      ],
    ],
  ])),
  'options_default_label' => '(Wybierz zwierzę)',
]))

```

#### Sterowanie trybami

[](#sterowanie-trybami)

Działanie klasy `\App\Html` można zmieniać dla wielu generowanych przez nią elementów poprzez zmianę ustawienia trybów. Włączenie trybu realizuje się tak:

```
@html(set_mode('nazwa_trybu', true))
```

Warto dodać, że metoda zwraca zawsze pusty string.

Wyłączenie trybu wygląda tak:

```
@html(set_mode('nazwa_trybu', false))
```

Możliwe jest pobranie aktualnego stanu trybu poprzez metodę `get_mode('nazwa_trybu')`. Wynikiem nie jest pusty string lecz wartość `true` lub `false`.

### Formularze

[](#formularze)

#### Wiązanie zmiennych

[](#wiązanie-zmiennych)

Gdy z różnych przyczyn `form_group` nie może odczytać danych z odpowiedniej tablicy, można dokonać ręcznego powiązania nazwy tablicy ze zmienną.

```
@html(form_add_var('search', $search))

```

#### File upload

[](#file-upload)

Aby upload działał, najpier należy wprowadzić route `upload` do API, która zawiadywać będzie zapisem `single_file` do pliku, sprawdzeniem jego właściwości, utworzeniem miniaturki oraz przede wszystkim zwróci obiekt JSON o właściwościach:

- url - ścieżka dopisywana później do bazowego adresu witryny
- preview - jeżeli nie ma dostępnej miniaturki, tutaj powinien znaleźć się URL do obrazka zastępującego ją (może być to placeholder, ale może to być też docelowy obraz w pełnym rozmiarze)
- thumbnail - ścieżka do miniaturki
- title - nazwa pliku lub po prostu inna nazwa, która wyświetli się przy miniaturce,

```
Route::post('upload', function(Request $request) {
  $supported_images = ['jpeg', 'jpg', 'JPG', 'gif', 'png'];
  $thumbnail = '';

  if ($request->hasFile('single_file') && $request->file('single_file')->isValid()) {
    $path = 'attachments/' . time() . '--' . $request->single_file->getClientOriginalName();
    file_put_contents(storage_path('app/public/') . $path, $request->single_file->getContent());
    if (in_array(pathinfo($path, PATHINFO_EXTENSION), $supported_images)) {
      Smartcrop::thumbnail(storage_path('app/public/') . $path, 300, 300);
      $thumbnail = Smartcrop::asset("storage/$path", 300, 300);
    }
    return json_encode([
      'url' => "storage/$path",
      'preview' => in_array(pathinfo($path)['extension'], $supported_images) ? "storage/$path" : asset('storage/images/file-icon-pngwing.com.png'),
      'thumbnail' => $thumbnail,
      'title' => $request->single_file->getClientOriginalName(),
    ]);
  }
  return 'ERROR';
})->name('upload');
```

Następnie można dodać pole formularza typu `file` ze stosownymi opcjami:

- route - nazwa route'u do funkcji upload
- loader - ścieżka do animowanego obrazu, który wstępnie będzie wyswietlony zanim funkcja upload zwóci link do właściwej miniaturki
- use\_smartcrop - informacja czy użyta ma być biblioteka SmartCrop do wycinania miniatur w taki sposób, aby ujmować najważniejszą cześć oryginalnego obrazu
- default\_source - domyślna ikona do wyświetlenia gdy brak miniatury
- preview\_width - szerokość miniatury
- preview\_height - wysokość miniatury
- gallery\_name - nazwa galerii, używana w przypadku korzystania z biblioteki glightbox jako wartość atrybutu `data-gallery`
- gallery\_selector - nazwa klasy dla elementów typu `a` zawierających w sobie obraz, aby je wszystkie włączyć do jednej galerii glightbox

```
$html = '';
$html .= \App\Html::form_group('file', $variable, $field . '--zalacznik--1', null, [
  'upload' => [
    'route' => route('upload'),
    'loader' => asset('storage/images/ajax-loader.gif'),
    'use_smartcrop' => true,
    'default_source' => asset('storage/images/file-icon-pngwing.com.png'),
    'preview_width' => 150,
    'preview_height' => 150,
    'gallery_name' => "$variable--$field",
    'gallery_selector' => 'glightbox',
  ],
]);
$html .= new \App\Html('label', "Dodaj załącznik", [
  'for' => \App\Html::field_id($variable, $field, 'upload-input'),
  'class' => 'btn',
]);
echo $html;
```

### Eksport do XLSX

[](#eksport-do-xlsx)

### Szablony klas

[](#szablony-klas)

```
cd app/Templates/
cp GenericControllerTemplate.php make Patronat
```

Generates new PatronatControllerTemplate, PatronatController, Patronat model file, Patronat requests files.

###  Health Score

19

—

LowBetter than 10% of packages

Maintenance30

Infrequent updates — may be unmaintained

Popularity8

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity26

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/f262c24205f77ff354004ec42690b58e0d6e8107e24fe6b519268bc96ad5c206?d=identicon)[gakowalski](/maintainers/gakowalski)

---

Top Contributors

[![gakowalski](https://avatars.githubusercontent.com/u/1021798?v=4)](https://github.com/gakowalski "gakowalski (29 commits)")

---

Tags

laravelphp

### Embed Badge

![Health badge](/badges/gakowalski-gk-form-toolkit/health.svg)

```
[![Health](https://phpackages.com/badges/gakowalski-gk-form-toolkit/health.svg)](https://phpackages.com/packages/gakowalski-gk-form-toolkit)
```

###  Alternatives

[heyday/silverstripe-hashpath

Hash path provides a function in SilverStripe templates which given a path to an asset returns a path including a hash of the asset

1475.3k](/packages/heyday-silverstripe-hashpath)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
