After the form is submitted, attach a div containing the saved record

Once the form is submitted, I'd like to seamlessly add the newly saved record to my existing div that holds all the records. If there's a better method for accomplishing this, please let me know.

I'm unsure of the correct approach to achieve this, so the code in my create.js.erb file is purely speculative at this point.

The Form

<%= form_for @comment, remote: "true" do |f| %>
  <%= f.hidden_field :chat_id, value: @chat.id %>
  <%= f.text_area :content %>
  <%= f.submit "Send" %>
<% end %>

The Controller

def create
  @comment = Comment.new(creation_params)
  @comment.user_id = current_user.id

  if @comment.save
    respond_to do |format|
     format.js
     format.html
    end
  else
    redirect_to root_path
  end
end

The create.js.erb File

$("#comments").append("<%= @chat.comments.last %>");
$('#comment_content').val('').focus();

The Comments Section

<ul id="comments">
<% @chat.comments.each do |comment| %>
  <li id="comment-<%= comment.id %>">
    <%= comment.user.name %>
    <%= comment.content %>
  </li>
<% end %>
</ul>

Answer №1

Upon initial review, I see a couple of areas that could benefit from some adjustments. While I am relatively new to this myself, I have had experience using Ajax with Rails in the past. Hopefully, my suggestions will be of assistance.

Form

Suggest replacing the string "true" with the boolean true within remote: "true".

<%= form_for @comment, remote: true do |f| %>
  <%= f.hidden_field :chat_id, value: @chat.id %>
  <%= f.text_area :content %>
  <%= f.submit "Send" %>
<% end %>

Controller

It is recommended to add

{render layout: false, content_type: 'text/javascript'}
after format.js. Additionally, ensure you define @chat in your create action if it's used in create.js.erb.

def create
  @comment = Comment.new(creation_params)
  @comment.user_id = current_user.id
  @chat = # however you can define your @chat variable, if you decide you need it

  if @comment.save
    respond_to do |format|
      format.js {render layout: false, content_type: 'text/javascript'}
      format.html
    end
  else
    redirect_to root_path
  end
end

create.js.erb

To maintain consistency, consider utilizing tags for formatting new comments with HTML like previous ones. Avoid appending the entire Ruby object by using @comment instead of @chat.comments.last. This way, only the comment's content and creator's name are appended, ensuring a smooth functioning JS file.

var markup = '<li id="comment-<%= @comment.id %>"><%= @comment.user.name %><%= @comment.content %></li>';
$("#comments").append(markup);
$('#comment_content').val('').focus();

Comments div

This section seems satisfactory as it stands.

<ul id="comments">
  <% @chat.comments.each do |comment| %>
    <li id="comment-<%= comment.id %>">
      <%= comment.user.name %>
      <%= comment.content %>
    </li>
  <% end %>
</ul>

Answer №2

Your initial attempt seems to be on the right track overall. Personally, when tackling this issue (which I frequently do as I use ajax heavily in Rails), I prefer to address and troubleshoot each issue separately whenever possible. Here's how I usually tackle it:

  • First, I check if the controller action is being called and running correctly by sprinkling some puts statements in the code and monitoring the console output for verification.
  • Next, I ensure that the controller is rendering what I expect by using Chrome's developer tools and checking the Network tab to view AJAX request details, response codes, and load times, allowing me to inspect the JavaScript sent back to the browser thoroughly.
  • Finally, I confirm that the JavaScript is executing as intended by adding an alert("Done!"); at the end of the create.js.erb snippet.

Looking at your specific code, I'm curious about the string being appended to #comments. The jQuery command is:

$("#comments").append("<%= @chat.comments.last %>");

However, I believe you might need to append content with full HTML markup instead of plain text. It may look more like this for better readability (broken into 2 steps):

var markup = '<li><%= @chat.comments.last %></li>';
$('#comments').append(markup);

Furthermore, my personal approach to AJAX in Rails involves mostly disregarding Rails' built-in AJAX features and UJS. Instead, I opt to write custom jQuery code (precompiled within the asset pipeline) to handle click events, send AJAX requests, provide feedback on changes, and manage other functionalities. This keeps all my JavaScript neatly organized in /app/assets, rather than scattered throughout the view folders. Additionally, my controllers typically return JSON or sometimes a rendered HTML partial instead of injecting additional JavaScript snippets after page load. This method feels cleaner and gives me greater control over the page behavior.

Of course, one drawback is that I sacrifice Rails' UJS support with this approach; any functionalities implemented this way will not gracefully degrade if the browser lacks JavaScript support.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Executing two Ajax calls sequentially without using asynchronous functionality

Creating a dynamic menu using two REST APIs to establish a parent/child relationship. The ID of the parent from the first API response is passed to the child API to fetch child records. Encountering issues where setting async false for the child API call ...

Adding additional `select` dynamically causes the value to disappear from view

