Step by Step How to include selectize.JS within a rails project build the Ajax request and Json answer?

Viewed 2872

and i heard about lib call selectize. It sounds a good lib to help me to show-up some awesome dropdown effect. However the documentation is not really easy and i'm blind about how to implement selectize correctly. I have tried to use it and it's ok till to use or implement ajax. Any help ?

for some reasons when i call selectize to a specific selectclass it work. But when I need to tell to selectize component to to make an ajax request and search through a JSON file to get the answer and build the dropdown multi select i have serious issues .

the documentation propose that pattern with a github example :

$('#select-repo').selectize({
      valueField: 'url',
      labelField: 'name',
      searchField: 'name',
      create: false,
      render: {
        option: function(item, escape) {
          return '<div>' +
          '<span class="title">' +
          '<span class="name"><i class="icon ' + (item.fork ? 'fork' : 'source')
          + '"></i>' + escape(item.name) + '</span>' +
          '<span class="by">' + escape(item.username) + '</span>' +
          '</span>' +
          '<span class="description">' + escape(item.description) + '</span>' +
          '<ul class="meta">' +
          (item.language ? '<li class="language">' + escape(item.language) + 
          '</li>' : '') +
          '<li class="watchers"><span>' + escape(item.watchers) + '</span> 
          watchers</li>' +
          '<li class="forks"><span>' + escape(item.forks) + '</span> forks</li>'
          + '</ul>' +
          '</div>';
          }
        },
        score: function(search) {
          var score = this.getScoreFunction(search);
          return function(item) {
             return score(item) * (1 + Math.min(item.watchers / 100, 1));
          };
        },
        load: function(query, callback) {
          if (!query.length) return callback();
            $.ajax({
               url: 'https://api.github.com/legacy/repos/search/' + 
               encodeURIComponent(query),
               type: 'GET',
               error: function() {
               callback();
            },
            success: function(res) {
              callback(res.repositories.slice(0, 10));
            }
        });
     }
 });


I have tryed without any success cause i don't really know how to build the JSON file, the query is also a very hard point.

The actual result is that i need to understand the step that i need to build before using that lib. then once done i will use that lib with an ajx request

1 Answers

Welcome on stack so. There are few steps that you mentioned without adding lots of descriptions. But here the thing what ever the Lib you use you need to read and read again its documentation.

Rails and JavaScript Libs are working together through webpack. Whatever the lib you need. You will found the lib you want Yarn.

From the selectize.js lib to the view, you will need to play some file.js, file.rb, file.json, routes.rb at least so it's a huge question....

Let's start with that setup and if need further information I will take more time

Your current rails app add webpack or not ?

As RoR we have to ways to call some JavaScript libs and write their custom script.

The old method is to play with that file app/assets/javascripts

The modern method is to work with webpack. And do stuff inside this file for instance app/javascript/packs/application.js

I suppose that webpack is installed cause you tagged that word. Be aware that it's possible to process through the old method but stay update

yarn

According to the link above yarn

install selectize.js in your app with that command line

$ yarn add selectize

that will add the last version of selectize inside your file package.json

Call selectize within the right way

 $ mkdir app/javascript/components  ## to create a folder to file your JS components 
 $ touch  app/javascript/components/selectize.js ## to create a file to build JS components

Move to your node_modules folder which host all javascript lib installed or not by you. This folder is to the root of your app.

(1) Then Figure out the file node_modules/selectize/dist

Then open the file app/javascript/components/selectize.js with you text editor and let's write the basic code...

# app/javascript/components/selectize.js
import 'selectize/dist/js/selectize.min.js'; # scroll to node folder (1) get that path
import 'selectize/dist/css/selectize.css'; # scroll to node folder (1) get that path

const selectize = () => {
  $('.select-beast').selectize({
      // create: true, (from example on selectize page)
      sortField: 'text'
  });

};

export { selectize }; # app/javascript/packs/application.js will call that const

Then open the file inside app/javascript/packs/application.js with you text editor and let's write the basic code...

Call selectize component within the right way

# inside app/javascript/packs/application.js
import { selectize } from '../components/selectize'; # import the component
// selectize(); # init the component ⚠️ comment that line for now

Display form with the correct selectize class choosen ('.select-beast')

something like tis in ruby ...

<%= form_for @category do |f| %>
   <%= f.text_field :name %>
   <%= f.select(:single_option_ids,
         SingleOption.all.collect {|a| [a.name, a.id]}, 
         {:include_blank => "category select"}, 
         {:class => "select-beast"})-%>
<%end %>

Your output is ...

<!-- where you want in your app   -->
<select class="select-beast" name="category[single_option_ids]" id="category_single_option_ids"><option value="">category select</option>
   <option value="1">category A</option>
   <option value="2">category B</option>
   ...
   <option value="37">category X</option>
   <option value="38">category Y</option>
   <option value="39">category Z</option>
</select>

Init selectize within the right way

# inside app/javascript/packs/application.js
import { selectize } from '../components/selectize'; # import the component
selectize(); # init the component 

done ✅

Refresh your page and it's fine.

if issue persiste...

with css style

(the css from selectize is not working ? not loaded ? not extracted ?..) move to config/webpacker.yml

# line 51
development:
  <<: *default
  compile: true
  extract_css: true

Also check and be sure that CSS from webpack is loaded ... how to know this ? have a look inside your webpack-dev-server console

Version: webpack 4.32.2
Time: 2351ms
Built at: 06/05/2019 9:21:14 AM
                       Asset        Size             Chunks             Chunk Names
css/application-ff5bcd2e.css    7.73 KiB        application  [emitted]  application 
# this line is a css asset from webpack so css from webpack is loaded 
                ...# other lines
ℹ 「wdm」: Compiled successfully.

'$ is not defined' or error iniside javascript console

Make sure that your webpack setup include this line ...

# inside config/webpack/environment.js
const { environment } = require('@rails/webpacker')

const webpack = require('webpack')

// Preventing Babel from transpiling NodeModules packages
environment.loaders.delete('nodeModules');

// Bootstrap 4 has a dependency over jQuery & Popper.js:
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    Popper: ['popper.js', 'default']
  })
)

module.exports = environment
# config/webpack/development.js

process.env.NODE_ENV = process.env.NODE_ENV || 'development'

const environment = require('./environment')

module.exports = environment.toWebpackConfig()
# config/webpack/production.js

process.env.NODE_ENV = process.env.NODE_ENV || 'production'

const environment = require('./environment')

module.exports = environment.toWebpackConfig()

finish

There is no better way according me to start with webpack and rails. Then sure, API, JSON, search are good thing to go through with js libs like selectize, choice or even select2 at the end. Let us know if this is a good start to answer to your question 'STEP BY STEP ...'

Related