2

How can I remove the HTML from showing in collection_select such as the <\/option>\n, <\/select>, <\/div>');

This is the HTML output before javascript kicks in:

<select name="duel[duelers_attributes][1][challenge_id]" id="duel_duelers_attributes_1_challenge_id"><option value="29">Climb Mount Everst by May 20, 2017</option>
<option value="24">Run by Feb 20, 2017</option>
<option value="26">See Drive-thru Movie by Feb 20, 2017</option>
<option value="28">Run 5 Miles on Weekdays for 10 Days Starting Jan 20, 17</option>
<option value="25">Bungee Jump by Feb 20, 2017</option>
<option value="27">Journal on Weekdays for 10 Days Starting Jan 20, 17</option></select>

This is the HTML output after javascript kicks in:

<select name="duel[duelers_attributes][1][challenge_id]"
  id="duel_duelers_attributes_1_challenge_id">
  $("#dropdown-no-2").html(
    "\n <option value="\&quot;\&quot;">&lt;\/option&gt;\n</option>
        <option value="\&quot;24\&quot;">Run by Feb 20, 2017&lt;\/option&gt;\n</option>
        <option value="\&quot;25\&quot;">Bungee Jump by Feb 20, 2017&lt;\/option&gt;\n</option>
        <option value="\&quot;26\&quot;">See Drive-thru Movie by Feb 20, 2017&lt;\/option&gt;\n</option>
        <option value="\&quot;27\&quot;">Journal on Weekdays for 10 Days Starting Jan 20, 17&lt;\/option&gt;\n</option>
        <option value="\&quot;28\&quot;">Run 5 Miles on Weekdays for 10 Days Starting Jan 20, 17&lt;\/option&gt;\n</option>
        <option value="\&quot;29\&quot;">Climb Mount Everst by May 20, 2017&lt;\/option&gt;&lt;\/select&gt;\n&lt;\/div&gt;"
  )</option></select>

Somehow things seem to get progressively worse with more options??

enter image description here

_dueler_fields.html.erb

<%= f.select :user_id, options_for_select(@challengers.collect { |challenger| [challenger.id] }) %>

<%= f.select :challenge_id, options_for_select(@challenger_challenges.collect { |challenged| [challenged.full_challenge, challenged.id] }) %> ,

# The problem occurs only AFTER the javascript kicks in and replaces the above line with collection_select(:dueler...
<script>
$('#duel_duelers_attributes_1_user_id').change(function () {
    var user_id = $(this).find(":selected").val();
    var address = "<%= user_challenges_path %>/".concat(user_id);
    $.get(address, function(data) {
        $("#duel_duelers_attributes_1_challenge_id").html(data);
    });
});
</script>

routes

  get 'duels/user_challenges/:id', :to => 'duels#user_challenges', as: 'user_challenges'
  get 'duels/user_challenges/:id/:user_id', :to => 'duels#user_challenges', as: 'select'

user_challenges.js.erb

$('#dropdown-no-2').html('<%= j render partial: "user_challenges" %>') 

_user_challenges.html.erb

<%= collection_select(:dueler, :challenge_id, @challenges, :id, :full_challenge, include_blank: true, id: 'dropdown-no-2') %>

AJAX console output

$('#dropdown-no-2').html('<select name=\"dueler[challenge_id]\" id=\"dueler_challenge_id\"><option value=\"\"><\/option>\n<option value=\"24\">Run by Feb 20, 2017<\/option>\n<option value=\"25\">Bungee Jump by Feb 20, 2017<\/option>\n<option value=\"26\">See Drive-thru Movie by Feb 20, 2017<\/option>\n<option value=\"27\">Journal on Weekdays for 10 Days Starting Jan 20, 17<\/option>\n<option value=\"28\">Run 5 Miles on Weekdays for 10 Days Starting Jan 20, 17<\/option>\n<option value=\"29\">Climb Mount Everst by May 20, 2017<\/option><\/select>')

ADDITIONAL ELABORATION

The larger goal is that upon the current_user selecting a :user_id that the selected user's challenges should appear in the collection_select.

challenges_controller

def show
  @challengers = User.where(id: current_user.following_ids)
  if (params[:challenger_id]).present?
    @challenger = User.find(params[:challenger_id])
  else
    @challenger = User.find(10)
  end
  @challenger_challenges = @challenger.challenges
  @duel = Duel.new
  @duel.duelers << Dueler.new
end

duels_controller

def user_challenges
  @user = User.find(params[:user_id])
  @challenges = @user.challenges.order(:created_at)
end

def new
  @duel = Duel.new
end

duelers_controller

def new
  @dueler = dueler.new
end

duel.rb

class Duel < ActiveRecord::Base
  belongs_to :user
  belongs_to :challenge
  has_many :duelers
  accepts_nested_attributes_for :duelers, :reject_if => :all_blank, :allow_destroy => true #correct
