Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: link_to with remote true and opening it in a new tab or window

I have a link which, when clicked, will make an AJAX call. This AJAX call will result in a modal showing up.

= link_to edit_evaluation_path(evaluation), remote: true

However, when trying to open a new tab from the link (by clicking it with the middle mouse button, for example) I've been getting a ActionController::UnknownFormat: ActionController::UnknownFormat error, because the action is not expecting to respond with a html format. Here's the respond_to code from the corresponding action:

respond_to do |format|
  format.js
end

How can I prevent the user from opening the link in another tab or window? Am I obliged to change the link_to to a button_to? Thanks!

like image 644
sauronnikko Avatar asked Jun 15 '14 07:06

sauronnikko


2 Answers

I've made created Javascript only solution for this problem in which I ran today.

$.each($("a[data-remote='true']"), function(i, val) {
  $(val).data("url", $(val).attr("href")).attr("href", "javascript:void(0);")
});

$.rails.href = function(el) {
  var $el = $(el);
  return $el.data('url') || $el.data('href') || $el.attr('href');
}

It will replace all data-remote links on the site directly

like image 123
Sumy Avatar answered Oct 16 '22 07:10

Sumy


I have devised a workaround for this. This comprises of two steps:

The jquery-ujs function that determines target url of a remote link can be overriden. So we override it to pick a data attribute before we check for href.

$.rails.href = function(el) {
    var $el = $(el);
    return $el.attr('data-url') || $el.attr('data-href') || $el.attr('href');
}

Next, We create a custom helper similar to link to that outputs the url in data attribute rather than href.

  def pseudo_link_to(name = nil, options = nil, html_options = nil, &block)
    html_options, options, name = options, name, block if block_given?
    options ||= {}

    html_options = convert_options_to_data_attributes(options, html_options)

    url = url_for(options)
    html_options["data-href".freeze] ||= url
    html_options['href'] = 'javascript:void(0)'
    content_tag("a".freeze, name || url, html_options, &block)
  end

Note that actual href is javascript:void(0) which is a javascript no-op.

Now, all you have to do is use pseudo_link_to helper in your rails views instead of link_to.

like image 37
lorefnon Avatar answered Oct 16 '22 05:10

lorefnon