How to run a specific AJAX call in Rails - ruby-on-rails

I am using has_scope to filer to filter jobs in a show.html.erb page. Once the jobs are filtered or not, the user can click on a job title and have the detail displayed on the same page on a partial. I have two functions in show.js.erb working, except that when the user clicks on the job title, the system run both call again and re-initialize the jobs selection. Can I isolate the second call so it does not run both functions ?
I have the two lines working well.
show.js.erb
$("#job_indiv").html("<%= j render partial: 'jobs/show', :locals => {:job => #job} %>");
(The above function display the individual details of the job)
$('#job_menu_left').html('<%= escape_javascript(render('menu_left')) %>')
(The above function filters the jobs list)
The view:
<div class="job_intro_display">
<%= form_tag job_path, method: 'get', id: "jobs_search" do %>
<div>
<% #industries = Job.all.distinct.pluck(:industry) - ["", nil] %>
Industry:<br>
<% #industries.each do |industry| %>
<div class="btn-filter">
<%= check_box_tag "by_industries[]", industry %> <%= industry %>
</div>
<% end %>
</div>
</div>
<div id="job_menu_left">
<%= render 'menu_left' %>
</div>
<div id="job_indiv">
<%= render 'jobs/show' %>
</div>
<script type="text/javascript">
$(function () {
$('input[type=checkbox]').change(function () {
$.get($('#jobs_search').attr('action'),
$('#jobs_search').serialize(), null, 'script');
return false;
});
$('#jobs_search').submit(function () {
$.get(this.action, $(this).serialize(), null, 'script');
return false;
});
});
</script>
Each ajax should be able to run separately.

Related

Rails Hotwire - How to search within existing form