end
Patru
  • 4,481
  • 2
  • 32
  • 42
AnthonyGalli.com
  • 2,796
  • 5
  • 31
  • 80
  • Usually, this shouldn't be there in the first place. i cannot see that the script causes this. Which collection_select has this issue? – KcUS_unico Feb 25 '17 at 11:44
  • `collection_select(:dueler` @KcUS_unico – AnthonyGalli.com Feb 25 '17 at 11:47
  • If I understand your comment properly then the problem will *only* occur after you trigger the JavaScript for the first time. This makes it highly likely that the problem lies with the JavaScript. Maybe you should post the relevant part of your HTML *before* and *after* the first call to your JavaScript. – Patru Feb 27 '17 at 12:18
  • Yea I'm guessing that is the root of the problem too. Just don't know how to fix it. Updated question with output @Patru – AnthonyGalli.com Feb 27 '17 at 12:42
  • Puuh Jeez, that "HTML output" *really* looks screwed. There seem to be increasing levels of double escaping going on. However, that would require some part of the JavaScript code to replace the `select` by something "approximately" the same. I am afraid I cannot quite see where that happens though, but that may have to do with my lack of knowledge about the intricacies of `jQuery`. Maybe it would be easier to judge the solution if you tried to tell us what you are trying to achieve? – Patru Mar 05 '17 at 03:13

6 Answers6

3

Well, it kinds of look like your html is not being parsed properly. Try using jQuery.parseHTML and then append it to the select input.

$.get(address, function(data) {
       var html = $.parseHTML( data );
       $("#duel_duelers_attributes_1_challenge_id").append(html);
});

Not tested, but give it a bash!!

Medard
  • 1,039
  • 10
  • 17
  • Unfortunately that stopped it from working altogether – AnthonyGalli.com Feb 27 '17 at 15:11
  • Sorry about that. Can you put a break point at html and check if the html has been parsed? – Medard Feb 28 '17 at 07:03
  • No worries I'm at your mercy. Been trying to figure this out for a while. Here is the HTML output of the challenges after switching users. As you can see the javascript did indeed still trigger, but it isn't being rendered in the browser because of some funky behavior and plus their is still the `option`s showing for it. – AnthonyGalli.com Feb 28 '17 at 07:43
  • Updated your question since it was too long to fit in comment. – AnthonyGalli.com Feb 28 '17 at 07:44
  • Can you show the value of data in the ajax response? – Medard Feb 28 '17 at 07:50
  • Sorry not sure how to do that? Do u mean like whats showing in the terminal or is there a line i should add to the script or am i suppose to see something pop up in chrome developer tools console? – AnthonyGalli.com Feb 28 '17 at 08:20
  • You should log data to console. Just add console.log(data) before $("#duel_duelers_attributes_1_challenge_id").html(data); – Medard Feb 28 '17 at 08:29
  • Okay did as requested. I added it to my question. – AnthonyGalli.com Feb 28 '17 at 10:51
  • I am not familiar with Ruby, why are you doing this $('#dropdown-no-2').html()? Why don't you just return '<%= j render partial: "user_challenges" %>' ? – Medard Feb 28 '17 at 11:04
  • I'm not entirely sure someone gave it to me a while back, but if you make your suggested change it doesn't work. I guess `#dropdown-no-2` needs to be signified – AnthonyGalli.com Feb 28 '17 at 11:14
3

Can you please try to remove name attribute & test once. Might be [](Square Brackets) are creating some problems.

Try like this

 <select id="duel_duelers_attributes_1_challenge_id"><option value="29">Climb Mount Everst by May 20, 2017</option>
<option value="24">Run by Feb 20, 2017</option>
<option value="26">See Drive-thru Movie by Feb 20, 2017</option>
<option value="28">Run 5 Miles on Weekdays for 10 Days Starting Jan 20, 17</option>
<option value="25">Bungee Jump by Feb 20, 2017</option>
<option value="27">Journal on Weekdays for 10 Days Starting Jan 20, 17</option></select>

Or

<select name="duel" id="duel_duelers_attributes_1_challenge_id"><option value="29">Climb Mount Everst by May 20, 2017</option>
<option value="24">Run by Feb 20, 2017</option>
<option value="26">See Drive-thru Movie by Feb 20, 2017</option>
<option value="28">Run 5 Miles on Weekdays for 10 Days Starting Jan 20, 17</option>
<option value="25">Bungee Jump by Feb 20, 2017</option>
<option value="27">Journal on Weekdays for 10 Days Starting Jan 20, 17</option></select>
Harjeet Singh
  • 388
  • 2
  • 6
  • 22
2

Ok. According to API I think your collection_select is not totally correct: http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/collection_select

Try:

