bernat / best_in_place

A RESTful unobtrusive jQuery Inplace-Editor and a helper as a Rails Gem
http://blog.bernatfarrero.com/in-place-editing-with-javascript-jquery-and-rails-3/
1.2k stars 572 forks source link

Usage in Rails 6 #620

Open alliedarmour opened 4 years ago

alliedarmour commented 4 years ago

Hi,

currently, I'm trying to use the best_in_place gem with my Rails 6 application, but since I use Webpacker I'm not able to figure out how to get the gem to work, cause the readme is kind of outdated.

If I Add //= require best_in_place or (newer) require("best_in_place") it's just not found.

So if anyone uses this gem in a Rails 6 application, how do you import the js-file?

Thanks for any help! `

Tomasmillar commented 4 years ago

I am also trying to use with Rails 6. I am finding that it shows the text but doesn't allow it to be editable...

gxlonline commented 4 years ago

me too

alliedarmour commented 4 years ago

I am also trying to use with Rails 6. I am finding that it shows the text but doesn't allow it to be editable...

How did you import the library? Can you Show me a code sample? :)

Tomasmillar commented 4 years ago

I put this into gem file

gem 'best_in_place', '~> 3.0.1'

then this into application.js

//= require jquery
//= require best_in_place

//= require jquery-ui
//= require best_in_place.jquery-ui

and then also pasted this into application.js:

$(document).ready(function() {
  /* Activating Best In Place */
  jQuery(".best_in_place").best_in_place();
});
Praveenkj commented 4 years ago

I am also trying to use with Rails 6. I am finding that it shows the text but doesn't allow it to be editable...

Yeah. For me too. Can't make it editable cause require("best_in_place") in application.js is not working. Uncaught TypeError: $(...).best_in_place is not a function is shown in console.

Praveenkj commented 4 years ago

Are there any other alternatives as good as best_in_place for rails 6?

alliedarmour commented 4 years ago

Unfortunately I didn't find anything. Seems like we have to use pure Javascript/JQuery.

Praveenkj commented 4 years ago

Unfortunately I didn't find anything. Seems like we have to use pure Javascript/JQuery.

Yeah. I was trying Jinplace in which it creates POST request and always triggers create action.There is no clear documentation on sending different requests. https://github.com/itinken/jinplace

alliedarmour commented 4 years ago

I found a relatively new plugin which I will try to get to work, that looks quite promising:

JEditable

Praveenkj commented 4 years ago

@alliedarmour Great. Let me know how it works after trying.

alliedarmour commented 4 years ago

@Praveenkj just wanted you to know that I found a working solution:

I'm using Inplace.js. It's easy to setup and working great!

balakirevs commented 4 years ago

do the following for make it work in rails 6:

alliedarmour commented 4 years ago

do the following for make it work in rails 6:

  • add erb support to webpacker rails webpacker:install:erb
  • create file like gems.js.erb & import it to app/javascript/packs/application.js -> import './gems.js.erb';
  • put thise inside gems.js.erb:
import '<%= File.join(File.join(Gem.loaded_specs['best_in_place'].full_gem_path, 'lib', 'assets', 'javascripts', 'best_in_place.js')) %>'
  • in application.js add:
$(".best_in_place").best_in_place();

Thanks, yeah it's working Like that. Didn't know you can add .erb-support to Webpacker :D. Thanks Mate!

lumpidu commented 4 years ago

No go for me with the above. Webpacker complains, it cannot find jquery:

ERROR in ~/.rvm/gems/ruby-2.6.3/gems/best_in_place-3.0.1/lib/assets/javascripts/best_in_place.js
Module not found: Error: Can't resolve 'jquery' in '~/.rvm/gems/ruby-2.6.3/gems/best_in_place-3.0.1/lib/assets/javascripts'
 @ ~/.rvm/gems/ruby-2.6.3/gems/best_in_place-3.0.1/lib/assets/javascripts/best_in_place.js 1:0-17 1:0-17
 @ ./app/javascript/components/gems.js.erb
 @ ./app/javascript/packs/application.js

I definitely have it installed. Does this have to do with erb support ?

davegudge commented 4 years ago

I think it may be complaining about the require at the top of best_in_place.js rather than the presence of jQuery itself:

//= require jquery.autosize

Edit:

It's not complaining about the require jquery.autosize. It appears that jquery cannot resolved when importing best_in_place.js from the gem itself, however, if a copy of best_in_place.js is placed in a directory which webpack is aware of, it seems to work as expected.

e.g. I'm upgrading a project so the webpacker.yml contains:

  resolved_paths: ["app/assets", "vendor/assets"]

I've moved best_in_place.js from the gem into vendor/assets/javascripts, and then added the following to app/javascript/packs/application.js:

import "javascripts/best_in_place";

And it appears to be imported without error. I haven't tested in app yet, as I still have more js libs to resolve.

Amm1r-IT commented 4 years ago

Hi @davegudge

I followed what u said

I added a copy of best_in_place.js in my lib/assets/javascripts

Then import "javascripts/best_in_place"; in my application.js

I also added another copy of import "javascript/best_in_place"; into javascript/pack dir but, i am still getting errors saying

Module not found: Error: Can't resolve 'jquery/src/jquery' in '/home/ubuntu/.rvm/gems/ruby-2.6.3/bundler/gems/best_in_place-c0bc9c8ad3e1/lib/assets/javascripts'

Module not found: Error: Can't resolve 'javascripts/best_in_place' in '/home/ubuntu/environment/apartment/app/javascript/packs'

Any suggestion?

Thanks,

davegudge commented 4 years ago

Hi @Amm1r-IT,

I haven't got as far as committing this change to the project I'm working on (as other things have come up (unrelated)), but I still have the changes stashed locally.

However, looking at your comment, if you're placing the file in lib/assets/javascripts (I didn't use this directory), you'll need to make sure webpacker knows to look in that location by adding it to the resolved_paths: in webpacker.yml

e.g.:

    resolved_paths: ["lib/assets"]

Hopefully that will resolve your issue?

Amm1r-IT commented 4 years ago

Hi @davegudge

thanks for your feedback

the issue is solved , i think it was on how to import the best_in_place.js file

i just added a copy into my pack folder and import it in application.js

with only these lines in my application.js for the gem

`
require("jquery") import "bootstrap" import "./best_in_place"

