0

I have a complex form page that saves records via AJAX without redirecting to the show page. Once the record is saved, there is a button that appears called Execute & Confirm.

Note:

  • save is really saving a draft, so it saves the record in the database until the user executes it.

  • execute is when the record is used in a rake task.

When clicking on the Execute & Confirm button, a modal appears in which I would like it to display the record that was just saved - asking the user if it is correct and to other execute or cancel.

I thought I would be able to use the instance variables in my controller's create method by using the show method in it but I get undefined method error for each attribute's method such as @campaign.program.name. I'm also suspicious that it's not being called since my flash[:success] does not appear when the record is saved via AJAX.

Here is the controller..

controllers/campaigns_controller.rb

class CampaignsController < ApplicationController

      def index
        @campaigns = Campaign.order("created_at DESC").page(params[:page]).per(7)
        @total_campaigns = Campaign.all
      end

      def new
        @campaign = Campaign.new
      end

      def create
        @campaign = Campaign.new(campaign_params)

        if @campaign.save

            zip = Uploadzip.find(params[:uploadzip_id])
            zip.campaign = @campaign
            zip.save

            flash[:success] = "Successfully saved a draft."
            respond_to format.js
            show
        else
            flash[:error] = "There was a problem saving your Campaign."
            redirect_to new_campaign_path
        end
      end

      def show
        @campaign = Campaign.includes(:program, :uploadzip, :plan, :uploadpdfs).find(params[:id])
      end

  private

      def campaign_params
        params.require(:campaign).permit(:name, :comment, :plan_id, :program_id, :campaign_id, uploadpdf_ids: [], channels: [])
      end
end

How do I display the newly saved record in the execute modal?

EDIT:

Note: I mistakenly thought my form was on the create page but realized is was actually the new. I tried adding the same functionality with the show method but still got the same undefined method errors.

views/campaigns/_form.html.erb

<%= form_for @campaign, url: {action: "create"}, remote: true, validate: true do |f| %>


  <div class="row full-width">
    <div class="large-6 columns camp-form-section">
        <h3 class="row">Campaign Attributes</h3>

            <div class="row">
                <div class="large-4 columns">
                    <label class="right-inline">
                        <%= f.label :campaign_name, "Campaign Name", class: "right-label" %>
                        </label>
                  </div>
                          <div class="large-8 columns">
                                <%= f.text_field :name %>
                          </div>
                </div>

        <div class="row">
            <div class="large-4 columns">
                <label class="right-inline">
                    <%= f.label :comments %>
                    </label>
                    </div>
                    <div class="large-8 columns">
                    <%= f.text_area :comment %>
            </div>
        </div>

        <div class="row">
            <div class="large-4 columns">
                <label class="right-inline">
                    <%= f.label :program %>
                    </label>
              </div>
                      <div class="large-8 columns">
                            <%= f.select :program_id, 
                                    Program.all.collect { |p| [ p.name, p.id ] }, { include_blank: true }, validate: { presence: true } %>
                      </div>
            </div>

    </div> <!-- large-6 -->


    <div class="large-6 columns camp-form-section">
      <h3 class="row">Campaign Content</h3>

        <div class="row">
            <div class="large-3 columns">
                <label class="right-inline">
                    <%= f.label :data_file, "Data File (.zip)", class: "right-label" %>
                    </label>
              </div>
                      <div class="large-9 columns">
                            <%= select_tag :uploadzip_id, 
                                    options_from_collection_for_select(
                                    Uploadzip.all, :id, :file_name
                                    ), { include_blank: "Include a Zip File" } %>
                      </div>
            </div>

        <div class="row">
            <div class="large-3 columns">
                <label class="right-inline">
                    <%= f.label :additional_files %>
                    </label>
                </div>

                        <div class= "large-9 columns">
                            <ul><%= f.collection_check_boxes :uploadpdf_ids, Uploadpdf.last(5).reverse, :id,
                                 :file_name, { mulitple: true } do |b| %>
                                     <li><%= b.label do %>
                                            <%= b.check_box + truncate(File.basename(b.text,'.*'), length: 45) %>
                                        <% end %>
                                <% end %>
                                    </li>
                            </ul>
                    </div>

        </div>
    </div>
  </div>


    <%= button_tag "Define Targeting", type: "button", id: "target-button" %>

    <%= render 'target', :f => f %>

    <div class="modalDarken"></div>

    <%= button_tag "Confirm & Execute", type: "button", id: "campaign-create-button", remote: true %>



<% end %>

views/campaigns/_target.html.erb

<div id="targetModal" class="row tiny " role="dialog">

  <div class="large-12 columns modal-header">
      <h3 class="row">Target</h3>
      </div>

        <div class="row">
            <div class="large-4 columns">
                <label class="right-inline">
                    <%= f.label :plan, "Pick a Plan", class: "right-label" %>
                </label>
            </div>


            <div class="large-8 columns">
                <%= f.select :plan_id,
                        Plan.all.collect { |p| 
                            [ p.name, p.id ] 
                            }, { include_blank: true } %>
            </div>




            <div class="large-4 columns">
                <label class="right-inline">
                    <%= f.label :channels, "Distribution Channel", class: "right-label" %>
                </label>
            </div>


            <div class="large-8 columns">
                <ul class="channels-list">
                    <% ["Folder", "Fax", "Email"].each do |channel| %>

                    <li><%= check_box_tag "campaign[channels][]", channel,
                            @campaign.channels.include?(channel), 
                            id: "campaign_channels_#{channel}", validate: true  %> <%= channel %></li>
                    <% end %>
                </ul>
            </div>
        </div>

      <%= f.submit "Done", class: "close-button", id: "done-button" %>