<%= collection_select(:dueler, :challenge_id, Challenge.all, :id, :full_challenge %>

The first 'dueler' means that it is for the object / model dueler, than the method or attribute (challenge_id),than Challenge.all for collection OR @challenges if you have that in your controller action. :id is value, :full_challenge is label. If your full_challenge does not include this HTML as a string than it should also not show up.

I hope this helps, may be it is not the correct answer, but I tried to help you out . Let me know,..

KcUS_unico
  • 513
  • 3
  • 9
2

Ok, so I tried to wrap my head around this even if it is way too late to do so. I guess you are trying to exchange the options of a select from the change-listener of another one. A reasonably common task to do, so maybe you should look for a guide on how to achieve it.

However, checking on the jQuery documentation will give you that the .html(...) function will replace the inside HTML of some element(s) identified by your selector. You may check out this JSFiddle and verify your JavaScript-console to figure out that these are only your options, not the select itself.

To me it looks as if you are trying to replace the options of the challenge select through a misguided JavaScript request which will return some JavaScript escaped html! We are still lacking a lot of the code necessary to actually judge this though (namely your controller action). If that might be the case though, then your poor browser will most probably be confused when you are trying to replace the inside of your select with a piece of JavaScript escaped html which again defines a select (or at least tries to do so).

Without further checking any guides and to retain maximal flexibility I would suggest you have your request just return the options you want the challenger to be presented with in some JSON format. This will allow you to replace the options through your request in the change listener. If you insist on providing the html you should make sure to provide only the options and to ensure you undo all necessary escaping before passing it to .html(...).

Patru
  • 4,481
  • 2
  • 32
  • 42
  • Hey thanks so much for your comment and answer! I think you have the right train of thought. I don't know javascript well so my script code is a concoction of different answers I found on SO. I was so excited because I thought I solved it until I saw this weird option stuff :/ I updated the question with controller code and additional info if you wouldn't mind helping me bring this question to a resolution. If it is still confusing just let me know and I'd be happy to put a gist together :] – AnthonyGalli.com Mar 05 '17 at 08:58
  • There are a few questions on StackOverflow discussing how to achieve what you want. [The answer to this question](http://stackoverflow.com/questions/31612461/change-second-select-list-based-on-first-select-list-value-in-rails) uses JSON, however the generation of options is not completely spelled out. This could be achieved through pure jQuery as in [this question](http://stackoverflow.com/questions/1801499/how-to-change-options-of-select-with-jquery). – Patru Mar 05 '17 at 16:34
  • A pretty "railsy" way pretty close to yours is presented in [this blogpost](https://kernelgarden.wordpress.com/2014/02/26/dynamic-select-boxes-in-rails-4/). However observe that the partial rendered in this post will *only* provide the options, not the `select`. – Patru Mar 05 '17 at 16:35
2

user_challenges.js.erb: $('#dropdown-no-2').html('<%= render partial: "user_challenges" %>')

or in other words remove the 'j' function which escapes html tags.

M. Stavnycha
  • 433
  • 3
  • 9
  • I only wish it was that easy. Didn't work, but thanks for trying. Upon selecting a new user, with your change, the `collection_select` didn't update. – AnthonyGalli.com Mar 05 '17 at 12:53
2

I suggest you to go for a regex replace like this on the html element.

var text=$('#duel_duelers_attributes_1_challenge_id').html();
text=text.replace(/(\\n|&lt;(.)*&gt;|\\&quot;|\"\n.*\))/g,''); 
text=text.replace(/\$[^<]*/,''); 
text=text.replace(/(\n)/g,'').replace(/\\\"/g,'"').replace(/\"\)/,'').replace(/\\\//g,'/'); 
$('#duel_duelers_attributes_1_challenge_id').html(text);

console.log(text);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select name="duel[duelers_attributes][1][challenge_id]"
  id="duel_duelers_attributes_1_challenge_id">
  $("#dropdown-no-2").html(
    "\n <option value="\&quot;\&quot;">&lt;\/option&gt;\n</option>
        <option value="\&quot;24\&quot;">Run by Feb 20, 2017&lt;\/option&gt;\n</option>
        <option value="\&quot;25\&quot;">Bungee Jump by Feb 20, 2017&lt;\/option&gt;\n</option>
        <option value="\&quot;26\&quot;">See Drive-thru Movie by Feb 20, 2017&lt;\/option&gt;\n</option>
        <option value="\&quot;27\&quot;">Journal on Weekdays for 10 Days Starting Jan 20, 17&lt;\/option&gt;\n</option>
        <option value="\&quot;28\&quot;">Run 5 Miles on Weekdays for 10 Days Starting Jan 20, 17&lt;\/option&gt;\n</option>
        <option value="\&quot;29\&quot;">Climb Mount Everst by May 20, 2017&lt;\/option&gt;&lt;\/select&gt;\n&lt;\/div&gt;"
  )</option></select>
Sagar V
  • 12,158
  • 7
  • 41
  • 68