This page is part of a series that describes building a complete todo list application with LiveComponent. Please consider reading it from the beginning.
1 | <div class="TodoItem"> |
2 | <% if @editing %> |
3 | <%= form_with(model: @todo_item) do |f| %> |
4 | <%= f.text_field :text %> |
5 | <%= f.submit %> |
6 | <% end %> |
7 | <% else %> |
8 | <%= @todo_item.text %> |
9 | <%= button_tag( |
10 | "Edit", |
11 | data: { action: "click->todoitemcomponent#edit" } |
12 | ) %> |
13 | <%= button_to( |
14 | "Delete", |
15 | todo_list_todo_item_path( |
16 | @todo_item.todo_list_id, |
17 | @todo_item
|
18 | ),
|
19 | rerender: :parent, |
20 | method: :delete, |
21 | form: { |
22 | data: { |
23 | turbo: true, |
24 | turbo_stream: true |
25 | }
|
26 | }
|
27 | ) %> |
28 | <% end %> |
29 | </div>
|
1 | <div class="TodoItem"> |
2 | <% if @editing %> |
3 | <%= form_with(model: @todo_item) do |f| %> |
4 | <%= f.text_field :text %> |
5 | <%= f.submit %> |
6 | <% end %> |
7 | <% else %> |
8 | <%= @todo_item.text %> |
9 | <%= button_tag( |
10 | "Edit", |
11 | data: { action: "click->todoitemcomponent#edit" } |
12 | ) %> |
13 | <%= button_to( |
14 | "Delete", |
15 | todo_list_todo_item_path( |
16 | @todo_item.todo_list_id, |
17 | @todo_item
|
18 | ),
|
19 | rerender: :parent, |
20 | method: :delete, |
21 | form: { |
22 | data: { |
23 | turbo: true, |
24 | turbo_stream: true |
25 | }
|
26 | }
|
27 | ) %> |
28 | <% end %> |
29 | </div>
|
1 | class TodoItemComponent < ApplicationComponent |
2 | include LiveComponent::Base |
3 | |
4 | def initialize(todo_item:, editing: false) |
5 | @todo_item = todo_item |
6 | @editing = editing |
7 | end
|
8 | end
|
1 | class TodoItemComponent < ApplicationComponent |
2 | include LiveComponent::Base |
3 | |
4 | def initialize(todo_item:, editing: false) |
5 | @todo_item = todo_item |
6 | @editing = editing |
7 | end
|
8 | end
|
1 | import { live, LiveController } from "@camertron/live-component"; |
2 | |
3 | @live("TodoItemComponent") // this is the Ruby class name |
4 | export class TodoItemComponent extends LiveController { |
5 | edit() { |
6 | this.render((component) => { |
7 | component.props.editing = true; |
8 | });
|
9 | }
|
10 | }
|
1 | import { live, LiveController } from "@camertron/live-component"; |
2 | |
3 | @live("TodoItemComponent") // this is the Ruby class name |
4 | export class TodoItemComponent extends LiveController { |
5 | edit() { |
6 | this.render((component) => { |
7 | component.props.editing = true; |
8 | });
|
9 | }
|
10 | }
|
1 | <h1><%= @todo_list.name %></h1> |
2 | <ul>
|
3 | <% todo_items.each do |todo_item| %> |
4 | <li><%= todo_item %></li> |
5 | <% end %> |
6 | </ul>
|
7 | <%= form_with( |
8 | model: [@todo_list, @todo_list.todo_items.build], |
9 | rerender: :self
|
10 | ) do |f| %> |
11 | <%= f.text_field :text %> |
12 | <%= f.submit "Add todo item" %> |
13 | <% end %> |
1 | <h1><%= @todo_list.name %></h1> |
2 | <ul>
|
3 | <% todo_items.each do |todo_item| %> |
4 | <li><%= todo_item %></li> |
5 | <% end %> |
6 | </ul>
|
7 | <%= form_with( |
8 | model: [@todo_list, @todo_list.todo_items.build], |
9 | rerender: :self
|
10 | ) do |f| %> |
11 | <%= f.text_field :text %> |
12 | <%= f.submit "Add todo item" %> |
13 | <% end %> |
1 | class TodoListComponent < ApplicationComponent |
2 | include LiveComponent::Base |
3 | |
4 | renders_many :todo_items, TodoItemComponent |
5 | |
6 | def initialize(todo_list:) |
7 | @todo_list = todo_list |
8 | end
|
9 | end
|
1 | class TodoListComponent < ApplicationComponent |
2 | include LiveComponent::Base |
3 | |
4 | renders_many :todo_items, TodoItemComponent |
5 | |
6 | def initialize(todo_list:) |
7 | @todo_list = todo_list |
8 | end
|
9 | end
|
1 | Rails.application.routes.draw do |
2 | resources :todo_lists do |
3 | resources :todo_items |
4 | end
|
5 | end
|
1 | Rails.application.routes.draw do |
2 | resources :todo_lists do |
3 | resources :todo_items |
4 | end
|
5 | end
|
1 | # frozen_string_literal: true
|
2 | |
3 | class TodoItemsController < ApplicationController |
4 | def update |
5 | @todo_item = TodoItem.find(params[:id]) |
6 | @todo_item.update(todo_item_params) |
7 | end
|
8 | |
9 | def create |
10 | @todo_list = TodoList.find(params[:todo_list_id]) |
11 | @todo_item = @todo_list.todo_items.create(todo_item_params) |
12 | end
|
13 | |
14 | def destroy |
15 | TodoItem.delete(params[:id]) |
16 | end
|
17 | |
18 | private
|
19 | |
20 | def todo_item_params |
21 | params.require(:todo_item).permit(:text) |
22 | end
|
23 | end
|
1 | # frozen_string_literal: true
|
2 | |
3 | class TodoItemsController < ApplicationController |
4 | def update |
5 | @todo_item = TodoItem.find(params[:id]) |
6 | @todo_item.update(todo_item_params) |
7 | end
|
8 | |
9 | def create |
10 | @todo_list = TodoList.find(params[:todo_list_id]) |
11 | @todo_item = @todo_list.todo_items.create(todo_item_params) |
12 | end
|
13 | |
14 | def destroy |
15 | TodoItem.delete(params[:id]) |
16 | end
|
17 | |
18 | private
|
19 | |
20 | def todo_item_params |
21 | params.require(:todo_item).permit(:text) |
22 | end
|
23 | end
|
1 | class TodoListsController < ApplicationController |
2 | def show |
3 | @todo_list = TodoList |
4 | .includes(:todo_items) |
5 | .find(params[:id]) |
6 | end
|
7 | end
|
1 | class TodoListsController < ApplicationController |
2 | def show |
3 | @todo_list = TodoList |
4 | .includes(:todo_items) |
5 | .find(params[:id]) |
6 | end
|
7 | end
|
1 | class TodoItem < ApplicationRecord |
2 | belongs_to :todo_list |
3 | end
|
1 | class TodoItem < ApplicationRecord |
2 | belongs_to :todo_list |
3 | end
|
1 | class TodoList < ApplicationRecord |
2 | has_many :todo_items |
3 | end
|
1 | class TodoList < ApplicationRecord |
2 | has_many :todo_items |
3 | end
|
1 | <%= live.rerender(todo_list: @todo_list) do |todo_list_component| %> |
2 | <% todo_list_component.with_todo_item(todo_item: @todo_item) %> |
3 | <% end %> |
1 | <%= live.rerender(todo_list: @todo_list) do |todo_list_component| %> |
2 | <% todo_list_component.with_todo_item(todo_item: @todo_item) %> |
3 | <% end %> |
1 | <%= live.rerender do |todo_list_component| %> |
2 | <% todo_list_component.todo_items.reject! do |todo_item_component| %> |
3 | <% todo_item_component.todo_item.id == params[:id].to_i %> |
4 | <% end %> |
5 | <% end %> |
1 | <%= live.rerender do |todo_list_component| %> |
2 | <% todo_list_component.todo_items.reject! do |todo_item_component| %> |
3 | <% todo_item_component.todo_item.id == params[:id].to_i %> |
4 | <% end %> |
5 | <% end %> |
1 | <%= live.rerender(todo_item: @todo_item, editing: false) %> |
1 | <%= live.rerender(todo_item: @todo_item, editing: false) %> |
1 | <%= render(TodoListComponent.new(todo_list: @todo_list)) do |todo_list_component| %> |
2 | <% @todo_list.todo_items.each do |todo_item| %> |
3 | <% todo_list_component.with_todo_item(todo_item: todo_item) %> |
4 | <% end %> |
5 | <% end %> |
1 | <%= render(TodoListComponent.new(todo_list: @todo_list)) do |todo_list_component| %> |
2 | <% @todo_list.todo_items.each do |todo_item| %> |
3 | <% todo_list_component.with_todo_item(todo_item: todo_item) %> |
4 | <% end %> |
5 | <% end %> |