$(document).ready(function() { / Activating Best In Place / jQuery(".best_in_place").best_in_place(); });

`

Thanks,

Tressa-Sanders commented 4 years ago

For me, this issue was order related. I knew it should be working because I have it working in other Rails 6 projects. I don't use Webpacker in any of my Rails 6 projects. I use the old asset pipeline.

But this one was giving me this Uncaught Type error. The only difference is I decided not to use Webpacker again for this new Rails 6 app and I'm barely using the old asset pipeline. In order to get this working, I had to move : <%= javascript_include_tag 'admin/application' %> to the bottom of my layout template right above because I'm not loading any jquery inside application.js. I have it linked directly in the layout (bypassing the asset pipeline). Once, I had application.js loading AFTER all my other JS scripts that are below the footer, it works fine.

I'm not saying that needs to happen in your application, only that it was an order issue with mine because of the way I'm loading my assets in this new project.

borstad commented 3 years ago

Praveenkj just wanted you to know that I found a working solution:

I'm using Inplace.js. It's easy to setup and working great!

@alliedarmour did you have a tutorial or something you used for this? I'm new to rails and trying to get some in place editing going. Any help would be appreciated!

alliedarmour commented 3 years ago

@bborstad I don't use it anymore, I implemented my own in place editing. Take a look at StimulusJS / Stimulus Reflex, it's easy to get it working with this and you can use it for many things throughout your project (real time interactions over ActionCable websockets).

borstad commented 3 years ago

@alliedarmour thank you!

poqudrof commented 3 years ago

Hello,

I did small updates for Rails 6 / Webpack and a Turbo (successor of Turbolinks) update for Best in place.

I have this in my javascript/packs/application.js:

// Best in place
require("../vendor/best_in_place");

$(document).on("turbo:load", () =>{
  $(".best_in_place").best_in_place();
}

Obviously it is not updated for the modern web, so I try to trigger here and then, I even written a very small stimulus controller to trigger it in page-part refresh without calling JS directly.

This version introduce two dependencies to add with yarn or npm:  "autosize" and "autosize-input".

Updated source: https://gist.github.com/poqudrof/0cf74465841f0fed0f6e4afe6ddc89e4

Tested to work in Rails 6.0. I hope it could be useful to anyone :smile: .

I am still not ready to rewrite a subset of it like @alliedarmour , I guess it would be a nice update to rewrite it without with Stimulus/Turbo instead of JQuery.

Cheers, Jeremy.

0agautam commented 3 years ago

I am also trying to use with Rails 6. I am finding that it shows the text but doesn't allow it to be editable...

i'm also stuck with the same problem i can see the text but it is not editable

0agautam commented 3 years ago

Hi @davegudge

thanks for your feedback

the issue is solved , i think it was on how to import the best_in_place.js file

i just added a copy into my pack folder and import it in application.js

with only these lines in my application.js for the gem

` require("jquery") import "bootstrap" import "./best_in_place"

