Search code examples
javascriptruby-on-railswebpackerruby-on-rails-6.1

Rails 6.1.3, webpacler, select2, getting error: readyException.js:6 Uncaught TypeError: $(...).select2 is not a function


I am new with Rails 6 and webpacker. I have created a new app with rails and webpacker, got everything working but when I tried to utilize the select2 I ran into a problem where I get readyException.js:6 Uncaught TypeError: $(...).select2 is not a function errors and not am not able to submit the selected attribute to the database. I have reviewed and tried several suggestions presented on the web but didn't work. Not sure where I went wrong. Any help is much appreciated. By the way I am using simple_form and Slim.

app/assets/application.scss

@import 'bootstrap/scss/bootstrap';

app/javascript/stylesheets/application.scss

@import 'bootstrap/scss/bootstrap';

app/javascript/packs/application.js

import Rails from "@rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "@rails/activestorage"
import "channels"

import "jquery";
import "popper.js";
import "bootstrap";
import "../stylesheets/application"
import "@fortawesome/fontawesome-free/js/all"
import select2 from 'select2';
import 'select2/dist/css/select2.css';


require("@rails/activestorage").start()
require("channels")
require("jquery")



Rails.start()
Turbolinks.start()
ActiveStorage.start()


$(document).ready(function() {
  $('.select').select2();
});

config/webpack/environment.js

const { environment } = require('@rails/webpacker')

const webpack = require('webpack')
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery'
  })
)

module.exports = environment

the view form views/users/_form.html.slim

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


      .form-inputs.form-group.center-block style="width:240px"
        = f.input_field :first_name,
        placeholder: 'First Name',
        class: 'form-control',
        autofocus: true,
        required: true
      .form-inputs.form-group.center-block style="width:240px"
        = f.input_field :last_name,
        placeholder: 'Last Name',
        class: 'form-control',
        autofocus: true,
        required: true
      .form-inputs.form-group.center-block style="width:240px"
        = f.input_field :email,
        placeholder: 'Email',
        class: 'form-control',
        autofocus: true,
        required: true
      .form-inputs.form-group.center-block style="width:240px"
        = f.select :roles, Role.all.map { |role| role.name }, {include_blank: true, required: true,
        include_hidden: false}, class: 'form-control', input_html: {class: 'select'}


      .form-actions.form-group.center-block style="width:240px"
        button.btn.btn-primary.space-above type="submit" Save
        = link_to "Cancel", admin_users_path, class: 'btn btn-default space-left'

Solution

  • I think you may be causing issues by importing jquery twice.

    Remove these lines:

    require("@rails/activestorage").start()
    require("channels")
    require("jquery")
    

    These are duplicating imports on lines above and (I think) the second require("jquery") could be clobbering the select2 plugin.

    Also, you're not using the local select2 variable from the import. This should be sufficient:

    import $ from 'jquery'
    import 'select2'
    
    $(document).ready(function() {
      $(...).select2()
    })
    

    I have a branch in a demo repo that has a working example https://github.com/rossta/rails6-webpacker-demo/compare/example/select2