Rails, flatpickr в простой форме не работает - PullRequest
1 голос
/ 07 апреля 2020

Сначала позвольте мне объяснить контекст очень быстро. Я создал это приложение, где пользователи могут организовывать джемы сессий musi c. Так что в основном у них есть возможность создавать такие мероприятия. Им предлагается ввести дату и диапазон часов в течение этого дня. В моей базе данных джем-сейшн имеет start_date и end_date, оба формата datetime. Это может способствовать усложнению моей жизни, поскольку было бы более логично иметь дату (ymd), а также start_time и end_time. Возможно, новая миграция для изменения - это лучшее решение, но позвольте мне спросить, могу ли я go обойти его таким, каким он является сейчас.

Пока мне удалось заставить его работать (вроде), но не с flatpickr.

Вот код, связанный с этой проблемой:

1 / В моем приложении / javascript / packs / application. js У меня есть это (TimePicker используется на другом страница для поиска, и, между прочим, работает нормально. Здесь я пытаюсь использовать datepicker):

import "bootstrap";
import "../plugins/flatpickr";

import flatpickr from "flatpickr";
import rangePlugin from "flatpickr/dist/plugins/rangePlugin";
import 'flatpickr/dist/flatpickr.min.css'

import 'mapbox-gl/dist/mapbox-gl.css'; // <-- you need to uncomment the stylesheet_pack_tag in the layout!
import { initMapbox } from '../plugins/init_mapbox';

flatpickr(".datepicker", {
  minDate: new Date,
  altInput: true,
});

flatpickr(".TimePicker", {
    // enableTime: true,
    minDate: new Date,
    altInput: true,
    plugins: [new rangePlugin({ input: ".timePicker-end"})]
  });

initMapbox();

2 / Файл schema.rb (только часть, касающаяся таблицы сессий jam):

  create_table "jam_sessions", force: :cascade do |t|
    t.string "title"
    t.string "description"
    t.string "genre"
    t.datetime "starts_at"
    t.datetime "ends_at"
    t.string "location"
    t.bigint "user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.float "latitude"
    t.float "longitude"
    t.index ["user_id"], name: "index_jam_sessions_on_user_id"
  end

3 / Новый файл, в котором находится форма:

<% music_genre = ["Acapella", "Accoustic", "Blues", "Classical", "Country", "Electronic", "Folk", "Funk", "Heavy Metal", "Hip Hop", "Jazz", "Latin", "Other", "Pop", "Reggae", "Rock", "World"] %>

<div class="container h-100">
  <div class="row justify-content-center align-items-center mt-3">
    <div class="col col-6">

      <h2>Create your own Jam Session</h2>

      <%= simple_form_for [@jam_session] do |f| %>
      <% f.error_notification %>
      <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>

        <div class="form-inputs">
          <%= f.input :title %>
          <%= f.input :description %>
          <%= f.input :genre, collection: music_genre %>
          <div class="row justify-content-center align-items-center mt-3">
            <%= f.input :starts_at, as: :string, required: true, input_html: {class: "datepicker"} %>
            <%= f.input :starts_at, as: :time, :minute_step => 15, required: true %>
            <%= f.input :ends_at, as: :time, :minute_step => 15, required: true %>
          </div>
          <%= f.input :location %>
        </div>

        <div class="d-flex justify-content-end">
          <%= f.button :submit, "GO !", class: 'big-button block' %>
        </div>
      <% end %>
    </div>
  </div>
</div>

4 / Контроллер jam_sessions

