0

The user is filling out a form that's something like this:

Simplified version...

<%= form_for @email, url: email_path(@email) do |f| %>

<%= f.text_field :subject, class: "form-control" %>

<div class="tooltip-demo" style="margin-top:20px;margin-left:10px">
      <%= link_to "Preview", preview_email_path, class: "btn btn-sm btn-primary preview", remote: true %>
    </div>

<% end %>

In my emails controller, I have a method that looks like this:

def preview

    print "Email sent!"

    print params.to_json

    respond_to do |format|
      format.json { head :no_content }
      format.js { } 
    end
end

How do I pass the value in the textfield :subject to my preview method in order to validate?

This is how my route looks.. if it matters:

get :preview_email, to: "emails#preview"
Walker
  • 1,127
  • 15
  • 39
  • You can get the `subject` value in your params, it must be `params[:subject]`, what does `puts params` print when you send the form? – Sebastián Palma Jul 03 '17 at 15:43
  • I tried that and it doesn't work. This is the result `{"controller"=>"emails", "action"=>"preview"}` @SebastiánPalma – Walker Jul 03 '17 at 15:44
  • That's when you do it in your view, not in your method, try inspecting the params in the method which responds to the `email_path` route. – Sebastián Palma Jul 03 '17 at 15:45
  • I entered the puts params in the preview method in my controller.. not in my view. I'm also trying to pass the parameter like this `preview_email_path(:subject => params[:subject])` is this correct? Thank you – Walker Jul 03 '17 at 15:46
  • @SebastiánPalma He has a form and a link and he is not submitting the form, he is just clicking that link :) – Pavan Jul 03 '17 at 15:48
  • possibly you can try use request.parameters.merge <%= link_to "Preview", preview_email_path( request.parameters.merge({:email_subject => :subject}) ), class: "btn btn-sm btn-primary preview", remote: true %> – widjajayd Jul 03 '17 at 16:10
  • I see, my mistake, thanks @Pavan. – Sebastián Palma Jul 03 '17 at 16:28

2 Answers2

0

You are not using Rails form helpers that are who attach all the form information before submiting the form.

So one alternative is to remove your emails#preview action and leave only the email action.

Then in your form you can have multiple submit buttons, like this:

 <%= f.submit "Preview" 
 <%= f.submit "Submit"

Finally in your controller you can separate some logic just checking the param commit that will have the content Preview if the user has pressed the preview button or Submit otherwise.

epergo
  • 565
  • 5
  • 17
0

I don't know the way you can add an optional parameter to your route, set it in your link_to and then change it without using JS.

But I think you could try defining your route:

get '/preview_email', to: 'emails#preview', as: 'preview_email'

Then your controller, as you've do it:

def preview
  print "Email sent!"
  print params.to_json
  respond_to do |format|
    format.json { head :no_content }
    format.js { } 
  end
end

And I think the greatest change is in your view, when you can left out the remote: :true part in the link_to and the route definition, to get the subject from the form input and when the user clicks on the link "Preview" to make the AJAX request to the method through the email_preview path, so, this way you receive the subject, and you can do any validation you need:

There's no route, it's '', but an id to make it accessible for your JS script. So, you get the preview anchor, add a click listener, and when the user clicks it, then use preventDefault() to stop the normal functioning, then create a variable which gets the user input on the email[subject] input tag, and use fetch to make the request passing the subject variable value and catching the errors:

<script>
  document.getElementById('preview').addEventListener('click', function(e) {
    e.preventDefault()
    let subject = document.querySelector('input[name="email[subject]"]').value
    fetch(`/preview_email?subject=${subject}`)
    .catch(function(error) {
      console.log(error)
    })
  })
</script>
Sebastián Palma
  • 32,692
  • 6
  • 40
  • 59
  • Thanks for your help! I'm getting `Completed 401 Unauthorized in 0ms (ActiveRecord: 0.0ms)` when I do this. Maybe the get request is being sent without authorization? – Walker Jul 03 '17 at 16:49
  • Oh, in such case you'd need to add the needed values for authorization in the body of the request, like [here](https://stackoverflow.com/a/30204697/5025116) you can see how. – Sebastián Palma Jul 03 '17 at 16:52
  • edit: I've removed the preview from authorization required and it works good! Sebastian, is this the best way to do it? It seems like a work around but just making sure I'm writing good code. Thank you – Walker Jul 03 '17 at 16:52
  • I think is a possible way, because you can't set a value as parameter in your `link_to` taking it from an input tag, or even if you'd like to change it, you'd need some JS code. I can't say is the best, I don't know still how many more variants could exist. – Sebastián Palma Jul 03 '17 at 16:55
  • I think is a possible way, because you can't set a value as parameter in your `link_to` taking it from an input tag, or even if you'd like to change it, you'd need some JS code. I can't say is the best, I don't know still how many more variants could exist. – Sebastián Palma Jul 03 '17 at 16:55