Docs›Services›MadAction
Services

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.

Você raramente instancia MadAction à mão

<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étodoRetornoUso
with(array $params)selfMescla mais parâmetros, encadeável.
url()stringURL amigável (/app/slug/...) — delega para MadRoutes::urlFor().
js()stringJS de navegação completa: Mad.go(classe, método, params, urlAmigavel).
jsGet()stringJS de chamada parcial: Mad.get('Classe@método', {...}, null, urlAmigavel).
jsOverlay()stringJS via Mad.overlay('Classe@método', {...}, urlAmigavel).
jsRowAttach()stringJS via Mad.rowAttach(this, 'Classe@método', {...}, urlAmigavel) — abre o form anexado à <tr> da grid.
jsAuto()stringjsGet() ou js() conforme isOverlay().
onclick()stringAtributo HTML completo: onclick="..." com js() escapado.
onget()stringAtributo HTML completo com jsGet().
onRowAttach()stringAtributo HTML completo com jsRowAttach().
auto()stringAtributo HTML completo, auto-detect (onget() ou onclick()).
isOverlay()boolO destino é DRAWER/MODAL?
__toString()stringCast 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áticoDescriçã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.
Forward params têm menor prioridade

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)

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