Skip to content

phx-value-value on <li> elements returns native DOM value (0) instead of attribute value #4139

@lifeiscontent

Description

@lifeiscontent

Environment

  • Phoenix LiveView version: 1.1.22
  • Elixir version: 1.18
  • Phoenix version: 1.8.3

Description

When using phx-value-value on <li> elements, the server receives the element's native DOM value property (integer 0) instead of the phx-value-value attribute value.

Steps to Reproduce

  1. Create a dropdown/listbox using <ul> and <li> elements:
<ul>
  <li
    :for={{label, value} <- [{"2025", 2025}, {"2026", 2026}]}
    role="option"
    phx-click="select"
    phx-value-value={to_string(value)}
  >
    {label}
  </li>
</ul>
  1. Click on "2025" option

  2. Observe server logs:

HANDLE EVENT "select"
  Parameters: %{"value" => 0}

Expected Behavior

The server should receive %{"value" => "2025"} (the string from phx-value-value).

Actual Behavior

The server receives %{"value" => 0} (integer 0 from the native DOM value property).

Root Cause

The <li> element has a native DOM value property (HTMLLIElement.value) that defaults to 0. This is meant for ordered lists to specify the ordinal value.

From the LiveView docs:

If the phx-value- prefix is used, the server payload will also contain a "value" if the element's value attribute exists.

The native DOM property is being read and overwrites the phx-value-value attribute because they share the same key name.

Workaround

Use a different parameter name:

<li phx-click="select" phx-value-selected={to_string(value)}>

Suggested Fix

A few options:

  1. Documentation: Add a note warning about using phx-value-value on elements with native value properties (<li>, <input>, <button>, etc.)

  2. Prioritize attribute over property: When both phx-value-X attribute and native X property exist, prefer the explicit attribute

  3. Namespace protection: Don't merge native properties when a phx-value- attribute with the same name exists

Option 2 or 3 would be ideal since the developer's explicit phx-value-value attribute should take precedence over the native DOM property.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions