1

I have a simple event app with a 'new event' form on the index page. It should create a new event and update the index page without having to reload the page. I already tried disabling turbo-link as per this stackoverflow post but to no avail. Lastly, it also has a calendar on the same page that I'd like to update with the index of events.

Here's a quick list of things that might factor into a solution:

  • routes to a subdomain
  • this was originally a scaffold

    enter image description here

    Gemfile:

    ## abbreviated ##
            gem 'coffee-rails', '~> 4.1.0'
            gem 'jquery-rails'
            gem 'jquery-turbolinks'
            gem 'jbuilder', '~> 2.0'
            gem 'simple_calendar', '~> 2.0.1'
            gem 'bootstrap-sass', '~> 3.3.5'
    

    application.js

    //= require jquery
    //= require jquery.turbolinks
    //= require jquery_ujs
    //= require_tree .
    

    events_controller.rb

    class EventsController < ApplicationController
      def index
        @events = @account.events.all
        @event = @account.events.new
      end
    
      def create
        @event = @account.events.new(event_params)
        @event.save!
    
        @events = @account.events.all
    
        respond_to do |format|
          format.html { redirect_to events_path }
          # supposedly this line below appends my partial from 'app/views/events/_event.html.erb
          format.js 
        end
      end
    ## abbreviated ##
    

    app/views/events/_event.html.erb

    <tr>
      <td><%= event.location %></td>
      <td><%= event.time.strftime("%I:%M %p") %></td>
      <td><%= event.event_name %></td>
      <td><%= link_to 'Show', event %></td>
      <td><%= link_to 'Edit', edit_event_path(event) %></td>
      <td><%= link_to 'Destroy', event, method: :delete, data: { confirm: 'Are you sure?' } %></td>
    </tr>
    

    events/index.html.erb

    <p id="notice"><%= notice %></p>
    
    <h1>Listing Events</h1>
    
    <div class="fluid-container">
      <div class="col-xs-7">
        <%= month_calendar attribute: :time, events: @events do |date, time_slots| %>
          <%= date.strftime("%m/%d") %>
    
          <% time_slots.each do |event| %>
            <div>
              <%= link_to event.event_name, event %>
            </div>
          <% end %>
        <% end %>
      </div><!--col-xs-7-->
      <div class="col-xs-5">
        <br />
    
        <p>
        <%= link_to "Toggle Events", "#", id: "events-link" %>
        </p>
    
        <section id="events-section">
          <%# <%= render 'form' %1> %>
          <%= form_for(@event, remote: true) do |f| %>
            <% if @event.errors.any? %>
              <div id="error_explanation">
                <h2><%= pluralize(@event.errors.count, "error") %> prohibited this event from being saved:</h2>
    
                <ul>
                  <% @event.errors.full_messages.each do |message| %>
                    <li><%= message %></li>
                  <% end %>
                </ul>
              </div>
            <% end %>
    
            <div class="form-group">
              <%= f.label :location %><br>
              <%= f.text_field :location, class: 'form-control' %>
            </div>
            <div class="field form-group">
              <%= f.label :time %><br>
              <%= f.datetime_select :time, class: 'form-control' %>
            </div>
            <div class="field form-group">
              <%= f.label :event_name %><br>
              <%= f.text_field :event_name, class: 'form-control' %>
            </div>
            <div class="actions">
              <%= f.submit class: "btn btn-primary" %>
            </div>
          <% end %>
    
          <h3>All events</h3>
    
          <div class="panel panel-default" >
            <table class="table table-striped">
              <thead>
                <tr>
                  <th>Location</th>
                  <th>Time</th>
                  <th>Event name</th>
                  <th colspan="3"></th>
                </tr>
              </thead>
              <tbody>
                <%= render @events %>
              </tbody>
            </table>
          </div><!--panel-->
        </section>
        <br />
      </div><!--col-xs-5-->
    </div><!--container-->
    

    EDIT 1: Forgot to include my create.js.erb file:

    create.js.erb

    $('#events').append("<%= j render @event %>");
    

    EDIT 2: Here's what it looks like with either of the solutions below - each solution renders the index on to the calendar like you see in the picture below. enter image description here

    EDIT 3: Changed create.js.erb to the following. However, only the index_content part works.

    index_content = '<%= escape_javascript render(@events) %>'
    $('#events-section').html(index_content)
    
    calendar_content = '<%= escape_javascript render('calendar') %>'
    $('#calendar-section').html(calendar_content)
    

    Created new file app/views/events/_calendar.html.erb:

    <div class="simple-calendar">
      <%= link_to "Previous", start_date: date_range.first - 1.day  %>
      <%= I18n.t("date.month_names")[start_date.month] %> <%= start_date.year %>
      <%= link_to "Next", start_date: date_range.last + 1.day  %>
    
      <div class="panel panel-default">
      <table class="table table-striped">
        <thead>
          <tr>
            <% date_range.slice(0, 7).each do |day| %>
              <th><%= I18n.t("date.abbr_day_names")[day.wday] %></th>
            <% end %>
          </tr>
        </thead>
    
        <tbody id="calendar-section>
          <% date_range.each_slice(7) do |week| %>
            <tr>
              <% week.each do |day| %>
                <%= content_tag :td, class: calendar.td_classes_for(day) do %>
                  <% block.call day, sorted_events.fetch(day, []) %>
                <% end %>
              <% end %>
            </tr>
          <% end %>
        </tbody>
      </table>
      </div><!--panel-->
    </div>
    
  • Community
    • 1
    • 1
    eternal44
    • 85
    • 2
    • 10

    3 Answers3

    1

    In app views events create a new template and app/views/events/create.js.erb. And write the code something like

    content = '<%= escape_javascript render(@events) %>'
    $('tbody').fadeOut('slow').html(content).fadeIn('slow')
    
    usmanali
    • 2,028
    • 2
    • 27
    • 38
    • This was close - it actually rerendered the index onto the tbody of the calendar as well.. I should have added this but I originally had $('#events').append("<%= j render @event %>"); in that file. Any suggestions? – eternal44 Sep 16 '15 at 08:37
    1

    Let me help you to fix this. You have to do the following:

    events/index.html.erb

    Change your index.html.erb code in calendar section and add a new attribute id="calendar-section":

    <p id="notice"><%= notice %></p>
    
    <h1>Listing Events</h1>
    
    <div class="fluid-container">
      <div id="calendar-section" class="col-xs-7">
        <%= month_calendar attribute: :time, events: @events do |date, time_slots| %>
          <%= date.strftime("%m/%d") %>
    
          <% time_slots.each do |event| %>
            <div>
              <%= link_to event.event_name, event %>
            </div>
          <% end %>
        <% end %>
      </div><!--col-xs-7-->
      <div class="col-xs-5">
        <br />
    
        <p>
        <%= link_to "Toggle Events", "#", id: "events-link" %>
        </p>
    
        <section id="events-section">
          <%# <%= render 'form' %1> %>
          <%= form_for(@event, remote: true) do |f| %>
            <% if @event.errors.any? %>
              <div id="error_explanation">
                <h2><%= pluralize(@event.errors.count, "error") %> prohibited this event from being saved:</h2>
    
                <ul>
                  <% @event.errors.full_messages.each do |message| %>
                    <li><%= message %></li>
                  <% end %>
                </ul>
              </div>
            <% end %>
    
            <div class="form-group">
              <%= f.label :location %><br>
              <%= f.text_field :location, class: 'form-control' %>
            </div>
            <div class="field form-group">
              <%= f.label :time %><br>
              <%= f.datetime_select :time, class: 'form-control' %>
            </div>
            <div class="field form-group">
              <%= f.label :event_name %><br>
              <%= f.text_field :event_name, class: 'form-control' %>
            </div>
            <div class="actions">
              <%= f.submit class: "btn btn-primary" %>
            </div>
          <% end %>
    
          <h3>All events</h3>
    
          <div class="panel panel-default" >
            <table class="table table-striped">
              <thead>
                <tr>
                  <th>Location</th>
                  <th>Time</th>
                  <th>Event name</th>
                  <th colspan="3"></th>
                </tr>
              </thead>
              <tbody>
                <%= render @events %>
              </tbody>
            </table>
          </div><!--panel-->
        </section>
        <br />
      </div><!--col-xs-5-->
    </div><!--container-->
    

    events/_calendar.html.erb

    Create a new render partial file app/views/events/_calendar.html.erb. Remove locals variable @events into events. This example:

    <%= month_calendar attribute: :time, events: events do |date, time_slots| %>
      <%= date.strftime("%m/%d") %>
    
      <% time_slots.each do |event| %>
        <div>
            <%= link_to event.event_name, event %>
        </div>
      <% end %>
    <% end %>
    

    events/create.js.erb

    Create new file app/views/events/create.js.erb. Add locals variable @events

        $("#error_explanation > ul").html("")
    
        <% if @event.errors.any? %>
          <% @event.errors.full_messages.each do |message| %>
            $("#error_explanation > ul").append($("<li />").html("<%= message.html_safe %>"))
          <% end %>
        <% else %>
           $('tbody').html("<%= escape_javascript(render 'event') %>");
           $('#calendar-section').html("<%= escape_javascript(render(:partial => 'calendar', :locals => {:events => @events})) %>");
        <% end %>
    

    I hope can help you.

    akbarbin
    • 4,985
    • 1
    • 28
    • 31
    • Hey Muhamad - thanks for the help but it didn't make any changes - I still had to manually refresh the page. – eternal44 Sep 16 '15 at 08:41
    • Have you tried to change <%= escape_javascript(render 'event') %> into <%= escape_javascript(render(@events)) %> – akbarbin Sep 16 '15 at 09:02
    • I just tried it but it works like usmanali's solution - I get the tbody of the index rendered onto the calendar as well (pls see the added image I added to this post). – eternal44 Sep 16 '15 at 17:29
    • I tried this too and it didn't work. I think we're getting close with targeting the ID's but it looks like it'll take a bit more tweeking. – eternal44 Sep 18 '15 at 05:48
    • I'm sorry. I have to make `id="calendar-section"` outside of render file. I will updated. – akbarbin Sep 18 '15 at 06:29
    • I have updated my answer. In those changes, I tried to modify the local variable to be sent. Then, I have moved the `
      ` outside of calendar file.
      – akbarbin Sep 18 '15 at 07:10
    1

    You are trying to append the row into #events but in the html I can't see any element with id events.

    Possible solution: change

      <tbody>
        <%= render @events %>
      </tbody>
    

    with

      <tbody id="events">
        <%= render @events %>
      </tbody>
    
    Aguardientico
    • 7,641
    • 1
    • 33
    • 33