Unknown token in URL in rails - ruby-on-rails

Whenever I submit a form rails append a unknown fragment in params in the url. But what is the purpose of that fragment ? and how I can get rid of it? Please refer to following sample URL.
By token I am referring to "#.U3Mw4XKHbFY" in the following URL
Here is URL sample
www.domain.com/posts?utf8=%E2%9C%93&query=surf&area=All+Area#.U3Mw4XKHbFY
<%= form_tag posts_path, method: 'get', class: "search_keywords_form" do %>
<%= text_field_tag :query, nil, class: "search-field", placeholder: "Search Item for swap" %>
<%= hidden_field_tag 'area', "All Area" %>
<input type="submit" class="search-btn" value="" />
<div class="clearfix"></div>
<div class="push"></div>
<% end %>
Another strange thing is when I review the params, I don't get it there. But when page get reloaded That unknown attribute get appended.
params = { "utf8"=>"✓",
"query"=>"surf",
"area"=>"All Area",
"action"=>"index",
"controller"=>"posts"
}

I also had to face this problem, this is definitely JS problem might be some plugin would be appending this.
Simple solution for this is just put location.hash = "" in your js file on document ready. And yes i remembered, this fragment is appended when you use some tracking system. Like google analytics or Addthis

What are you talking about is the fragment part of an URI. The fragment part of the URI refers to some part of the HTML content response, and it is processed only client side: that's why you don't - and you can't - see or process it server side.
The fragment appears because it is present somewhere in the HTML form, or because some client side code (aka JavaScript) sets it to the form URL.
I have the feeling I have already seen that fragment pattern somewhere, but I don't remember where...

Related

Form responses must redirect to another location with link_to

I am using rails 6.1.x with hotwire-rails
I was wondering if you have ever experienced the following:
I have a page where I have link_to like this:
<%= link_to client_luser_courses_path,
{
method: :get,
class: "btn btn-primary text-center float-right",
data: {turbo: false}
} do %>
<i class="fa fa-arrow-right" aria-hidden="true"></i>Get the files:
<% end %>
On the top of the page, I enable turbo with:
<%= javascript_pack_tag 'client', 'data-turbo-track': 'reload' %>
Now, if i click the link, I get the error:
"Error: Form responses must redirect to another location" in Firefox console
and nothing happens.
If I remove the "method: :get" part, then it works fine.
<%= link_to client_luser_courses_path,
{
class: "btn btn-primary text-center float-right",
data: {turbo: false}
} do %>
<i class="fa fa-arrow-right" aria-hidden="true"></i>Get the files:
<% end %>
Do you know why this is happening? It's really puzzling.
Just to flesh out information from the comments, especially since there seems to be a lot of confusion around links in Hotwire/Turbo:
If you wish for a link to have "default" behavior (meaning it takes to you a new page / a full page reload), OP is correct to have data: { turbo: false } declared on the link.
Commenter max is correct that adding method: :get is not necessary to make the link behave this way. It's important to note, however, that the reason for the failure is that adding a method parameter actually makes the link send a POST request, with a hidden input with name "_method", and value "get". See link_to in the Rails API docs.
The error message OP sees is actually a Turbo error. It's unclear if this is a bug or not, since Turbo should be deactivated. It should be the case that the network request is succeeding, but not redirecting because Turbo has taken over. The reason the failure ultimately occurs is because Turbo is (mistakenly?) handling the request, and expecting a 30x redirect, but no redirect is happening. This is why the failure ultimately occurs. If you open up your network inspector in DevTools, you'll see a 200 request with a preview of the page you're linking to.
TLDR: Adding method: :get makes the link send a POST request, which is probably why Turbo is taking over even though OP put in data: { turbo: false }.

Rails Passing param from form to persist sorting order

