JS.set_attribute, for setting input "value" not working


I’m trying to use JS.set_attribute to set the value on an input hidden, like this:

<input id="new_planner_action" name="new_planner[action]" type="hidden" value="save">

// on a phx-click
JS.set_attribute({"value", "publish"}, to: "#new_planner_action")

but does not seem to work, but this one works:

JS.set_attribute({"style", "background-color:red !important;"}, to: "#new_planner_action");

I’ve gonne through the documentation, but cannot find any reason why setting the value would not work in that way.

Is there any blocking or security issue when doing that?
Or for setting values there is diferent JS method?


I think you first need to remove the old attribute and then set the new one. Existing ones don’t get replace.

I am not sure if this is intended behaviour or not, but it should at least be documented.

In your case something like this should work:

<input id="new_planner_action" name="new_planner[action]" type="hidden" value="save">

// on a phx-click
JS.remove_attribute("value", to: "#new_planner_action") 
|> JS.set_attribute({"value", "publish"}, to: "#new_planner_action")

amazing. thanks @moogle19

cant find anything that mentions that in the those, besides that does not make any sense, is something that could be completly run internally… instead of making someone waste 2 days.


For regular inputs, there’s an important distinction between the control’s value and the attribute value, which is the initial setting. For instance, in this JSFiddle: Edit fiddle - JSFiddle - Code Playground

  • clicking “poke” without changing the input from its default value causes it to update to “bleh”

  • but typing in a new value and then clicking “poke” does NOT change the current value

I couldn’t reproduce this behavior with a hidden input, tho (at least in Chrome)

the weird part is that the DOM actually updates the value, if you inspect the value with dev tools, you can se the value changing, but is not reflected in the input itself.

This is because the dom attribute called value, attached to that input is changed, but the value of the input is not changed.

Try updating the fiddle with

function pokeInput() {
  var el = document.getElementById("thing")
  el.setAttribute("value", "bleh")
  console.log("el.getAttribute(value)", el.getAttribute("value"))
  console.log("el.value", el.value)

And play with the input, you’ll see that the value attribute gets changed but the value is not “clobbered” if the user has made a change, it’s effectively unlinked from the attribute on change.