2
votes

I would like to know how to dynamically update phoenix variables using javascript functions in my Phoenix templates.

Currently I have a list sent from my controller and I am using an elixir for loop to render html based on what is inside of it. I would like to be able to type into an input box and based on what is in the input box filter the list.

Example of the code

<%= for word <- @words do %>
  <p><%= word %></p>
<% end %>

I would like to be able to dynamically filter @words based on a js function.

Does anyone know how this can be achieved?

Thanks in advance

1
Check out this post, I've been using the hint from Dogbert as a best practice for a while. Don't know if you needed it at the time but you know need to wrap the Elixir JSON encoding in raw like var bob = <%= raw Poison.encode!() %>. stackoverflow.com/questions/39052160/… - The Brofessor
Perhaps, you might just want to read the @words from your js either by setting the value into a global variable from your view template or by setting it to a data-words attribute on some of your HTML elements - hisa_py

1 Answers

0
votes

There are a couple different approaches you can take, mainly depending on whether the JS function is initially called (on page load) or on only called later based on user action.

Approach 1. Generate JS in the Phoenix template and have JS render the list.

<script>
  var wordList = [
    <%= for word <- @words do %>
      '<%= word %>',
    <% end %>
  ];
</script>

Approach 2. As @hisa_py said, tag each item with a an attributes that you can later select and hide.

<%= for word <- @words do %>
  <p class='word-list' data-word='<%= word %>'><%= word %></p>
<% end %>

And then in JS

function show(list) do
  var words = $('.word-list');
  for (var i = 0; i < words.length; i++) {
    if (list.indexOf($(words[i]).addr('data-word')) === -1) {
      $(words[i]).hide();
    } else {
      $(words[i]).show();
    }
  }
}