0

Ajax in Rails Admin

Admin Panel is a part and parcel of web development as it is useful to maintain data and information in the system. In ruby on rails, there are some useful and effective gems. In this post i will talk about rails_admin gem.

Rails Admin:

Rails admin is a powerful gem with impressive feature set which generate a powerful system to decorate admin panel of application. By default, one can create, update, delete, and export data of a model, along with its association with this. It has a vast mechanism to customize any of these actions for a model. Also one can add custom action for a model to maintain the flow in the application. Installing rails in application is just like other gems. Add gem 'rails_admin', '~> 1.2' in the gemfile and bundle install. Run rails g rails_admin:install in the console. This will add rails admin initializer file in config folder. It will be global settings folder in application. Now it is good to go. The basic usage can be found here.

AJAX

Asynchronous JavaScript And XML, widely known as AJAX, is a set of Web development techniques using many Web technologies on the client side to create asynchronous Web applications. With Ajax, Web applications can send and retrieve data from a server in the background without interfering with the display and behavior of the existing page. AJAX allows developer to change content dynamically without the need to reload the entire page. It is not a single technology, but rather a group of technologies. HTML and CSS can be used in combination to mark up and style information

AJAX in Rails Admin

By default rails admin use Pjax in their system. But what if one need to add ajax as ajax is widely known and accepted to the developer. There may be a confusuion like rails_admin uses pjax, but how to integrate ajax? But if anyone look at the definition of pjax, It will be clear that PJAX is just an extension of AJAX.

PJAX

PJAX is a javascript module that uses ajax and pushState to deliver a fast browsing experience with real permalinks, page titles, and a working back button. Pjax works by fetching HTML from server via ajax and replacing the content of a container element on web page with the loaded HTML. It then updates the current URL in the browser using pushState. If the server is configured for pjax, it can render only partial page contents and thus avoid the potentially costly full layout render. As a result, it is very swift in page rendering. Pjax sites give the feeling of browsing an app even in low bandwidth internet.

So Easy Yet Too Hard

When I first encounter the problem of writing AJAX for rails_admin, I thought its impossible to do so. One reason for this thinking is lack of resource for such kind of work. But later I found out that tt is not that hard at all. One just need to know where to write HTML and javascripts. At first I placed all the code in main application asset. But after reading the documentation of rails admin, I came to know that rails admin engine dont get any asset of the main application. It has its own environment and world like son doong cave. We just need to find the entrance to go inside this rails admin world. I will tell about it with an example.

Like I have a boolean field in a model and i want to update it in just a click rather than clicking on edit button, then going to edit page and finally change the attribute and save. The process of rails_admin default is not wrong but in case of user-friendliness it is not beautiful. So how to do?

if we list down the process, We will have

  1. We have to add a button in the corresponding model index body.
  2. Write Javascript action for that button
  3. Write controller action to render JSON for the ajax request.

First of all, We have to add a button in the body. It is just a easy task but the question arise in our mind is where to write these so that rails_admin can read and execute them. If one go through the structure of rails_admin gem, he will see that all the view file is written in app/views/rails_admin folder. Also in rails admin helper, It is instructed to precompile all the html file from that folder. So if we write our custom HTML code in that directory, rails_admin will take it as its own code and compile it. Now we will write our html code creating that directory.

app/views/rails_admin/_button.html.erb

<button type="button" class="btn btn-success update-bool" id="edit-bool<%= object.id %>"
    value="<%= object.enabled %>" data-id="<%= object.id %>">
    <i class="fa fa-check" aria-hidden="true"></i>
</button>

Here object is passed by binding[:object] from controller or config file like this.

bindings[:view].render partial: "button.html.erb", locals: {field: self, object: bindings[:object]}

So now our buttton is set, next we have to write Javascript which includes AJAX call to controller for that button. Again in helper method, It is coded that ui.js in app/assests/javascripts/rails_admin/custom folder is like application.js file rails_admin. So if we add our custom js file in that file, rails_admin will take it as its own asset. We can customize that file by creating this file in that directory. We write our ajax code in button.js file and added it in ui.js.

app/assests/javascripts/rails_admin/custom/ui.js

//= require ./application_enable

app/assests/javascripts/rails_admin/custom/application_enable.js

$('document').ready(function() {
  $('body').on('click', '.update-bool', function () {
    $.ajax({
      url: 'application/' + element_id +'/enable',
      type: 'PUT',
      data: {model_name: 'application', application:{enabled: !status}},
      success:function(data){
       ....
      },
      error: function (data) {
       ....
      }
    });
  });
});

Note that rails_admin dont execute any JS code unless it is written in $('document').ready() block

Last but not the least is the design of JSON source for the AJAX. By default rails have some action defined. And also it is very easy to override them for our own work. But preference is to write custom action. The process is

  • Create a file in lib folder in rails project. For this example, I just created a file named update_bool.rb in lib folder.
  • Next I need to include it in initializer file so that it is loaded when server starts. The line would be require Rails.root.join("lib", "update_bool.rb")

Next, write the logic in register_instance_option :controller block

lib/enable_bool.rb

module RailsAdmin
  module Config
    module Actions
      class EnableBool < RailsAdmin::Config::Actions::Base
        RailsAdmin::Config::Actions.register(self)

        .....

        register_instance_option :controller do
            if @object.save
              render json: {
               success: "success"  
              }
            else
              render json: {error: error}
            end
          end
        end
      end
    end
  end
end

Now this system is good to go. One of the most important thing i forget is one have to restart the rails server after any change to view the result of recent change. Or you have to spent extra time in debugging a correct code like me 😦

Hope It will help. Happy coding!


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.