LoginSignup
1
1

More than 1 year has passed since last update.

Railsで画像を選択するとidが送られるフォームを作りたい(ラジオボタンを画像で選択させる)

Last updated at Posted at 2022-02-02

概要

こんな感じのItemモデルへの投稿フォームの作りました。
画像を押すと選択され、もう一度押すと選択が解除されます。

mojikyo45_640-2.gif

投稿すると送られるパラメーター

Parameters: {"item"=>{"title"=>"青い玉", "ball_id"=>"2"}, "commit"=>"投稿"}

各モデルの構成

Itemモデル

タイトルとball_idを登録するテーブルです。

belongs_to :ball

Ballモデル

3種類のボールが画像と共に既にデータベースに登録済みとします。

has_many :items

ID NAME IMAGE
1 Red Red.png
2 Blue Blue.png
3 Green Green.png

コード

application_helper.rb
module ApplicationHelper
  #引数(モデル名とnameカラム)をもとに、idを返すメソッド
  def return_id_by_model_and_name(model, name)
    model.constantize.find_by(name: name).id
  end
end

html.erb

HTMLにonclick属性を使うのはあまり良くありませんが、実験ということで。
本当はイベントリスナーやイベントハンドラを使った方が良いです。

<h1>新規投稿</h1>
<%= form_with model: @item, local: true do |f| %>
  <h4 class="text-xl font-bold">タイトル</h4>
  <%= f.text_field :title %>

  <h4 class="text-xl font-bold">カラー</h4>
  <div class="boxContainer">

    <div class="text-center">
      <%= f.radio_button :ball_id, return_id_by_model_and_name("Ball", "Red"),{class:"radio_btn_to_image Red",
        onclick: "ballDeselection(this, #{return_id_by_model_and_name("Ball", "Red")})"} %>
      <%= f.label "ball_id_#{return_id_by_model_and_name("Ball", "Red")}", class:"remove_inner_html" %>
      <p>Red</p>
    </div>

    <div class="text-center">
      <%= f.radio_button :ball_id, return_id_by_model_and_name("Ball", "Blue"), {class:"radio_btn_to_image Blue",
        onclick: "ballDeselection(this, #{return_id_by_model_and_name("Ball", "Blue")})"} %>
      <%= f.label "ball_id_#{return_id_by_model_and_name("Ball", "Blue")}", class:"remove_inner_html" %>
      <p>Blue</p>
    </div>

    <div class="text-center">
      <%= f.radio_button :ball_id, return_id_by_model_and_name("Ball", "Green"), {class:"radio_btn_to_image Green",
        onclick: "ballDeselection(this, #{return_id_by_model_and_name("Ball", "Green")})"} %>
      <%= f.label "ball_id_#{return_id_by_model_and_name("Ball", "Green")}", class:"remove_inner_html" %>
      <p>Green</p>
    </div>

  </div>

  <%= f.submit '投稿', class:"px-2 bg-blue-600 text-white" %>
<% end %>

CSS


.boxContainer{
  display: flex;
}

.radio_btn_to_image+label:before{
  content: "";
  display: inline-block;
  background-size: contain;
  width: 80px;
  height: 80px;
}

.radio_btn_to_image:checked+label::before{
  border: 3px solid #000;
  box-sizing: border-box;
}

.radio_btn_to_image{
  display: none;
}

.radio_btn_to_image[class="radio_btn_to_image Red"]+label:before{
  background-image: url(/images/balls/Red.png); /*画像は/public/images/balls/に置いている*/
  background-repeat: no-repeat;
}
.radio_btn_to_image[class="radio_btn_to_image Blue"]+label:before{
  background-image: url(/images/balls/Blue.png);
  background-repeat: no-repeat;
}
.radio_btn_to_image[class="radio_btn_to_image Green"]+label:before{
  background-image: url(/images/balls/Green.png);
  background-repeat: no-repeat;
}

JavaScript

let ball_remove = 0;
function ballDeselection = (self, value) => {
  if(ball_remove == value) {
    self.checked = false;
    ball_remove = 0;
  } else {
    ball_remove = value;
  }
};

参考にさせていただいたサイト

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1