I trying to pass a hidden param in my form that maintains the sort order of my list. I am able to pass the query param without a problem but cannot seem to pass in a custom param to the controller. I am not sure how to do this correctly and have tried using f. hidden_param with no success.
The form is hooked up to stimulus reflex and submits with every key press.
Any help would be appreciated.
<%= form_with url: x_path, method: :get do |f| %>
<%= f.text_field :query, value: params[:query] %>
<% end %>
Just try this .....
<%= f.hidden_field :sort, value: your_value_asc_or_desc %>
Hope it will work for you.
You don't even need a form in the first place and you can't actually pass "hidden parameters" in a GET request as there is no request body.
In GET the only thing the server recieves is the request URI and any headers sent by the client (such as cookies). If you want to add parameters to a GET request just add them to the query string:
<%= link_to 'Link text', x_path(query: { foo: 'bar' }) %>
The result is identical to if you created a form with hidden inputs. On the controller side there is difference between request body and query string parameters. Both are added to the params hash.

rails Initialize new object through associated search

In my rails application I would like to be able to search for a client from the nav bar and have it automatically provide the WorkOrderController with the associated client. The goal is to automatically generate some of the work order information before the user gets to the new view. I was hoping to do this by making the new work order path nested under clients, but I'm not sure where to turn the form submission into a find to return the client for use in the work order controller. Clearly I am missing a method somewhere, but I'm not sure where to put it and what exactly it is I need it to do.
As far as I can tell what I need to do is somehow have the form submit to some method, which would then redirect to the new work order page with the :client_id in the params.
Am I totally off base here or am I missing something relatively small? An hour and a half of searching didn't turn up much as most guides talk about the form_for functionality. This doesn't appear to be a full on search either.
#routes.rb
....
resources :client do
get 'schedule', to: 'work_order#client_schedule'
get 'archive', to: 'work_order#client_archive'
resources :work_order, only: [:new]
end
.....
#application.html.erb
.....
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter client number">
</div>
<button type="sumbit" class="btn btn-default">New Work Order</button>
</form>
.....
#WorkOrderController.rb
....
def new
client = Client.find(params[:client_id])
#workorder = WorkOrder.new(client: client)
end
....
EDIT:
I made the following change and now when I attempt to load the page I get an error saying I am missing the client_id parameter, though I thought that is what I'm looking for in the first place
<%= form_tag new_client_work_order_path, :method => "get", class: "navbar-form navbar-left" do %>
<div class="form-group">
<%= text_field_tag :search, params[:search], class: "form-control", placeholder: "Enter client number"%>
</div>
<button type="sumbit" class="btn btn-default">New Work Order</button>
<% end %>
EDIT 2:
Was able to achieve my desired result by doing the following:
In work_order_controller.rb
....
def new
client = Client.find_by(clientnumber: params[:client_number])
#workorder = WorkOrder.new(client: client)
end
....
I switched the routes so that the new route was not nested under client and then changed the form to be:
<%= form_tag new_work_order_path, :method => "get", class: "navbar-form navbar-left" do %>
<div class="form-group">
<%= text_field_tag :client_number, params[:client_number], class: "form-control", placeholder: "Enter client number"%>
</div>
<button type="sumbit" class="btn btn-default">New Work Order</button>
<% end %>
I get the impression that I've created some other problem I don't yet see though, but I could just be paranoid
Scanning your code quickly, I don't see anything missing and while there's a number of ways to get this done, I think you're on the (a) right track.
Building things like this in Rails involves getting quite a number of components all working together at the same time, so in this case I'd focus on each step in turn (chronologically) to verify that it works as expected. Specifically I'd:
Watch the Rails console when I click that "New Work Order" button to verify that the client_id parameter is "seen" by the controller. (On closer inspection, according to your HTML, I don't see how this form would pass this parameter... or how the form would submit in the first place. Where's the form's action attribute?)
Use puts statements in the controller #new action to verify that the client object is initialized properly and that #workorder.client_id is the expected value.
Add output to the #new view template that prints out the #workorder.client_id to verify that the ID is carried over to the view. I don't see this view template in the above code snippets so I don't know what you expect to show up.
And so forth. Just breaking the problem into smaller steps so they're easier to figure out what's happening. Good luck!

How to add data-attribute to the form tag in simple_form?

I'm using garlic.js to validate my forms. Garlic.js recommends adding a data-attribute on the form tag.
Here's what I need to generate:
<form data-validate="parsley">
I'm having issues to generate this data attribute on the form tag. I tried everything and nothing worked. Anyone has a solution to this?
Try this:
<%= simple_form_for #entity, :html => {:"data-validate" => 'parsley'} do |f| %>
<!-- inputs -->
<% end %>
Update
From the comment below, to have the form include an HTML5 data attribute with no value try the following:
<%= simple_form_for #entity, :html => {:"other-data-value" => ''} do |f| %>
By setting the attribute to an empty string the form helper renders just the attribute.
You can set data attributes directly by passing in a data hash, but all other HTML options must be wrapped in the HTML key. Example:
<%= form_for(#post, data: { validate: "parsley" }, html: { name: "go" }) do |f| %>
...
<% end %>
The HTML generated for this would be:
<form action='http://www.example.com' method='post' data-validate='parsley' name='go'>
...
</form>
api.rubyonrails.org
For anyone stumbling across this in 2016 using either the newer version of Rails (4) or the newer version of Parsley (2) here is what you'll need to do:
First of all to activate parsley with data attributes in the new version you add data-parsley-validate now instead of the data-validate="parsley" from version 1 of Parsley. Now lets get that to work with rails form_for.
Even if you're not using parsley, this is how to insert a data attribute in Rails 4.
<%= form_tag '/login', :"data-parsley-validate" => '' do %>
<!-- inputs -->
<% end %>
So basically the difference is not using the html=>{} hash. I tried that to see if that trick would work and at least for me my markup looked like this:
<form action="/login" method="post" html="{:data-parsley-validate}">
<!-- inputs -->
</form>
But by simply putting the data attribute directly in there as a symbol with an empty string as the corresponding value and it worked perfectly. This is the markup I received.
<form action="/login" method="post" data-parsley-validate>
<!-- inputs -->
</form>
In other words its perfect. So thats how to use Rails 4 to get data attributes in your form_tag.

What should I do to accomplish this feature?

So I have a form that is for adding topics (tags) to videos:
<%= form_for #video, :url => {:action => "update"}, :remote => true do |f| %>
<div class="field">
<%= f.text_field :topic_names, :class => "topic_field" %>
</div>
<%= f.submit "Add Topic" %>
<% end %>
However, I want the form to initially not be there and appear only after a user clicks a link. Initially I wanted to load in the form from a different file with jQuery with this code:
$("#edit_topics_link").click(function(e){
e.preventDefault();
$(".topic_form").load("topic_form.html.erb");
$("#edit_topics_link").hide();
});
The problem with this is that the second I remove the form from its original view, I get this JS error: Uncaught TypeError: Cannot set property '_renderItem' of undefined
I think this might have something to do with the fact that the form is handled with an AJAX request since I pass the :remote => true option to it.
Anyway, because of this error, I'm thinking of just keeping the form in the view and hiding it, and then showing it when the user clicks the link. Is this a bad idea? If I should be loading in the form, how can I prevent that JS error?
I would go with loading it and keeping it hidden when the page loads and then show it when they click. The form will show faster than doing another request to the server, and what does it really cost you by adding it to pages where a user may not show it? probably a millisecond worth of view load and a millisecond of http data transfer?
Although I think this is a better approach its worth noting that your error is probably resulting form this:
$(".topic_form").load("topic_form.html.erb");
You should be calling a controller/action inside the load. Jquery load makes a request to the server, and it will be calling this URL: http://yoursite.com/topic_form.html.erb. I am assuming that routes does not exist. You need to render this form from your controller action.

Resources