问题
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>
来源:https://stackoverflow.com/questions/29303678/rails-multi-dimensional-array-in-jquery-object-literal-using-gon-gem