Reputation: 1785
I have the following leex template with a collection of cards and inside each card, there is a nested button.
I would like to update the text on the button only without rendering again the whole component. Is it possible?
I am stuck here. The idea is to send an update to this button but it's not clear how if possible at all.
Or is another way would be assigning again the @repos
to the socket?
<form phx-change="gsearch">
<fieldset>
<label for="name">Name</label>
<input id="name" type="text" name="name" value="<%= @name %>"
placeholder="Search repos..."
autofocus autocomplete="off" phx-debounce="500" />
<input class="button-primary" type="submit" value="Clear"/>
</fieldset>
</form>
<%= unless @repos == [] do %>
<h2>Search Results</h2>
<div class="cont">
<%= for repo <- @repos do %>
<%= card do %>
<%= card_header do %>
<h2>Name: <%= repo.name %> Stars: <%= repo.stars %></h2>
<%= if repo.description != nil do %>
<%= repo.description %>
<% end %>
<% end %>
<%= card_body do %>
<%= link repo.link, to: repo.link, target: "_blank" %>
<button id="<%= repo.id %>"
class="button-primary fav"
phx-click="save"
phx-value-id="<%= repo.id %>"
phx-value-action="<%= if repo.liked do %>unlike<% else %>like<% end %>"
style="display: block">
<%= if repo.liked do %>Remove<% else %>Add<% end %>
</button>
<% end %>
<% end %>
<% end %>
</div>
<% end %>
When I click the button, I do the job on the server side and then I want to update only this button in particular.
As it is clear from the code, buttons are located inside the card component which is just a div.
Is it possible to update just the button which I clicked?
Upvotes: 1
Views: 672
Reputation: 324
Since you're using LiveView, updating the socket such that the new repos
assign contains an updated target repo with a toggled liked
attribute should do the trick. Here's one way of updating the assigns:
def handle_event("save", %{"id" => id}, socket) do
# update repo in db
# ...
# then update repo in socket
updated_socket =
update(socket, :repos, fn repos ->
update_in(repos, [Access.filter(&(&1.id == id}}], fn repo ->
%{repo | liked: !repo.liked}
end)
end)
{:noreply, updated_socket}
end
I'd also suggest reading through the Managing State section of the LiveView docs. It's meant for LiveComponent and Heex, but should still be applicable and lays out the different options you have for state management.
Upvotes: 0