$(document).ready(function() { / Activating Best In Place / jQuery(".best_in_place").best_in_place(); });

`

Thanks,

Can you help me with the same problem?

0agautam commented 3 years ago
import "javascripts/best_in_place";

I think it may be complaining about the require at the top of best_in_place.js rather than the presence of jQuery itself:

//= require jquery.autosize

Edit:

It's not complaining about the require jquery.autosize. It appears that jquery cannot resolved when importing best_in_place.js from the gem itself, however, if a copy of best_in_place.js is placed in a directory which webpack is aware of, it seems to work as expected.

e.g. I'm upgrading a project so the webpacker.yml contains:

  resolved_paths: ["app/assets", "vendor/assets"]

I've moved best_in_place.js from the gem into vendor/assets/javascripts, and then added the following to app/javascript/packs/application.js:

import "javascripts/best_in_place";

And it appears to be imported without error. I haven't tested in app yet, as I still have more js libs to resolve.

Thanks dear, Your solution helped me, I was stuck like for more than a day because of this problem. Thanks a lot :+1:

yosh1tsune commented 1 year ago

Hello,

I did small updates for Rails 6 / Webpack and a Turbo (successor of Turbolinks) update for Best in place.

I have this in my javascript/packs/application.js:

// Best in place
require("../vendor/best_in_place");

$(document).on("turbo:load", () =>{
  $(".best_in_place").best_in_place();
}

Obviously it is not updated for the modern web, so I try to trigger here and then, I even written a very small stimulus controller to trigger it in page-part refresh without calling JS directly.

This version introduce two dependencies to add with yarn or npm:  "autosize" and "autosize-input".

Updated source: https://gist.github.com/poqudrof/0cf74465841f0fed0f6e4afe6ddc89e4

Tested to work in Rails 6.0. I hope it could be useful to anyone smile .

I am still not ready to rewrite a subset of it like @alliedarmour , I guess it would be a nice update to rewrite it without with Stimulus/Turbo instead of JQuery.

Cheers, Jeremy.

Saved my life, I'm returning to use Rails front-end after Rails 7 and Turbo and was at the point of headbuting the wall haha

This worked for me just fine, thank's a lot!

poqudrof commented 1 year ago

Hello,

Instead of a Turbo:load I now use a small Stimulus Controller like this, it saves lives for ajax calls and back button presses.

import { Controller } from "@hotwired/stimulus"
// Trigger a refresh of Best in place.
export default class extends Controller {
  connect() {
      $(".best_in_place").best_in_place();
  }
}

Cheers, Jeremy.