# Phoenix.HTML.Link.button with params

**URL:** <https://forum.elixirforum.com/t/phoenix-html-link-button-with-params/25827>\
**Category:** Questions\
**Tags:** phoenix, link\
**Created:** [October 3, 2019, 2:25pm UTC](https://forum.elixirforum.com/t/phoenix-html-link-button-with-params/25827 "2019-10-03T14:25:42Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![augnustin](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/augnustin/32/14538_2.png) [@augnustin](https://forum.elixirforum.com/u/augnustin)\
**Post date:** [October 3, 2019, 2:25pm UTC](https://forum.elixirforum.com/t/phoenix-html-link-button-with-params/25827/1 "2019-10-03T14:25:42Z")

</div>

Hello,

I’d like my `button("content", to: url)` to have extra hidden fields in it, like `button("content", to: url, params: %{field: "value"})` is this possible?

The same question went in Rails: [https://stackoverflow.com/questions/4886963/how-to-add-additional-params-to-a-button-to-form](https://stackoverflow.com/questions/4886963/how-to-add-additional-params-to-a-button-to-form) and it is now possible. 😄

Cheers

---

<div class="post-metadata">

**Author:** ![albydarned](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/albydarned/32/16621_2.png) [@albydarned](https://forum.elixirforum.com/u/albydarned)\
**Post date:** [October 3, 2019, 3:00pm UTC](https://forum.elixirforum.com/t/phoenix-html-link-button-with-params/25827/2 "2019-10-03T15:00:39Z")

</div>

From the [docs](https://hexdocs.pm/phoenix_html/Phoenix.HTML.Link.html)

```elixir
button("hello", to: "/world", method: "get", class: "btn")
#=> <button class="btn" data-method="get" data-to="/world">hello</button>

```

Try

```elixir
button("hello", to: "/world", method: "get", class: "btn", custom: "property")
#=> <button class="btn" data-method="get" data-to="/world" custom="property">hello</button>

```

Image from my test:  
 ![image](https://forum.elixirforum.com/uploads/default/original/3X/2/6/26f5a54099e003142cc20e1740347345d048d595.png)

---

<div class="post-metadata">

**Author:** ![augnustin](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/augnustin/32/14538_2.png) [@augnustin](https://forum.elixirforum.com/u/augnustin)\
**Post date:** [October 3, 2019, 3:07pm UTC](https://forum.elixirforum.com/t/phoenix-html-link-button-with-params/25827/3 "2019-10-03T15:07:02Z")

</div>

Apologies if I have been unclear but I’d like `custom=property` to be sent out within the ajax call that submits the form, while your solution only adds an html custom attribute, doesn’t it?

---

<div class="post-metadata">

**Author:** ![albydarned](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/albydarned/32/16621_2.png) [@albydarned](https://forum.elixirforum.com/u/albydarned)\
**Post date:** [October 3, 2019, 3:08pm UTC](https://forum.elixirforum.com/t/phoenix-html-link-button-with-params/25827/4 "2019-10-03T15:08:22Z")

</div>

I see, so this button is in a form?

Have you considered adding properties as [hidden inputs](https://hexdocs.pm/phoenix_html/Phoenix.HTML.Form.html#hidden_input/3)?

---

<div class="post-metadata">

**Author:** ![LostKobrakai](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/32/3072_2.png) [@LostKobrakai](https://forum.elixirforum.com/u/LostKobrakai)\
**Post date:** [October 3, 2019, 3:15pm UTC](https://forum.elixirforum.com/t/phoenix-html-link-button-with-params/25827/5 "2019-10-03T15:15:09Z")

</div>

I’m not sure why this was added to rails, but conceptionally it seems quite strange to exist. GET parameters are part of the url, so I’m not sure why they should be added via options on the button. Phoenixs’ route helpers allow you to add GET parameters to urls as well as the `URI` module of the elixir core. If you’re looking for additional body params you’d need to wrap the button in a form to submit, which has some hidden inputs.

---

<div class="post-metadata">

**Author:** ![OvermindDL1](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/overminddl1/32/2677_2.png) [@OvermindDL1](https://forum.elixirforum.com/u/OvermindDL1)\
**Post date:** [October 3, 2019, 3:23pm UTC](https://forum.elixirforum.com/t/phoenix-html-link-button-with-params/25827/6 "2019-10-03T15:23:15Z")

</div>

> [@augnustin](#):
>
> Apologies if I have been unclear but I’d like `custom=property` to be sent out within the ajax call that submits the form

Phoenix doesn’t use javascript to perform ajax calls, Phoenix is just a server that lets you do on the front-end whatever you wish. If you have something that needs to perform ajax calls then it is that which should do it, phoenix will just handle the back-end side. What front-end are you using that performs ajax in the browser?

---

<div class="post-metadata">

**Author:** ![augnustin](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/augnustin/32/14538_2.png) [@augnustin](https://forum.elixirforum.com/u/augnustin)\
**Post date:** [October 7, 2019, 10:48am UTC](https://forum.elixirforum.com/t/phoenix-html-link-button-with-params/25827/7 "2019-10-07T10:48:29Z")

</div>

Completely agreed with the fact that `GET` parameters should be in the query URL.

But `button\2` is actually more useful in the case of a `POST/PUT/DELETE` query IMHO, where `params` act as extra hidden fields.

Anyway, since it is [phoenix\_html.js](https://hexdocs.pm/phoenix_html/Phoenix.HTML.Link.html#link/2-javascript-dependency) which actually submits data, it could be conditional on the `method` so that `GET` is in the query parameter, and others are hidden fields.

I guess that’s what Rails does.

Cool thing about this is that `method` can be dynamic without having to rewrite the logic:

```elixir
= button("content", to: "/example", method: method, params: params)
/ instead of
= if method == :get do
  = button("content", to: "/example?#{params |> Enum.map(fn k, v -> "#{k}=#{v}" end) |> Enum.join("&")}"
- else
  = button("content", to: "/example", method: method, params: params)

```

---

<div class="post-metadata">

**Author:** ![augnustin](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/augnustin/32/14538_2.png) [@augnustin](https://forum.elixirforum.com/u/augnustin)\
**Post date:** [October 7, 2019, 10:52am UTC](https://forum.elixirforum.com/t/phoenix-html-link-button-with-params/25827/8 "2019-10-07T10:52:28Z")

</div>

Oh ok, I thought it would, like `rails_ujs` does. But apparently it does has [JS dependency](https://hexdocs.pm/phoenix_html/Phoenix.HTML.Link.html#link/2-javascript-dependency).

Of course, one can do without it, but in this case, it seems pretty reasonable to use it the _phoenix-way_ so that front-end and back-end plug each other easily.

Rails is really great at doing this, and I guess if phoenix is so much inspired from it, it means it is trying to reach the same convenience.

---

<div class="post-metadata">

**Author:** ![augnustin](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/augnustin/32/14538_2.png) [@augnustin](https://forum.elixirforum.com/u/augnustin)\
**Post date:** [October 7, 2019, 11:01am UTC](https://forum.elixirforum.com/t/phoenix-html-link-button-with-params/25827/9 "2019-10-07T11:01:51Z")

</div>

Basically instead of

```elixir
      content_tag(:button, text, [data: [method: method, to: to] ++ csrf_data] ++ opts)

```

I’d expect to go for:

```elixir
      content_tag(:form, text, method: method, action: to) do
        if method != :get do
          hidden_field(:csrf_token, Plug.CSRFProtection.get_csrf_token())
        end
        Enum.map(opts[:params], fn k, v -> 
          hidden_field(k, v)
        end) 
        content_tag(:button, text, type: :submit)
      end

```

And this would work for either `:get` and `:post`.

---

<div class="post-metadata">

**Author:** ![LostKobrakai](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/32/3072_2.png) [@LostKobrakai](https://forum.elixirforum.com/u/LostKobrakai)\
**Post date:** [October 7, 2019, 11:24am UTC](https://forum.elixirforum.com/t/phoenix-html-link-button-with-params/25827/10 "2019-10-07T11:24:38Z")

</div>

Phoenix’s button handling with `method` is mostly a convenience to not need to wrap just a button with a form, to defines nothing more than a url/method. If you need more data as part of the request use a form with hidden fields. You’re imho past the point there the convenience does make much sense.  
For get requests you could alter the url, but a form will also just use get params if you submit it with the `GET` method. I guess both ways are viable for get parameters.

> [@augnustin](#):
>
> ```elixir
> content_tag(:form, text, method: method, action: to) do
> if method != :get do
> hidden_field(:csrf_token, Plug.CSRFProtection.get_csrf_token())
> end
> Enum.map(opts[:params], fn k, v -> 
> hidden_field(k, v)
> end) 
> content_tag(:button, text, type: :submit)
> end
> 
> ```
> 
> And this would work for either `:get` and `:post` .

If you’d use `form_for` instead of `content_tag(:form, …)` you’d get the csrf token and the method override automatically and it would therefore work for any http method.

---

<div class="post-metadata">

**Author:** ![OvermindDL1](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/overminddl1/32/2677_2.png) [@OvermindDL1](https://forum.elixirforum.com/u/OvermindDL1)\
**Post date:** [October 7, 2019, 3:19pm UTC](https://forum.elixirforum.com/t/phoenix-html-link-button-with-params/25827/11 "2019-10-07T15:19:55Z")

</div>

> [@augnustin](#):
>
> Oh ok, I thought it would, like `rails_ujs` does.

No clue what `rails_ujs` is, but I can’t imagine such a feature working without javascript support for it, and thus it _will_ fail when javascript is disabled. It’s really not something that should be relied on.

---

<div class="post-metadata">

**Author:** ![alexsysm](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/alexsysm/32/23471_2.png) [@alexsysm](https://forum.elixirforum.com/u/alexsysm)\
**Post date:** [November 11, 2020, 2:21pm UTC](https://forum.elixirforum.com/t/phoenix-html-link-button-with-params/25827/12 "2020-11-11T14:21:20Z")

</div>

2 → link(“POST”, to: Routes.admin\_user\_path(@conn, :create, %{user: %{name: “alex”, uid: “alex@gmail”}}), method: :post, data: [confirm: “Are you sure?”], class: “btn btn-danger btn-xs”)