After attempting to replicate the functionality of the select field, I encountered an issue where it no longer displays any values. Specifically, if I opt for a small size, I encounter this error message in the console. https://i.stack.imgur.com/5hKX6.png ...

Error message: Unauthorized request error with the change.org JavaScript API

I am currently working on integrating the javascript API from change.org in order to retrieve all of my signed petitions for display on my source forge page. However, I am encountering an unauthorized request response from the change.org API. Despite tryi ...

Laravel validation successfully validates Vanilla AJAX request, but the controller does not receive the values

Currently, I am utilizing AJAX (vanilla JS) to send a form to a Laravel 5.5 controller for searching the Amazon products API. The AJAX is sending the correct keywords and category inputs, but the controller is not receiving them. Even though the request p ...

The method this.$el.querySelector does not exist

The data retrieved from the database is inserted into the input fields and submitted as a form. This data is an object that passes the value to the database. However, when I trigger this form, an error occurs. See example of the error <input id=" ...

Utilize data binding in Typescript to easily link variables between a service and controller for seamless utilization

Is there a way to overcome the issue of value assignment not binding data in this scenario? For example, using this.arrayVal = someService.arrayVal does not work as intended. The objective is to simplify the assignment in both HTML and controller by using ...

What are some ways to lazily load directives in AngularJS?

Currently, I am exploring the capabilities of angularjs and aiming to dynamically load directives only when they are required instead of loading all of them initially on the page. My focus is on creating custom directives for the plugins that I use frequen ...

Encountering an Unexpected Token Error While Parsing JSON with jQuery

Utilizing the Envato API with jQuery to collect user stats is my current project. An example JSON response that I will display is as follows: { "new-files-from-user":[ { "thumbnail":"http://3.s3.envato.com/files/60560.jpg", "tags":"", "use ...

What is the best way to transform a JSON data-storing object into an array within Angular?

I am currently working on developing a machine learning model using tensorflow.js, but I have encountered a roadblock. The issue I am facing is that I have stored my JSON content in a local object, but for it to be usable in a machine learning model, I ne ...

Using regular expressions, you can eliminate a specific segment of a string and substitute

Provide a string in the following format: lastname/firstname/_/country/postalCode/_/regionId/city/addressFirst/addressSecond/_/phone I am creating a function that will extract the specified address parts and remove any extra parts while maintaining maxim ...

What could be the reason for my React/HTML select element occasionally failing to display the default selected value?

I am currently working on creating a select element in Reactjs/HTML and I am facing an issue with setting a default value based on a component variable. Essentially, the default value of the select should be the id of a component. This is my current imple ...

Display alert only when focus is lost (on blur) and a dropdown selection was not made

Utilizing Google Maps Places for autocompletion of my input, I am aiming to nudge the user towards selecting an address from the provided dropdowns in order to work with the chosen place. A challenge arises when considering enabling users to input address ...

Angular's ngRoute is causing a redirect to a malformed URL

Currently, I am in the process of developing a single-page application using AngularJS along with NodeJS and Express to serve as both the API and web server. While testing locally, everything was working perfectly fine. However, after cloning the repositor ...

I can only use innerHTML once in my React application

I am attempting to clear my container div when the user clicks the search button in order to remove all existing search results. However, I am encountering an issue where using innerHTML to clear the container div only works the first time. If a second sea ...

Tips for adding a new property to an array object in TypeScript using a condition

Here is an array object that I have: arr = [ { Name: "ABC", Age: 20}, { Name: "XXX", Age: 15} ]; In Typescript, I am looking to dynamically add a new property called "Flag" with a value of 1 only if the Age is greater than 15. Can someone suggest ...

Why won't the button's color change when I try clicking on it?

I am currently learning vue and facing some challenges. The code I have is supposed to change the button color when clicked, but it's not working as expected. Any advice on how to fix this issue would be greatly appreciated. Thank you! let app = ...

Creating a single page application in Angular2+ using JSON data

I am looking to create an Angular JS application using the provided JSON structure: { name: 'App Name', pages: [ { name: 'Home', url: '/', layout: { type:'HTMLElement' tag:'div ...

challenges surrounding the use of getElementByTagName

Within my webpage, I have implemented two select elements, both containing multiple options. However, I am facing an issue where I can only access the options from the first select box using getElementByTagName("options"), and unable to retrieve the option ...

The method to eliminate the default active class using AngularJS when clicking on different links

Here is the scenario: The first link is initially active and highlighted with the active class when the page loads. <a class="button active" ng-click="$parent.Filter = ''" ng-class="{ 'active': Filter === '' }"> Test l ...

Is it possible to utilize curly brackets in JavaScript for dividing code segments?

Check out this code snippet. I'm curious if there are any potential drawbacks to using it. //some example code var x = "hello"; { var y = "nice"; function myfunction() { //perform tasks... } } One advantage I see in utilizing t ...