I have a weird bug that hangs up or makes my app unusable or freezes for a minute.
So I have a 2 forms side by side one for billing and one for shipping and it has a drop down that uses the select2 library. When a user selects this drop down the Chrome autocomplete shows up too. It's overlapping the select2 dropdown. Here's an image:
So the problem here is when the user uses that drop down to select a country and uses the Chrome autofill instead of the select2 drop down and hits the enter key the form on the right fills the country and hangs up or freezes the app. Also when they choose a country or a state it will do a get request to the server.
What I tried are:
turn off the Chrome autocomplete on the settings; it works with no issues. The form on the right won't be updated (so I concluded it was Chrome)
I added an html: {autocomplete: 'off'} but this doesn't work, and I don't know why.
Here's the form:
<%= form_for [:admin, #corporate_account], html: { autocomplete: "off" } do |f| %>
<fieldset data-hook="new_property">
<div class="row">
<div class="col-md-12">
<%= render partial: 'form', locals: { f: f } %>
</div>
</div>
</div>
<div class="col-md-12">
<%= render partial: 'address_form', locals: { f: f } %>
</div>
</div>
<div class="form-actions">
<%= render partial: 'spree/admin/shared/new_resource_links' %>
</div>
</fieldset>
<% end %>
Update
I found that when I hit the enter with the Chrome autocomplete it sends a GET request, but with the regular drop down from the app it doesn't. I think Chrome's autocomplete after hitting the enter key it sends the form.
We are using select2 for our searches. It uses jQuery and ids are dynamically added. I found the script attaches the ID dynamically. It wasn't in the .js file, it was inside the .erb file. I've added this .js script inside the .erb file.
<% content_for :head do %>
<%= javascript_tag do %>
$(document).ready(function(){
$('span#<%= s_or_b %>country .select2').on('change', function() { update_state('<%= s_or_b %>'); });
<%# bellow this comment the code that I added %>
<%# this IDs are gnerated dynamically by select2 %>
const countryID = $('span#<%= s_or_b %>country .select2 .select2-search input').attr('id')
const stateID = $('span#<%= s_or_b %>state .select2 .select2-search input').attr('id')
<%# add the type attribute search so autocomplete can be toggled on and off %>
$(`#${countryID},#${stateID}`).attr('type', 'search')
<%# on focus set the autocomplete attribute off %>
$(`#${countryID},#${stateID}`).on('focus', function(){
$(`#${countryID},#${stateID}`).attr('autocomplete', 'off')
})
});
<% end %>
<% end %>
So when I focus on the search input, Chrome's autocomplete is not working any more.
Related
I have a Page model which has a body property in which the following in stored as example:
<h1>This is the HTML body</h1>
<p>and we want to use some rails code </p>
<%= Time.current.to_s %>
In my controller I get this page and render it simple in my view like this
-- rest omitted to keep it clear
<div class="card-body">
<%= #post.body.html_safe %>
</div>
How can I make the rails part <%= Time.current.to_s %> to render into displaying the date?
I am trying to create a todo app in which the checkbox is created using the simple form and this needs to be submitted remotely when the checkbox is clicked. I am using the onchange() function but the form isnt getting submitted remotely. It is submitting via a full page refresh.
When a submit button is included, it submits the form remotely and everything works fine. But i am not able to get it to work without the submit button but only using the check box.
_goal.html.erb
<li id='<%= "Goal_li_#{goal.id}" %>'>
<div class="collapsible-header" tabindex="0">
<label>
<%= simple_form_for(goal, url:goal_path(goal),remote: true,authenticity_token: true) do |f| %>
<%= f.check_box :is_complete,onchange: 'this.form.submit();', disabled:goal_disabled_class(goal), class: "check_box_check" %>
<span class=<%= "line-through-goal" if goal.is_complete==1 %>>
<%= goal.title %>-<%= goal.id %>-<%= goal.status %>
</span>
<%= "<span class='new badge blue right'> #{goal.sub_goals.where(is_complete: 0).count} </span>".html_safe if goal.sub_goals.where(is_complete: 0).count > 0 %>
<% end %>
</label>
</div>
</li>
This is leading to a page refresh instead of submitting the form remotely. All the examples i have found to be working are using the submit button. How can i trigger the remote execution on the basis of checkbox click?
Because of rails-ujs it is submitted via normal HTML request. Related issue and answer.
Try this way:
onchange: 'Rails.fire(this.form, "submit")'
I am building a website for a music database.
I would like to display categories like classical and hip hop first; when the user clicks on a category, I would like to display all the tracks names in that category (I would like to do this without a page refresh). I would also need to support pagination of this list displaying 10 items in one page (and I need to display buttons for display, edit, delete alongside each track in this list)
How can I accomplish this? Does bootstrap provide components that support this kind of implementation?
(If I could do this with a page refresh, I have done this before and I would know how to do it. But I am not sure how to do this without a page refresh)
On views/categories/index.html.erb:
<% #categories.each do |category| %>
<%= link_to category_path(category), :remote => true do %>
<%= category.name %>
<% end %>
<div class="category_<%= category.id %>">
</div>
<% end %>
Then create a partial views/categories/_show.html.erb (here you can insert a table or a structure with bootstrap row and columns):
<% #category.tracks.each do |track| %>
<%= track.name %>
... and you can add here delete and edit actions
<% end %>
Then create views/categories/show.js.erb:
$(".category_<%= #category.id %>").html("<%= escape_javascript(render("show")) %>");
Fyi what you are trying to do has nothing to do with bootstrap, unless you wanted for instance display tracks on a bootstrap modal.
Here is a poor man's bootstrap example I whipped up: when you click on the Track Category example, the table should expand. (You must have bootstrap v4 set up for this to work) and you must have a track_table partial as well - you can use the same partial for the two different tables that you want:
<div class="track-group">
<div class="track track-default">
<div class="track-heading">
<h4 class="track-title">
<p data-toggle="collapse" href="#collapse1"> Track Category (Click to Expand)</p>
</h4>
</div>
<div id="collapse1" class="track-collapse collapse">
<div class="track-body">
<%= render 'track-table' %>
</div>
<div class="track-footer">
</div>
</div>
</div>
</div>
Here's how it looks with an existing app on my computer:
I have a menu item that fires ajax that returns javascript partial that is a bootstrap modal. The problem I am having is when a user clicks the menu item the first time, the modal opens as expected. The user closes the modal and tries to open it again, it doesn't open (although the ajax fires again from backend).
Consider the following code (using bootstrap 4):
Menu.html.erb:
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownMenuLink">
<%= link_to user_profile_path(current_user.user_profile.id), remote: true, class: "dropdown-item" do %>
<%= fa_icon "id-card", text: "Profile Settings" %>
<% end %>
</div>
...
<div id="user_profile"></div>
user_profile/show.js.erb (ajax js partial):
$("#user_profile").replaceWith("<%= j render "user_profile" %>");
user_profile/_user_profile.html.erb (bootstrap modal):
<script>
$('#user_profile_modal').modal('show');
</script>
<%= form_with model: #user_profile do |f| %>
<div class="modal fade" id="user_profile_modal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document">
...
</div>
</div>
<% end %>
Is there a way to fire the the modal('show'); each time the modal is fired from the backend? By the way, this is just one of 3 modals that get loaded this way on the page.
Thanks again!
After trying a few things, simply replacing the replaceWith with html in the user_profile/show.js.erb will cause the ajax to fire each time.
Old:
$("#user_profile").replaceWith("<%= j render "user_profile" %>");
New:
$("#user_profile").html("<%= j render "user_profile" %>");
The reason for this is because the replaceWith is replacing the element in the parent, and thus not firing again because the element has already been replaced the first time.
Hope that helps anyone in the future!
Does anyone know a good guide or example for me to follow on how to change data on the screen using ajax?
I have a div that stores the last #event_status and every 5 minutes I want to go get the last event status created and display it in the div using ajax.
<div id="last_status">
Last Status:
<% if #event_status.present? %>
<span id="last_status_content">[<%= #event_status.user.initials %> # <%= #event_status.created_at.strftime("%I:%M%p") %>]<br />
Audio: <%= #event_status.audio ? 'Good' : 'None' %> |
Video: <%= #event_status.video ? 'Good' : 'None' %> |
<% if #event_status.notes.present? %>
Notes: <%= #event_status.notes %>
<% else %>
Notes: No Notes
<% end %>
</span>
<% else %>
<span id="last_status_content">None</span>
<% end %>
</div>
You can use javascript to periodically call an action and place the contents into a div. First extract the content of your last_status div to a partial, then return said partial from a controller action.
Javascript in your page:
$(document).ready(
function() {
setInterval(function() {
$('.last_status').load('/controller_name/action_name');
}, 36000);
}
);
Your controller action needs to then initialize all variables used by the partial, then render the partial.
def my_action
#event_status = get_latest_event
render :partial => 'my_partial'
end