I have form that has a section that displays a series of checkboxes for what groups a user manages. I want to add a search box at the top of the checkboxes that allows them to search a name and have it filter the results. From there they can check whatever ones they need to and submit the main form.
The only way I have ever done this is by triggering a from submission. It is not working (not doing anything) I assume because it is within another form. Is there a way to get this to work like I have it below, or is there a better way to set up this filter?
cardrequest form:
<%= form_with(model: cardrequest, id: dom_id(cardrequest), class: "contents") do |form| %>
form fields for cardrequest ...
<div class="mb-4 space-y-4">
<%= form_with url: search_cardrequests_path, method: :get, data: { controller: "search-form", search_form_target: "form", turbo_frame: "cgs" } do |c| %>
<div>
<label for="add-guests">Select Cardholder Groups</label>
<div class="relative">
<%= c.search_field :search, data: { action: "input->search-form#search" }, value: params[:search] %>
</div>
<% end %>
</div>
<div data-controller="checkbox-select-all">
<label>
<input type="checkbox" data-checkbox-select-all-target="checkboxAll" />
<span class="btn_primary_small">Select All / Deselect All</span>
</label>
<%= turbo_frame_tag "cgs" do %>
<div class="space-y-3">
<%= form.collection_check_boxes :cardholdergroup_ids, current_user.cardholdergroups, :id, :friendlyname do |g| %>
<div class="flex items-center mr-4">
<%= g.check_box data: { checkbox_select_all_target: 'checkbox' } %>
<%= g.label %>
</div>
<% end %>
</div>
<% end %>
</div>
<% end %>
Stimulus controller:
import { Controller } from "#hotwired/stimulus"
export default class extends Controller {
static targets = [ "form" ]
search() {
clearTimeout(this.timeout)
this.timeout = setTimeout(() => {
this.formTarget.requestSubmit()
}, 200)
}
}
cardrequests controller search method:
def search
cardholdergroups = current_user.cardholdergroups
#cardholdergroups = cardholdergroups.where("friendlyname LIKE ?", "%#{search}%") if params[:search].present?
render(partial: 'cgs', locals: { cardholdergroups: #cardholdergroups })
end
routes:
resources :cardrequests do
collection do
get 'search'
end
end

Starting owlCarousel in rails

I am new to rails and this is the first time I want to use a carousel in a web application. My carousel appears, but it does not auto-play.
This is what I have in my application.js :
//= require owl.carousel
$(function(){ $(document).foundation(); });
var owl = $('.owl-carousel');
owl.owlCarousel({
items:5,
loop:true,
margin:10,
autoplay:true,
autoplayTimeout:1000,
autoplayHoverPause:true
});
And this is from my view:
<div id="owl" class="owl-carousel">
<% #artists.each do |artist| %>
<div class="artist-card ">
<%= link_to artist, class: "poster" do %>
<%= image_tag artist.image.url(:thumb) %>
<% end %>
<div class="artist-info ell glassy-bg padmy padlx">
<div class="artist-card ">
<h6><%= artist.name %> <span>(<%= artist.instrument %>)</span></h6>
</div>
</div>
</div>
<% end %>
</div>
Is there also a way to display every artist from my database in the carousel? I've seen that the default number of items for the carousel is 5. Can I make it dynamic ?
I managed to solve the issue. Here is what I've done:
(function ($) {
$(document).ready(function() {
if ($('.carousel .owl-wrapper-outer').length === 0) {
var owl = $('.carousel').owlCarousel({
items:5,
loop:true,
margin:10,
autoPlay:1000,
autoplayHoverPause:true,
responsive: true,
responsiveRefreshRate : 200,
responsiveBaseWidth: window,
});
$('.carousel').hover(function() {
owl.trigger('owl.stop');
}, function(){
owl.trigger('owl.play', 1000);
});
}

How to use radio button to not send data to the server?

I am able with the radio button and a little javascript to toggle between the two categories, but even if one category is hidden it's data still sends.
challenge.rb
class Challenge < ActiveRecord::Base
scope :oneshot, -> { where(categories: 'One-Shot') }
scope :ongoing, -> { where(categories: 'Ongoing') }
_form
<%= form_for(#challenge) do |f| %>
<%= f.text_field :action %>
<% Challenge::CATEGORY.each do |c| %>
<%= label(c, c) %>:
<%= f.radio_button(:category, c, :class => "date-format-switcher", checked: (c=='One-Shot')) %>
<% end %>
<div id='id_of_first_div'>
<%= f.date_select :deadline %>
</div>
<div id='id_of_second_div'>
<%= f.date_select :date_started %>
</div>
<% end %>
<script>
$(function(){
$('#id_of_second_div').hide();
$('#challenge_category_one-shot').click(function(){
$('#id_of_first_div').show().attr('disabled', false);
$('#id_of_second_div').hide().attr('disabled', true);
});
$('#challenge_category_ongoing').click(function(){
$('#id_of_first_div').hide().attr('disabled', true);
$('#id_of_second_div').show().attr('disabled', false);
});
});
</script>
Radio Button HTML
<input class="date-format-switcher" type="radio" value="One-Shot" checked="checked" name="challenge[category]" id="challenge_category_one-shot" />
<input class="date-format-switcher" type="radio" value="Ongoing" name="challenge[category]" id="challenge_category_ongoing" />
Adapting Fiddle
<input id='a-selector' type='radio' name='selector' value='A' checked/> A
<input id='b-selector' type='radio' name='selector' value='B'/> B
<div id='details'>
<div id='for-a'>
<%= f.date_select :deadline, include_blank: true, selected: Date.current %>
</div>
<div id='for-b'>
<%= f.date_select :date_started, include_blank: true, selected: Date.current %>
</div>
</div>
<script>
var removed = $('#for-b').detach();
$('#a-selector').click(function() {
$('#details').append(removed);
removed = $('#for-b').detach();
})
$('#b-selector').click(function() {
$('#details').append(removed);
removed = $('#for-a').detach();
})
</script>
Setting a form element as disabled only disables user interaction with it; it doesn't remove it from the form's data (although your jQuery code is actually setting the div to disabled, which does nothing, but fixing that wouldn't help at all). What you want to do instead is clear the value of the date elements, e.g.,
<script>
$(function(){
$('#id_of_second_div').hide();
$('#challenge_category_one-shot').click(function(){
$('#id_of_first_div').show();
$('#id_of_second_div').hide();
$('#id_of_second_div select').value('')
});
$('#challenge_category_ongoing').click(function(){
$('#id_of_second_div').show();
$('#id_of_first_div').hide();
$('#id_of_first_div select').value('')
});
});
</script>
Though for that to work, you will need to add include_blank: true as an option to your date_select tags:
<%= f.date_select :deadline, include_blank: true %>
This will add the empty value as an option to your date selects, so that the above code can reset them to that empty value.
I'd also like to note -- all of this is just front-end logic, which any malevolent (or curious) user can circumvent. Your backend code (i.e., your controller) should handle discarding the fields you don't need based on your business logic, too.

form_for checkboxes only working on the first jquery-tab

I'm creating a form_for that basically lets the user mark when it has completed a video. I'm nesting this form inside a jQuery tabs and want to have one checkbox on each tab, and so far I got that. However the functionality is the one that is failing: Only the checkbox on the first tab actually changes the value when it is submitted. Any ideas on how to fix this?
<% for i in 1..#statement %>
<div id="htab-current-<%= i %>">
<%= form_for #user.workouts.where(week_num: #week).where(video_num_in_week: i).first.assignedworkouts.first, remote:true ,:html=>{:id=>'completed_form'} do |f| %>
<%= f.check_box :completed, :onclick => "$('#completed_form').submit()" %>
<% end %>
<div class='videowrapper2'>
<div id="myElement<%= i %>">Loading the player ...</div>
<script type="text/javascript">
jwplayer("myElement<%= i %>").setup({
skin: 'five',
width: "100%",
aspectratio: "4:3",
listbar: {
position: 'bottom',
},
playlist: '<%=asset_path(#user.workouts.where(week_num: #week).where(video_num_in_week: i).first.playlist_file ) %>'
});
</script>
</div>
</div>
EDIT: I tried brute forcing it and actually it was an issue of the id on the form being the same. However when I changed it to be generated dynamically even though the ids on the form and the jQuery call are the same, they don't seem to be working.
<% for i in 1..#statement %>
<div id="htab-current-<%= i %>">
<%= form_for #user.workouts.where(week_num: #week).where(video_num_in_week: i).first.assignedworkouts.first, remote:true ,:html=>{:id=>"#{i}completed_form'"} do |f| %>
<%= f.check_box :completed, :onclick => "$('#{i}completed_form').submit()" %>
<% end %>
<div class='videowrapper2'>
<div id="myElement<%= i %>">Loading the player ...</div>
<script type="text/javascript">
jwplayer("myElement<%= i %>").setup({
skin: 'five',
width: "100%",
aspectratio: "4:3",
listbar: {
position: 'bottom',
},
playlist: '<%=asset_path(#user.workouts.where(week_num: #week).where(video_num_in_week: i).first.playlist_file ) %>'
});
</script>
</div>
</div>
Try with:
<% for i in 1..#statement %>
<div id="htab-current-<%= i %>">
<%= form_for #user.workouts.where(week_num: #week).where(video_num_in_week: i).first.assignedworkouts.first, remote:true ,:html=>{:id=>'completed_form'} do |f| %>
<%= f.check_box :completed, :onclick => "$('#completed_form').submit()" %>
<div class="videowrapper2">
<div id="myElement<%= i %>">Loading the player ...</div>
<script type="text/javascript">
jwplayer("myElement<%= i %>").setup({
skin: 'five',
width: "100%",
aspectratio: "4:3",
listbar: {
position: 'bottom',
},
playlist: '<%=asset_path(#user.workouts.where(week_num: #week).where(video_num_in_week: i).first.playlist_file ) %>'
});
</script>
</div>
</div>
<% end %>

send a value from another field as a argument for ajax in rails

I have following code in a new.html.erb page.
<h3>Create Make Payment </h3>
<%= simple_form_for(#payment) do |f| %> <%= f.error_notification %> <div class="form-inputs">
<%= f.input :email, collection:#arr,:required=>true,:id=>"payment_email" ,:class=>"chosen-select"%> </div> <div class="form-inputs">
<%= f.hidden_field :user_id,:value=>User.find_by_email(ar).id,:id=>"user_id" %> </div> <div class="form-inputs">
<%= f.input :amount,:required=>true%> </div>
<div class="form-inputs">
<%= f.input :desc, as: :text ,:required=>true%> </div>
<div class="form-actions">
<%= f.button :submit %> </div> <% end %>
On chage in the payment_email select box I want a ajax request to take place. I have done the following.
Added respond_to do |format| format.js in the create action in payments controller.
I have written the following in a js file.
jQuery.ajaxSetup({
'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
})
jQuery.fn.submitWithAjax = function() {
this.onChange(function() {
$.post(this.action, $(this).serialize(), null, "script");
return false;
})
return this;
};
$(document).ready(function() {
$("#payment_email").submitWithAjax();
})
created a file called create.js.erb and entered the following in it.
$("#user_id").value("<%= escape_javascript(render(:partial => user_id)) %>");
I have created a partial _user_id.html.erb to print the value to be changed.
Now where I am stuck is that, I am not sure how to send the value of payment_email through ajax to create.js.erb where I will use it to get the required User id. How can I do this?
You can use jQuery Change event
$(document).ready(function() {
$( "#payment_email" ).change(function() {
$.ajax({
type: "POST",
url: "/controller/action",
data: { email: $( "#payment_email" ); }
});
});
});

Resources