Afolabi Olaoluwa
Afolabi Olaoluwa

Reputation: 1948

UJS does not work for my inline editing solution in Rails 6.1.0

I am trying to do inline editing which is not responding to the Ajax JQuery solution. However, if I remove remote: true from the view and make it respond to HTML, it edits and updates the record perfectly well. The Ajax JQuery solution for Delete/Destroy works well. I don’t know what I am missing. My code is listed below. I am using Rails 6.1.0, Bootstrap 4.

Controller

# frozen_string_literal: true

class MerchantsController < ApplicationController
  include ControllerHelpers::StrongParameters

  def index
    @merchants = Merchant.all.load
  end

  def new; end

  def edit
    merchant
  end

  def update
    merchant

    respond_to do |format|
      if @merchant.update(update_params)
        format.js { redirect_to merchants_path, notice: 'Merchant was successfully updated.' }
        format.json { render :show, status: :ok, location: @merchant }
      else
        format.js { render :edit }
        format.json { render json: @merchant.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    merchant
    @merchant.destroy
    respond_to do |format|
      format.js { redirect_to merchants_path, notice: 'Merchant was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private

  def merchant
    @merchant ||= Merchant.find(params[:id])
  end

  def update_params
    params.require(:merchant).permit(permitted_merchant_update_attributes)
  end
end

index.html.slim

table.table.table-bordered.table-hover
    thead
      tr[style="background-color: #f1f8ff;"]
        th
          | Name
        th
          | Description
        th
          | Email
        th
          | Status
        th
          | Transaction Sum
        th[colspan="2"]
          | Functions
    tbody
      = render @merchants #This renders _merchant.html.slim below

_merchant.html.slim

- present(merchant) do |merchant|
  tr#remove-row.refresh
    td
      = merchant.name
    td
      = merchant.description
    td
      = merchant.email
    td
      = merchant.status
    td
      = merchant.total_transaction_sum
    td
      |  <div id="edit-merchant">
      = link_to t('merchant_page.button_labels.edit'), edit_merchant_path(merchant), remote: true, class: 'btn btn-primary btn-sm'
    td
      = link_to t('merchant_page.button_labels.delete'), merchant, method: :delete, data: { confirm: t('merchant_page.messages.delete'), remote: true }, class: 'delete btn btn-danger btn-sm'

_form.html.slim

= simple_form_for @merchant, remote: true do |f|
  = f.error_notification
  = f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present?

  .form-inputs
    = f.input :name
  .form-inputs
    = f.input :description
  .form-inputs
    = f.input :email
  .form-inputs
    = f.input :status
  .form-actions
    = f.button :submit, class: 'btn btn-primary btn-block btn-lg'

development log when I hit on edit button with remote set to true on the view template

Started GET "/merchants/22/edit" for 127.0.0.1 at 2020-12-25 18:04:29 +0100
Processing by MerchantsController#edit as JS
  Parameters: {"id"=>"22"}
  Merchant Load (3.1ms)  SELECT "merchants".* FROM "merchants" WHERE "merchants"."id" = $1 LIMIT $2  [["id", 22], ["LIMIT", 1]]
  ↳ app/controllers/merchants_controller.rb:63:in `merchant'
  Rendering merchants/edit.js.slim
  Rendered merchants/_form.html.slim (Duration: 34.6ms | Allocations: 9456)
  Rendered merchants/_form.html.slim (Duration: 28.4ms | Allocations: 9060)
  Rendered merchants/edit.js.slim (Duration: 64.0ms | Allocations: 18921)
Completed 200 OK in 99ms (Views: 66.3ms | ActiveRecord: 14.2ms | Allocations: 24445)

edit.js.slim

| $('#edit-merchant a').hide().parent().append("
= j render 'form', merchant: @merchant
| ") $('#edit-merchant form').hide().parent().append("
= j render 'form', merchant: @merchant
| ")

browser console (upon hitting in edit button)

Uncaught SyntaxError: unexpected token: identifier
    processResponse rails-ujs.js:283
    node_modules application-729c39a0883e65f714cb.js:1570
    onreadystatechange rails-ujs.js:264
    createXHR rails-ujs.js:262
    node_modules application-729c39a0883e65f714cb.js:1568
    node_modules application-729c39a0883e65f714cb.js:2026
    node_modules application-729c39a0883e65f714cb.js:1546
    node_modules application-729c39a0883e65f714cb.js:1538
    node_modules application-729c39a0883e65f714cb.js:2137
    js application.js:6
    Webpack 3
        __webpack_require__
        <anonymous>
        <anonymous>
    processResponse rails-ujs.js:283
    xhr rails-ujs.js:196
    onreadystatechange rails-ujs.js:264
    (Async: EventHandlerNonNull)
    createXHR rails-ujs.js:262
    ajax rails-ujs.js:194
    handleRemote rails-ujs.js:652
    delegate rails-ujs.js:172
    (Async: EventListener.handleEvent)
    delegate rails-ujs.js:164
    start rails-ujs.js:763
    js application.js:6
    Webpack 3
        __webpack_require__
        <anonymous>
        <anonymous>

browser source code

enter image description here

Upvotes: 0

Views: 282

Answers (1)

Afolabi Olaoluwa
Afolabi Olaoluwa

Reputation: 1948

Apparently, edit.js.slim code does not respond to pick the elements it is supposed to pick. I had to rewrite that by using Ajax, and this is what I came up with for it to work. Though, I changed the html table element to my own custom div table, but it works with html table elements as well.

edit.js.slim

| $('.divTable.blueTable').replaceWith('
= j render 'inline_edit_form'
| ');

So, I am selecting the HTML classes where I have divTable and blueTable and replaced them with my inline edit form, which works fine. I do hope that helps someone. Check below for my broswer page source elements, in any case, anyone wants to develop this further.

What I have written in the question is what I used for one of my Rails 6.0.0 projects with Bootstrap 4 and it worked fine there without any problem. Unfortunately, it doesn't with Rails 6.1.0.

enter image description here

Upvotes: 1

Related Questions