Question

So my website right now has a list of addresses with a drop down list of Locations. The Locations are indexed when being created, however it is changing their index when the Location gets updated. So Essentially the issue is say I want to change Location 1. Say I also have 6 Locations. When I press Update on Location 1 the Location instance moves to the end of the index(#6). I know where the issue is, but I'm not sure how to fix it.

My Show Page

.dropdown-panel
    .dropdown-info
      - if events.any?
        %a.button.dropdown{"data-dropdown" => "drop1"} Locations
      - else
        %a.button No Locations
      %ul#drop1.f-dropdown{"data-dropdown-content" => "", "data-tab" => ''}
        - events.each_with_index do |event, index|
          %li
            %a#dropDownNav{:href => "#panel1-#{index + 1}"} Location #{index + 1}
    .dropdown-add
      - if current_user
        %a.button#add_event{:href => "#new_event"} +
  .tabs-content
    - events.each_with_index do |event, index| <---I feel this is the issue(See Below)
      -if event.user_id == current_user.id
        .content{id: "panel1-#{index + 1}", class: index.zero? ? 'active' : ''}  
          = render 'form', event: event, index: index
    - if current_user
      .content{id: "new_event"}
        = render 'form'

I think the above has the issue under the .tabs-content. The each_with_index assigns a new index every time that list is reloaded. I can't figure out how to change it to only assign an index to the new events only.

I'm not sure if the _form.html.haml partial will help, but here it is...

.form-content
      - if current_user
        / - event.errors.each do |attr, msg|
        /   = msg
        = form_for event do |f|
          %fieldset.location-entry
            - title = f.object.new_record? ? "New Location" : "Location #{index + 1}"
            = f.hidden_field :date, value: date
            .alert-box.alert{"data-alert" => ""}
              An address is required
              %a.close{:href => "#"} &times;
            %h4= title
            - flash.each do |name, msg|
              = content_tag :div, msg, class: name
            .fields
              %dl
                %dt
                  = f.label :address, "Enter Location", :required => true
                %dd
                  = f.text_field :address, placeholder: 'Enter Address', class: 'address-input'
              %dl
                %dt
                  = f.label :start, "Enter Timeframe"
                %dd.time-entry
                  #timestart= f.time_select :start, { combined: true, minute_step: 15, ampm: true, :time_separator => ""}
                  .to
                    %p to
                  #time_end= f.time_select :end_time, { combined: true, minute_step: 15, ampm: true, :time_separator => ""}
            %dl.entry-submit
              - if !event.address
                = f.submit 'Enter Location', class: 'button', id: 'newevent'
              - if event.address
                = f.submit 'Update Location', class: 'button', id: 'updateevent', method: :put
                .remove-location
                  = link_to 'Remove Location', event, method: :delete,  data: { confirm: 'Are you sure?' }

Also let me know if this is a good job of explaining it or what I would need to add to make it better.

My Events Controller

class EventsController < ApplicationController
  before_action :verify_user_or_admin

  def update
    params[:event].parse_time_select! :start
      params[:event].parse_time_select! :end_time
    event = current_user.events.find(params[:id])
    respond_to do |format|
      if event.update(event_params)
        format.html { redirect_to event_path(event.start.to_date), notice: 'Event was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { redirect_to event_path(event.date), alert: 'There was an error creating your event.' }
        format.json { render json: event.errors, status: :unprocessable_entity }
      end
    end
  end

  def show
    if current_user
      @locations= current_user.events.where( "date(start) = ?", date).all
    elsif current_admin
      @locations = Event.where("date(start) = ?", date).all
    end
    @hash = Gmaps4rails.build_markers(@locations) do |location, marker|
      marker.lat(location.latitude)
      marker.lng(location.longitude)
      marker.infowindow render_to_string(:partial => "info", :locals => { :event => location })
      marker.picture({
        "url" => ActionController::Base.helpers.image_path('icon-marker-truck.gif'),
        "width" => 28,
        "height" => 40
      })
    end
  end

  def refresh
    render :partial => "welcome/info"
  end

  def new
  end

  def create
    params[:event].parse_time_select! :start
    params[:event].parse_time_select! :end_time
    event.attributes = event_params

    if event.save
      redirect_to event_path(event.start.to_date)
      flash[:notice] = "Event created successfully"
    else
      flash[:alert] = "There was an error creating your event"
      render :new
    end
  end

  def date
    @date ||= params[:id].present? ? Date.parse(params[:id]): Date.today
  rescue ArgumentError
    @date = Date.today
  end
  helper_method :date

  def days
    (date.beginning_of_week(:sunday)..date.end_of_week(:sunday))
  end
  helper_method :days

  def event
    if current_user
      @event ||= current_user.events.build(start: date, end_time: date)
    end
  end
  helper_method :event

  def events
    @events ||= current_user.events.for_day(date)
  end
  helper_method :events

def destroy
  event = current_user.events.find(params[:id])
  event.destroy
  redirect_to event_path(event.start.to_date), :notice => "Your event has been deleted"
end
  private
    def event_params
      params.require(:event).permit(:start, :end_time, :address, :date)
    end

end
Was it helpful?

Solution

Try with:

index = 0
events.each do |event|
  # ...
  index += 1 if event.new_record?
end

A bit too much procedural for my tastes, but it should do the job

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top