MadAction
Builder de URLs e onclicks tipados (MadAction::to).
Mad\Ui\MadAction é o builder central de navegação do MAD — gera
onclick e URLs para qualquer destino Classe@método, decidindo
entre navegação completa (Mad.load/Mad.go,
troca a tela) e chamada parcial (Mad.get/Mad.overlay,
abre modal/drawer por cima) conforme o $wrapper declarado no
MadComponent de destino.
<mad-btn navigate="Classe::método(args)"> (ou o atributo
target, aceito como alias) já compila para
MadAction::to(...)->auto() automaticamente — ver
mad-btn.
Use a classe diretamente só em onclicks customizados, geração de links para
e-mail/PDF, ou JS dinâmico.
API básica
MadAction::to($class, $method = 'show', $params = []) cria o builder.
A partir daí, métodos de saída (todos terminais, exceto with()):
use Mad\Ui\MadAction;
// URL AMIGAVEL — delega para MadRoutes::urlFor($class, $method, $params)
$url = MadAction::to('ProdutoForm', 'onEdit', ['id' => 42])->url();
// → /app/produtos/42/editar (ou /app/ProdutoForm/onEdit?id=42 no fallback)
// onclick="Mad.go(...)" — navegação completa (troca a tela)
$onclick = MadAction::to('ProdutoForm')->onclick();
// onclick="Mad.get(...)" — chamada parcial (abre modal/drawer por cima)
$onget = MadAction::to('ProdutoForm', 'onEdit', ['id' => 42])->onget();
// onclick="Mad.rowAttach(this, ...)" — form anexado à linha da grid (quick-edit)
$onRow = MadAction::to('ProdutoForm', 'onEdit', ['id' => 42])->onRowAttach();
// Auto-detect — escolhe onclick() ou onget() conforme o wrapper do destino
$auto = MadAction::to('ProdutoForm', 'onEdit', ['id' => 42])->auto();
| Método | Retorno | Uso |
|---|---|---|
with(array $params) | self | Mescla mais parâmetros, encadeável. |
url() | string | URL amigável (/app/slug/...) — delega para MadRoutes::urlFor(). |
js() | string | JS de navegação completa: Mad.go(classe, método, params, urlAmigavel). |
jsGet() | string | JS de chamada parcial: Mad.get('Classe@método', {...}, null, urlAmigavel). |
jsOverlay() | string | JS via Mad.overlay('Classe@método', {...}, urlAmigavel). |
jsRowAttach() | string | JS via Mad.rowAttach(this, 'Classe@método', {...}, urlAmigavel) — abre o form anexado à <tr> da grid. |
jsAuto() | string | jsGet() ou js() conforme isOverlay(). |
onclick() | string | Atributo HTML completo: onclick="..." com js() escapado. |
onget() | string | Atributo HTML completo com jsGet(). |
onRowAttach() | string | Atributo HTML completo com jsRowAttach(). |
auto() | string | Atributo HTML completo, auto-detect (onget() ou onclick()). |
isOverlay() | bool | O destino é DRAWER/MODAL? |
__toString() | string | Cast direto para string retorna url(). |
Auto-detect de wrapper
isOverlay() consulta $class::getWrapper() via reflection — se o
destino estende MadComponent e declara DRAWER ou
MODAL, o auto-detect usa chamada parcial; qualquer outro caso
(INTERNAL, classe não é MadComponent) usa navegação completa:
class ProdutoForm extends MadComponent
{
protected static string $wrapper = self::DRAWER; // ou MODAL / INTERNAL
}
// isOverlay() consulta ProdutoForm::getWrapper() via reflection
MadAction::to('ProdutoForm')->isOverlay(); // true (DRAWER)
// auto() usa isOverlay() para decidir:
// DRAWER/MODAL → onget() (Mad.get — abre por cima, sem trocar a tela)
// INTERNAL → onclick() (Mad.load — navega para a tela)
O que navigate=/target= realmente gera
O MadBladeCompiler (ver MadBlade)
reconhece os atributos navigate/target em qualquer tag
<mad-*> e os reescreve, em tempo de compilação, para uma chamada real a
MadAction::to(...)->auto() injetada na prop attrs do componente:
MAD__BLADE_COMMENT__1__
<mad-btn navigate="ProdutoForm::onEdit({{ $id }})" variant="primary">Editar</mad-btn>
MAD__BLADE_COMMENT__2__
Forward params
Forward params propagam um parâmetro (ex.: o ID do registro mestre) por toda a árvore
de navegação filha sem precisar repeti-lo manualmente em cada MadAction::to().
São setados globalmente (estáticos) pelo componente pai, tipicamente no show():
// No show() do componente pai — propaga negociacao_id para toda navegação filha
class NegociacaoForm extends MadComponent
{
public function show(): void
{
MadAction::setForwardParams(['negociacao_id' => $this->negociacaoId]);
parent::show();
}
}
// Qualquer MadAction::to(...) montada durante o render deste componente
// herda automaticamente negociacao_id E _forward_param_negociacao_id=...,
// para que o próximo destino possa repropagar adiante.
MadAction::to('ArquivoForm')->auto();
// → inclui negociacao_id=401&_forward_param_negociacao_id=401 na URL/params
| Método estático | Descrição |
|---|---|
setForwardParams(array $params) | Define os forward params globais (sem o prefixo — adicionado no output). |
getForwardParams() | Retorna os forward params atuais. |
clearForwardParams() | Limpa os forward params. |
Se você passar a mesma chave explicitamente em MadAction::to($class, $method, $params)
ou via with(), o valor explícito sempre vence sobre o forward param.
Detecção de método estático
url() só emite ?static=1 quando o método destino é
realmente um método PHP estático — checado via
ReflectionMethod::isStatic(), espelhando o gate do backend
(MadAppController::run). Em métodos de instância o parâmetro nunca é emitido,
evitando ruído na URL amigável de navegações comuns:
// MadAppController::run() honra ?static=1 SOMENTE quando o método destino é
// realmente um método PHP estático (ReflectionMethod::isStatic()). MadAction
// espelha essa checagem — emite static=1 sozinho quando faz sentido.
class ProdutoService
{
public static function onSearch(): void { /* ... */ }
}
MadAction::to(ProdutoService::class, 'onSearch')->url();
// → /app/ProdutoService/onSearch?static=1
MadAction::to('ProdutoForm', 'onEdit', ['id' => 42])->url();
// → /app/produtos/42/editar (onEdit é de instância: sem static=1)
Alvo declarativo — navTarget() e acceptsPost()
Widgets que recebem o destino como string num atributo Blade (cards, kanban,
org-chart, click-target) não montam a URL no client: o mapa de rotas
não vive no JS. MadAction::navTarget() assa no servidor o trio
class/method/url — e, para as chaves que só o client
conhece, devolve a URL com placeholder __MAD_<key>__ para substituição no
clique (mesmo contrato do FieldListAction):
// Widgets que recebem um alvo declarativo num atributo Blade (click-target,
// call=, action=) usam navTarget() para assar classe+metodo+URL no servidor.
MadAction::navTarget('ClienteForm'); // metodo = $defaultMethod ('show')
MadAction::navTarget('ClienteForm::onShow'); // metodo explicito
MadAction::navTarget('ClienteForm::onShow({id})'); // args declarados — o `({id})` some
// Retorno: ['class' => ..., 'method' => ..., 'url' => ...] — ou null se $target vazio.
// As chaves de $paramKeys (default ['id']) viram placeholder __MAD_id__ na URL:
// o servidor nao conhece o id do card clicado, entao assa o TEMPLATE e o client
// substitui na hora do clique — inclusive quando o id vai no PATH.
// A rota amigavel aceita POST? resource() registra so GET; expose()/
// exposeService()/exposeClass() registram match(['get','post']).
MadAction::acceptsPost('/app/clientes/42/editar'); // false — POSTar ali daria 405
Diretivas Blade — @madAction / @madGet / @madUrl
Para onclicks fora do alcance de <mad-btn>/<mad-act>
(HTML cru, componentes de terceiros), o MadBlade registra três diretivas que
delegam direto para MadAction:
MAD__BLADE_COMMENT__3__
<a href="#" @madAction('ProdutoForm', 'onEdit', ['id' => $id])>Editar</a>
MAD__BLADE_COMMENT__4__
<a href="#" @madGet('ProdutoForm', 'onEdit', ['id' => $id])>Editar (modal/drawer)</a>
MAD__BLADE_COMMENT__5__
<span data-href="@madUrl('ProdutoForm', 'onEdit', ['id' => $id])">só a URL, sem onclick</span>
Próximos passos
MadResponse::open() usa MadAction internamente para abrir componentes.