Vypsání inputu v komponentě
- martinzi
- Člen | 6
Zdravím všechny,
Jsem naprostý začátečník v Nette a začal jsem dělat jednoduchý redakční systém webů.
Mám tedy formulář, který manuálně vykresluji v šabloně, do které includnu šablonu s inputy, které zrovna potřebuji (na základě stránce, kterou edituji). Vzhledem k množství opakujících se stejných inputů jsem se rozhodl vytvořit komponentu (zatím neznám jiný způsob.)
Šablona s inputy:
<div class="form-check">
<input n:name="single_product_btn_value" class="form-check-input" id="single_product_btn_value">
<label class="form-check-label" for="single_product_btn_value">
Kategorie
</label>
</div>
<div class="form-check">
<input n:name="single_product_heading" class="form-check-input" id="single_product_heading">
<label class="form-check-label" for="single_product_heading">
Header
</label>
</div>
Namísto repetetivního přepisování chci docílit něčeho takového
{var $inputText = "Product"}
{var $inputName = "single_product_btn_value"}
{control checkbox $inputText, $inputName}
vytvořil jsem si tedy componentu v AppearancePresenter
...
protected function createComponentCheckbox()
{
$control = new \CheckboxControl;
return $control;
}
...
Ve složce components mám CheckboxControl.php
use Nette\Application\UI\Control;
class CheckboxControl extends Control
{
// public function render(string $inputName, string $inputText)
public function render(string $inputText, string $inputName)
{
$template = $this->template;
// nastavení šablony
$template->setFile(__DIR__ . '/checkbox.latte');
// nastavení proměnné z parametru
$template->inputText = $inputText;
$template->inputName = $inputName;
$template->render();
}
}
a checkbox.latte
<div class="form-check">
<input n:name="{$inputName}" class="form-check-input" id="{$inputName}">
<label class="form-check-label" for="{$inputName}">
{$inputText}
</label>
</div>
Problém je v n:name, protože když tam není, vše funguje.
Vyhazovaná chyba – end() expects parameter 1 to be array, null given
Předem děkuji za tipy a rady.
- martinzi
- Člen | 6
@netteman – mám pouze jeden formulář a v něm veliké množství inputů různého druhu. Přemýšlel jsem že, jak vypisování zjednodušit a napadlo mě udělat na každý typ inputu jednu komponentu, kterou vypíšu. (jedna komponenta obsahuje pouze jeden input)
{block checkbox}
{* <div class="form-check">
<input n:name="{$inputName}" class="form-check-input" id="{$inputName}">
<label class="form-check-label" for="{$inputName}">
{$inputText}
</label>
</div>
{/block}
@Milo – Presenter jsem sem nechtěl dávat, je to celé jeden
vyliký zmatek ale mám to všechno tam. (Bez komponenty vše funguje).
Celý problém spočívá v tom, že když napíšu input ručně vše funguje,
ale když přes komponentu, input nefunguje a vyhazuje chybu.
Presenter AppearancePresenter.php:
<?php
declare(strict_types=1);
namespace AdminModule;
use Nette;
use Nette\Application\UI\Form;
use Nette\Utils\DateTime;
final class AppearancePresenter extends Nette\Application\UI\Presenter
{
protected function startup()
{
parent::startup();
if (!$this->getUser()->isLoggedIn()) {
$this->redirect('Homepage:default');
}
}
private Nette\Database\Explorer $database;
public function __construct(Nette\Database\Explorer $database)
{
$this->database = $database;
}
protected function createComponentCheckbox()
{
$control = new \CheckboxControl;
return $control;
}
public function renderGlobal(string $editedPage = null): void {
........
}
protected function createComponentNewForm(): Form
{
$web_structure = $this->database
->table("web_structure");
$web_colors = $this->database
->table("web_colors");
$web_content = $this->database
->table("web_content");
$web_info = $this->database
->table("web_info")
->get(1);
$gdpr = $this->database
->table("officials")
->where("type", "gdpr")
->fetch();
$termsandconditions = $this->database
->table("officials")
->where("type", "termsandconditions")
->fetch();
$form = new Form;
$form->addText("basicWebInfo_name")
->setDefaultValue($web_info->name);
$form->addUpload("faviconImg", "Favicon");
$input_list_display = [];
$httpRequest = $this->getHttpRequest();
$url = $httpRequest->getUrl();
$url = strval($url);
$sanitizeGet = explode("=", strtolower($url));
if (count($sanitizeGet) >= 2) {
$sanitizeGet2 = explode("%3a", $sanitizeGet[1]);
}else{
$sanitizeGet2[0] = "homepage";
$sanitizeGet2[1] = "default";
}
$actualPageLink = $sanitizeGet2[0] . ":" . $sanitizeGet2[1];
foreach($web_structure as $structure_section){
if(strtolower($structure_section->for_page) == $actualPageLink){
if($structure_section->type == "checkbox"){
${$structure_section->sec_name} = $structure_section->display;
array_push($input_list_display, $structure_section->sec_name);
$form->addCheckbox($structure_section->sec_name)
->setValue($structure_section->display);
}
}
}
if(count($input_list_display) == 0){
$input_list_display = "none";
}
$input_list_colors = [];
foreach($web_colors as $color){
if($color->editable == 1){
if(strtolower($color->for_page) == $actualPageLink){
array_push($input_list_colors, $color->name);
$form->addText($color->name)
->setHtmlType("color")
->setDefaultValue($color->value);
}
}
}
if(count($input_list_colors) == 0){
$input_list_colors = "none";
}
$input_list_text = [];
foreach($web_content as $content){
if(strtolower($content->for_page) == $actualPageLink){
array_push($input_list_text, $content->name);
$form->addText($content->name)
->setDefaultValue($content->content);
}
}
if(count($input_list_text) == 0){
$input_list_text = "none";
}
if($actualPageLink == "officials:gdpr"){
$form->addTextArea($gdpr->type)
->setAttribute("rows", 10)
->setDefaultValue($gdpr->content);
}
if($actualPageLink == "officials:termsandconditions"){
$form->addTextArea($termsandconditions->type)
->setAttribute("rows", 10)
->setDefaultValue($termsandconditions->content);
}
if($input_list_display != "none"){
$input_list_display = implode(", ", $input_list_display);
}
$form->addText("input_list_display")
->setDefaultValue($input_list_display);
if($input_list_colors != "none"){
$input_list_colors = implode(", ", $input_list_colors);
}
$form->addText("input_list_colors")
->setDefaultValue($input_list_colors);
if($input_list_text != "none"){
$input_list_text = implode(", ", $input_list_text);
}
$form->addText("input_list_text")
->setDefaultValue($input_list_text);
$form->addSubmit('send', 'Uložit a aktualizovat');
$form->onSuccess[] = [$this, 'newFormSubmited'];
return $form;
}
public function newFormSubmited(\stdClass $values): void
{
// foreach input on page update his value in database
if($values->input_list_display != "none"){
$input_list_display = explode(", ", $values->input_list_display);
foreach($input_list_display as $input){
$this->database
->table('web_structure')
->where('sec_name', $input)
->update([
'display' => $values->{$input},
]);
}
}
// foreach color in database save new value
if($values->input_list_colors != "none"){
$input_list_colors = explode(", ", $values->input_list_colors);
foreach($input_list_colors as $color){
$this->database
->table('web_colors')
->where('name', $color)
->update([
'value' => $values->{$color},
]);
}
}
// // update content in footer
if($values->input_list_text != "none"){
$input_list_text = explode(", ", $values->input_list_text);
foreach($input_list_text as $text){
$this->database
->table("web_content")
->where("name", $text)
->update([
"content" => $values->{$text},
]);
}
}
// update web_info name of website
if($values->basicWebInfo_name){
$this->database
->table("web_info")
->get(1)
->update([
"name" => $values->basicWebInfo_name,
]);
}
if(isset($values->gdpr)){
if($values->gdpr != ""){
$this->database
->table("officials")
->where("type", "gdpr")
->update([
"content" => $values->gdpr,
]);
}
}
// favicon update
$file = $values->faviconImg;
if($file->isImage() and $file->isOk()) {
$webInfo = $this->database
->table("web_info")
->get(1);
$old_favicon = $webInfo->favicon_name;
$old_path = "/hosting/www/martinzach.cz/bootstrapuser/www/images/" . $old_favicon;
if(file_exists($old_path)){
unlink($old_path);
}
$file_ext = strtolower(mb_substr($file->getSanitizedName(), strrpos($file->getSanitizedName(), ".")));
$new_file_name = "favicon" . $file_ext;
$file->move("/hosting/www/martinzach.cz/bootstrapuser/www/images/" . $new_file_name);
$this->database
->table("web_info")
->get(1)
->update([
"favicon_name" => $new_file_name
]);
}
$this->redirect('this');
}
}
- Milo
- Nette Core | 1283
Zapouzdřit jeden input formuláře do samostatné komponenty moc jednoduše nejde. Do komponent se zapouzdřují většinou celé formuláře. Zkus to jinak.
V úvodu ukazuješ svoji šablonu. Zkus to takhle:
<div class="form-check">
<input n:name="single_product_btn_value" class="form-check-input">
<label n:name="single_product_btn_value" />
</div>
<div class="form-check">
<input n:name="single_product_heading" class="form-check-input">
<label n:name="single_product_heading" />
</div>
Už to zápis zkrátí. Nebo se podívej do dokumentace na makra
{input ...}
a {label ...}
.
V latte si pro opakující se části můžeš definovat bloky. Například (píšu to z hlavy):
{define form-input}
<div class="form-check">
<input n:name="$name" class="form-check-input">
<label n:name="$name" />
</div>
{/define}
{include form-input, name: single_product_btn_value}
{include form-input, name: single_product_heading}