</div>




<div id="executeModal" class="row large " role="dialog">

  <div class="large-12 columns modal-header">
      <h3 class="row">Warning: Confirm Campaign</h3>
      </div>

      <div>
        <p>You are about to execute a campaign. Please confirm campaign settings one last time before executing.</p>
      </div>


        <div class="row">
        <table>
            <tbody>
                <tr>
                    <td>
                    Campaign Name:
                    </td>
                    <td>
                    <%= @campaign.name %>
                    </td>
                </tr>
                <tr>
                    <td>
                    Program:
                    </td>
                    <td>
                     <%#= @campaign.program.name %>
                    </td>
                </tr>
                <tr>
                    <td>
                    Zip File:
                    </td>
                    <td>
                    <%#= @campaign.uploadzip.file_name %> 
                    </td>
                </tr>
                <tr>
                    <td>
                    Additional Files:
                    </td>
                    <td>
                    <%# @campaign.uploadpdfs.each do |f| %>
                        <li><%#= f.file_name %></li>
                    <%# end %>
                    </td>
                </tr>
                <tr>
                    <td>
                    Plan:
                    </td>
                    <td>
                    <%#= @campaign.plan.name %> 
                    </td>
                </tr>
                <tr>
                    <td>
                    Channels:
                    </td>
                    <td>
                    <%#= @campaign.channels.to_sentence %>
                    </td>
                </tr>

            </tbody>
        </table>

        <button class="cancelButton">Cancel</button>
        <button>Execute Campaign</button>
        </div>
    </div>

</div>

views/campaigns/new.html.erb

<div class="row title">
    <div class="small-12 large-12 columns">
    <h2>Launch a Campaign</h2>
    </div>
</div>


<%= render 'form' %>

assets/javascripts/campaign_form.js

$(document).ready(function(){



$("form #target-button").click(function(e){
    e.preventDefault();
    $("#targetModal, .modalDarken").fadeIn();
});

$('.modalDarken, .cancelButton').click(function(e){
    e.preventDefault();
    $("#targetModal, #executeModal, .modalDarken").fadeOut();
    $("#campaign-create-button").hide();
    $("#target-button").css("display", "block");
});


    $(".close-button").click(function(e){
        e.preventDefault();

        var planId = $("#campaign_plan_id").val();
        var nameId = $("#campaign_name").val();
        var programId = $("#campaign_program_id").val();
        var uploadZip = $("#uploadzip_id").val();
        var uploadPdf = $("campaign[uploadpdf_ids][]").val();

        if (planId.length > 0 && 
            nameId.length > 0 && 
            programId.length > 0 && 
            uploadZip.length > 0){
            $('form#new_campaign').trigger('submit.rails');
            $("#targetModal, .modalDarken").fadeOut();
            $("#target-button").hide();
            $("#campaign-create-button").css("display", "block").css("background-color", "#E37368");
        } else {
            $("#targetModal, .modalDarken").fadeOut();

        }

    });

    //this is for showing the execute modal
    $("#campaign-create-button").click(function(e){
        e.preventDefault();
        $("#executeModal, .modalDarken").fadeIn();
    });

})
shroy
  • 918
  • 2
  • 10
  • 24
  • your `flash notice` is not working because flash notice doesn't work with ajax by default, look at this: http://stackoverflow.com/questions/366311/how-do-you-handle-rails-flash-with-ajax-requests – Santiago Suárez Jun 24 '15 at 19:09
  • also, can I see your index view, or wherever your ajax method is being called? also on your controller on the create you are not responding anything with js format, take a look at the controller part here: http://guides.rubyonrails.org/working_with_javascript_in_rails.html – Santiago Suárez Jun 24 '15 at 19:13
  • Can't you respond with a .js file instead and using Javascript add the record to the modal or add the flash error to the page? Whichever may occur. – pyRabbit Jun 24 '15 at 19:17
  • @SantiagoSuárez - Thank you for the response with the helpful links. This is my first time using JQuery and AJAX so I'm not too familiar with what's exactly needed. I'm using the simple `remote: true` functionality and some JQuery lines I found on SO to get the job done. I'll add the `respond_to format.js`. – shroy Jun 24 '15 at 19:36
  • @pyRabbit - I'm not too sure how to do that but I assumed Rails would make it fairly easy with the Ruby code already in the controller. However, this is new territory for me and javascript is my greatest weakness.. – shroy Jun 24 '15 at 19:38
  • Trust me, I am bad at Javascript too. However you can use a respond_to block and respond with a .js file... This would look for (as oddly as it sounds) a file inside your app/views/feature for a file called the create.js (assuming your submitting a request to the create action. – pyRabbit Jun 24 '15 at 19:45
  • 1
    Here you go... check this out http://codebeerstartups.com/2012/12/ajaxify-your-site-with-remote-true/ I guarantee this is the pattern you are looking for – pyRabbit Jun 24 '15 at 19:47

0 Answers0