class JamSessionsController < ApplicationController
  def index
    # @jam_sessions = JamSession.search_by_location(params[:query])

    @jam_sessions = JamSession.includes(:spots, :instruments)
    # @jam_sessions = @jam_sessions.where(instruments: { id: jam_session_params[:instrument_id] }) if jam_session_params[:instrument_id].present?
    @jam_sessions = @jam_sessions.where(instruments: { id: params["jam_session"]["instrument_id"] }) if params["jam_session"]["instrument_id"].present?
    @jam_sessions = @jam_sessions.where(genre: params["jam_session"]["genre"]) if params["jam_session"]["genre"].present?
    @jam_sessions = @jam_sessions.search_by_location(params["jam_session"]["location"]) if params["jam_session"]["location"].present?


    if params[:jam_session] && params[:jam_session][:starts_at]
      x = params[:jam_session][:starts_at]

      @start_date = x&.split("to")[0]&.strip
      @end_date = x&.split("to")[1]&.strip

      @jam_sessions = @jam_sessions.where("starts_at > ?", @start_date) if @start_date.present?
      @jam_sessions = @jam_sessions.where("starts_at < ?", @end_date) if @end_date.present?
    end

    # -------- access input from user ---------
    # @location_input = params["jam_session"]["location"]
    # @starts_at_input = params["jam_session"]["starts_at"]
    # @ends_at_input = params["jam_session"]["ends_at"]
    # @instrument_input = Instrument.find(params["jam_session"]["instrument_id"]).name if params["jam_session"]["instrument_id"].present?
    geocode(@jam_sessions)
    # access id of instruments
    @session_instruments_id = Instrument.all
  end

  def show
    @jam_session = JamSession.find(params[:id])
    @markers = [{
      lat: @jam_session.latitude,
      lng: @jam_session.longitude,
      infoWindow: render_to_string(partial: "info_window", locals: { jam_session: @jam_session }),
      image_url: helpers.asset_url("custom_marker.png"),
    }]
    @messages = JamSession.includes(messages: :user).find(params[:id])
  end

  def new
    @jam_session = JamSession.new
  end

  def create
    @jam_session = JamSession.new(jam_session_params)
    @jam_session.user = current_user
    if @jam_session.save
      redirect_to jam_session_path(@jam_session)
    else
      render "new"
    end
  end

  private

  def geocode(jam_sessions)
    @jam_sessions = @jam_sessions.geocoded #returns jam_sessions with coordinates

    @markers = @jam_sessions.map do |jam_session|
      {
        lat: jam_session.latitude,
        lng: jam_session.longitude,
        infoWindow: render_to_string(partial: "info_window", locals: { jam_session: jam_session }),
        image_url: helpers.asset_url("custom_marker.png"),
      }
    end


  end

  def jam_session_params
    params.require(:jam_session).permit(:title, :description, :genre, :starts_at, :ends_at, :location, :instrument_id)
  end
end

Но он не работает. Визуально это происходит, это означает, что календарь появляется и кажется, что пользователь вводит правильную дату, но в конце дата игнорируется, и вместо этого по умолчанию дата дня записывается в базу данных.

Он работает с этим кодом в простой форме, но это уродливо, и только если я поставлю поле даты после полей часов, что противоречит интуитивно понятно:

<div class="row justify-content-center align-items-center mt-3">
  <%= f.input :starts_at, as: :time, :minute_step => 15, required: true %>
  <%= f.input :ends_at, as: :time, :minute_step => 15, required: true %>
  <%= f.input :starts_at, as: :date, required: true %>
</div>

Любая идея, как я мог бы заставить эту работу работать с flatipckr.

Вот пара вариантов 2 вариантов формы.

С датчиком (НЕ РАБОТАЕТ): datepicker not working

Просто простая форма (РАБОТАЮЩАЯ, но уродливая): enter image description here

