Rails multi-dimensional array in JQuery Object Lit

2019-08-20 02:33发布

问题:

I am very new to JS & Jquery. I am building a scheduling app. I am storing appointments in a model called "Event". I am using a helper to build the multi-dimensional array from values in columns called "event.time_start" and "event.time_end" for a given day that a user might make an appointment. When a user picks a start_time and end_time from the dropdown menu, times that already have appointments will be grayed out/"disabled". I am using jquery.timepicker by http://jonthornton.github.io/jquery-timepicker/ with rails to blocks certain time values in a given array of time pairs ( [8am, 6pm], [1pm, 2pm]).
I am finding the "other" events on a given day (the ones that inform which times are taken) using the variable @other_events.

this is the helper that pairs the event.start_time and event.end_time
events_helper.erb

module EventsHelper

    def taken_times(other_events)
      other_events.map { |event| [event.time_start, event.time_end] }
      @taken_times = taken_times(other_events)
    end
end



I can get the array to work like this in the view:

<% taken_times(@other_events).each do |taken_time| %>
  <%= taken_time.first.strftime("%l:%M %P")%>
  <%= taken_time.last.strftime("%l:%M %P")%>,
 <% end %>

But I can't get it to work in the JS. I am now trying to use the Gon Gem What I need to out put to is this:

events/show.html.erb view

 <script>
     $('#jqueryExample .time').timepicker({
         'timeFormat': 'g:ia',
            'disableTimeRanges':   [
      // start dynamic array
    ['10:00am', '10:15am'],
    ['1:00pm', '2:15pm'],
    ['5:00pm', '5:15pm']
]
      //end dynamic array
     });
        $('#jqueryExample').datepair();
        </script>

so I've tried

application.html.erb

  <%= Gon::Base.render_data({}) %>

events_controller.erb

def show
 @event = Event.new
 @other_events = Event.where(date_id: params[:id])
 gon.taken_times = @taken_times
end

with the JS

 <script>
     $('#jqueryExample .time').timepicker({
         'timeFormat': 'g:ia',
            'disableTimeRanges':   [
      // start dynamic array
     gon.taken_times
      //end dynamic array
     });
        $('#jqueryExample').datepair();
        </script>

but this doesn't work. it just kills the dropdown function of the textfields. I'd love to know what these comma separated objects like "'timeFormat': 'g:ia'," and "disableTimeRanges: [....]" are called so I can better search SO for javascript answers. I am very new to JS & JQuery.

回答1:

Gon seems the right way to handle this but there are various errors in your code:

Where do you write <%= Gon::Base.render_data({}) %> ? It should be in the <head> tag, before any javascript code

Your event_helper.rb is wrong:

def taken_times(other_events)
  # Map returns a **copy**, if you don't assign it to anything, it's just lost
  other_events.map { |event| [event.time_start, event.time_end] }
  # This has **completely no sense**, this method will throw a stack level too deep error **every time you call it**, you should read a book about programming before trying to use rails
  @taken_times = taken_times(other_events)
end

If you want to use that, go for something like

def taken_times(other_events)
  other_events.map { |event| [event.time_start, event.time_end] }
end

The controller has the same problem of previous code

def show
 @event = Event.new
 @other_events = Event.where(date_id: params[:id])
 # @taken_times is not assigned, gon.taken_times will always be `null` in JS
 gon.taken_times = @taken_times
end

You should rewrite it like:

helper :taken_times
def show
 @event = Event.new
 @other_events = Event.where(date_id: params[:id])
 gon.taken_times = taken_times(@other_events)
end

And finally, you have a big syntax error in your javascript code, that's why everything disappear. Also you are using gon if it's something special. Gon just creates a plain javascript object, you can access it in javascript like you would do with anything else.

 <script>
     $('#jqueryExample .time').timepicker({
         'timeFormat': 'g:ia',
            // Here you have an opening square brackets, which is never closed
            // Also, there is no point in having a square brackets here or you'll have an array of array of array, while you want an array of array
            'disableTimeRanges':   [
      // start dynamic array
     gon.taken_times
      //end dynamic array
     });
        $('#jqueryExample').datepair();
        </script>

Which instead should be

 <script>
     $('#jqueryExample .time').timepicker({
         'timeFormat': 'g:ia',
            'disableTimeRanges': gon.taken_times
     });
        $('#jqueryExample').datepair();
        </script>

My main suggestion is, read a Ruby book first, not one with Ruby and Rails merged, you clearly need to improve your programming skills before doing anything. Start with something like The Well Grounded Rubyist and follow up with a good book about javascript (which I have yet to find, comments about it are well appreciated). Then go for Rails 4 in Action and at this point you probably understand better what's going on.

This is my recipe to become a good rails developer



回答2:

Big thanks to Fire-Dragon-Dol. I had to do a few more tweaks...I had to change the helper and add strftime to make it work. I also had to call the helper in a different way...In case anyone should like to see the working code:

module EventsHelper
def taken_times(other_events)
  other_events.map { |event| [event.time_start.strftime("%l:%M %P"), event.time_end.strftime("%l:%M %P")] }
end
end

events_controller.rb

include EventsHelper

def show
 @event = Event.new
 @other_events = Event.where(date_id: params[:id])
 gon.taken_times = taken_times(@other_events)
show

the view

  <script>
     $('#jqueryExample .time').timepicker({
         'timeFormat': 'g:ia',
    'disableTimeRanges':   
      // start dynamic array
    gon.taken_times
              // end dynamic array
 });
        $('#jqueryExample').datepair();
        </script>