ЗДЕСЬ ЖУРНАЛЫ, КОГДА Я СОЗДАЮ СЕМЬЮ ДЖАМА. Первая часть (перед ^ [[B ^ [[B] - это когда новая страница загружена, где находится форма. После этого - журналы после отправки формы. Чтобы быть понятным, дата начала, которую я ввел, была 28-й) но записал сегодняшнюю дату покупки по умолчанию)

Started GET "/jam_sessions/new" for ::1 at 2020-04-08 09:54:14 +0200
Processing by JamSessionsController#new as HTML
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ /home/olivier/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activerecord-5.2.4.1/lib/active_record/log_subscriber.rb:98
  Rendering jam_sessions/new.html.erb within layouts/application
  Rendered jam_sessions/new.html.erb within layouts/application (41.1ms)
  ActiveStorage::Attachment Load (0.3ms)  SELECT  "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4  [["record_id", 1], ["record_type", "User"], ["name", "photo"], ["LIMIT", 1]]
  ↳ app/views/shared/_navbar.html.erb:19
  ActiveStorage::Blob Load (0.4ms)  SELECT  "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ app/views/shared/_navbar.html.erb:19
  Rendered shared/_navbar.html.erb (5.0ms)
[Webpacker] Everything's up-to-date. Nothing to do
  Rendered shared/_footer.html.erb (0.3ms)
Completed 200 OK in 67ms (Views: 63.4ms | ActiveRecord: 1.0ms)


^[[B^[[B
Started POST "/jam_sessions" for ::1 at 2020-04-08 09:54:59 +0200
Processing by JamSessionsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"rA4WsBD2H9qDMp9/Jt/kxvJ6sJ+cHnRLByH0yFJlO/dm7EbNeuCtV3DK25pKVvb0RyaTWz2cUDhxWukL3HGMWQ==", "jam_session"=>{"title"=>"Let's play", "description"=>"sdfkjqsdhflkjshdflkjqs", "genre"=>"Country", "starts_at"=>"2020-04-28", "starts_at(1i)"=>"2020", "starts_at(2i)"=>"4", "starts_at(3i)"=>"8", "starts_at(4i)"=>"07", "starts_at(5i)"=>"00", "ends_at(1i)"=>"2020", "ends_at(2i)"=>"4", "ends_at(3i)"=>"8", "ends_at(4i)"=>"09", "ends_at(5i)"=>"00", "location"=>"Berlin"}, "commit"=>"GO !"}
  User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ /home/olivier/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activerecord-5.2.4.1/lib/active_record/log_subscriber.rb:98
   (0.3ms)  BEGIN
  ↳ app/controllers/jam_sessions_controller.rb:50
  JamSession Create (0.8ms)  INSERT INTO "jam_sessions" ("title", "description", "genre", "starts_at", "ends_at", "location", "user_id", "created_at", "updated_at", "latitude", "longitude") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING "id"  [["title", "Let's play"], ["description", "sdfkjqsdhflkjshdflkjqs"], ["genre", "Country"], ["starts_at", "2020-04-08 07:00:00"], ["ends_at", "2020-04-08 09:00:00"], ["location", "Berlin"], ["user_id", 1], ["created_at", "2020-04-08 07:54:59.230840"], ["updated_at", "2020-04-08 07:54:59.230840"], ["latitude", 52.5170365], ["longitude", 13.3888599]]
  ↳ app/controllers/jam_sessions_controller.rb:50
   (0.8ms)  COMMIT
  ↳ app/controllers/jam_sessions_controller.rb:50
Redirected to http://localhost:3000/jam_sessions/22
Completed 302 Found in 191ms (ActiveRecord: 2.3ms)


Started GET "/jam_sessions/22" for ::1 at 2020-04-08 09:54:59 +0200
Processing by JamSessionsController#show as HTML
  Parameters: {"id"=>"22"}
  JamSession Load (0.5ms)  SELECT  "jam_sessions".* FROM "jam_sessions" WHERE "jam_sessions"."id" = $1 LIMIT $2  [["id", 22], ["LIMIT", 1]]
  ↳ app/controllers/jam_sessions_controller.rb:33
  Rendered jam_sessions/_info_window.html.erb (0.7ms)
  CACHE JamSession Load (0.0ms)  SELECT  "jam_sessions".* FROM "jam_sessions" WHERE "jam_sessions"."id" = $1 LIMIT $2  [["id", 22], ["LIMIT", 1]]
  ↳ app/controllers/jam_sessions_controller.rb:40
  Message Load (0.3ms)  SELECT "messages".* FROM "messages" WHERE "messages"."jam_session_id" = $1  [["jam_session_id", 22]]
  ↳ app/controllers/jam_sessions_controller.rb:40
  Rendering jam_sessions/show.html.erb within layouts/application
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ app/views/jam_sessions/show.html.erb:12
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ app/views/jam_sessions/show.html.erb:12
  Spot Load (0.3ms)  SELECT "spots".* FROM "spots" WHERE "spots"."jam_session_id" = $1  [["jam_session_id", 22]]
  ↳ app/views/jam_sessions/show.html.erb:13
  User Exists (0.6ms)  SELECT  1 AS one FROM "users" INNER JOIN "participations" ON "users"."id" = "participations"."user_id" INNER JOIN "spots" ON "participations"."spot_id" = "spots"."id" WHERE "spots"."jam_session_id" = $1 AND "users"."id" = $2 LIMIT $3  [["jam_session_id", 22], ["id", 1], ["LIMIT", 1]]
  ↳ app/models/jam_session.rb:35
  Rendered shared/_chat-messages.html.erb (4.2ms)
  Spot Exists (0.4ms)  SELECT  1 AS one FROM "spots" LEFT OUTER JOIN "participations" ON "participations"."spot_id" = "spots"."id" WHERE "spots"."jam_session_id" = $1 AND "participations"."spot_id" IS NULL LIMIT $2  [["jam_session_id", 22], ["LIMIT", 1]]
  ↳ app/views/jam_sessions/show.html.erb:86
  CACHE User Exists (0.0ms)  SELECT  1 AS one FROM "users" INNER JOIN "participations" ON "users"."id" = "participations"."user_id" INNER JOIN "spots" ON "participations"."spot_id" = "spots"."id" WHERE "spots"."jam_session_id" = $1 AND "users"."id" = $2 LIMIT $3  [["jam_session_id", 22], ["id", 1], ["LIMIT", 1]]
  ↳ app/models/jam_session.rb:35
  SQL (0.5ms)  SELECT "spots"."id" AS t0_r0, "spots"."jam_session_id" AS t0_r1, "spots"."instrument_id" AS t0_r2, "spots"."created_at" AS t0_r3, "spots"."updated_at" AS t0_r4, "participations"."id" AS t1_r0, "participations"."spot_id" AS t1_r1, "participations"."user_id" AS t1_r2, "participations"."created_at" AS t1_r3, "participations"."updated_at" AS t1_r4 FROM "spots" LEFT OUTER JOIN "participations" ON "participations"."spot_id" = "spots"."id" WHERE "spots"."jam_session_id" = $1 AND "participations"."spot_id" IS NULL  [["jam_session_id", 22]]
  ↳ app/views/jam_sessions/show.html.erb:95
  Rendered jam_sessions/show.html.erb within layouts/application (14.5ms)
  ActiveStorage::Attachment Load (0.4ms)  SELECT  "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4  [["record_id", 1], ["record_type", "User"], ["name", "photo"], ["LIMIT", 1]]
  ↳ app/views/shared/_navbar.html.erb:19
  ActiveStorage::Blob Load (0.3ms)  SELECT  "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ app/views/shared/_navbar.html.erb:19
  Rendered shared/_navbar.html.erb (4.2ms)
[Webpacker] Everything's up-to-date. Nothing to do
  Rendered shared/_footer.html.erb (0.3ms)
Completed 200 OK in 41ms (Views: 32.3ms | ActiveRecord: 3.9ms)

Спасибо! Оливье

1 Ответ

1 голос
/ 08 апреля 2020

Хорошо, у вас есть два поля, которые оба являются «sets_at», поэтому второе перезаписывает первое.

Я не уверен, может ли flatpickr сделать время окончания в небольшом всплывающем окне. Я знаю, что у него может быть день начала и окончания в одном всплывающем окне, а также время, но время окончания я не уверен. Так что вы, вероятно, хотите сделать, это одно поле, в котором вы просто выбираете дату, а затем две для времени, которое вы уже подготовили. И затем в контроллере в действии create вы собираете все вместе, прежде чем создавать новый джем-сейшн

Так что одно из полей «launch_at» вам нужно переименовать. Simple_form это не понравится, потому что он смотрит на объект сеанса jam, и у него нет просто другого столбца даты. Так что здесь нам нужно немного обдумать это и просто написать поле ввода либо в плане html, либо с помощью помощника из rails.

Вы можете просто включить поле ввода в форму, и оно будет отправлено вместе с формой, но мы хотим убедиться, что информация получает правильное место в параметрах. Вы знаете, что вся информация о джем-сейшне вложена под ключом "jam_session" в параметрах ha sh.

params = {..., "jam_session"= {"title"=>"Let's play", ... }... }

Как это заканчивается? Это объясняется тем, что каждая строка в вашей простой форме после преобразования в html имеет атрибут name, который определяет структуру параметров ha sh. (Проверьте каждое поле ввода вашей формы в браузере). Это выглядит примерно так:

<input class="form-control" type="text" name="jam_session[title]" id="jam_session_title">

И мы должны скопировать это для даты - назовем это днем, чтобы мы могли различить guish это.

<input class="form-control" type="text" name="jam_session[day]" id="jam_session_day" class="datepicker">

Не забудьте добавить класс datepicker.

Теперь это должно привести к параметрам ha sh, у которых есть день, но также start_date и end_date. От даты начала и окончания нам понадобится только время, а не дата. Поэтому в контроллере jam_sessions в действии create вам нужно создать правильные форматы даты и времени, прежде чем создавать новый экземпляр.

Проверьте параметры, чтобы увидеть, что вы получите, и создайте новые экземпляры даты, которые затем будете использовать для создания. новый экземпляр джем-сейшн. Дайте мне знать, если вам нужна помощь в этом.

Ключевые вещи для изучения:

  • Простая форма - отличный инструмент, но он также скрывает много важных элементов в формах, которые заставляют их передавать информацию, как они делают. Всегда проверять элементы ввода в браузере.
  • Простая форма создает связь между моделью и формой. Однако вы можете добавить в форму дополнительные поля - даже простую форму.
  • Структура ha sh определяется атрибутами name в полях ввода.
...