Adding htmx to Active Admin
  • This is the perfect example of "Just because you can do something doesn't mean you should". There was quite a lot of hacking to get this to work. I'm hoping that Active Admin 4 will remove the need for most of this hackery.

  • Loading HTMX

  • First we need to load in the htmx js file

  • # /config/initializers/active_admin.rb
    ActiveAdmin.setup do |config|
      config.register_javascript '/vendor/htmx/1.9.9.js'
    end
  • Then we need to add hx-boost to the body tag

  • # /config/initializers/active_admin.rb
    module ActiveAdmin
      module Views
        module Pages
          class Base
            alias_method :original_build_page, :build_page
            def build_page
              within body(class: body_classes, "hx-boost" => "true") do
                original_build_page # Ensures that the rest of the page is built as usual
              end
            end
          end
        end
      end
    end
  • Fixing issues

  • All htmx requests are sent with an Accept header of */*. Active Admin doesn't allow this, so we need to override the restrict_format_access! method.

  • First create a controller concern

  • # app/controllers/concerns/admin/common_admin_functions.rb
    module Admin
      module HtmxEnable
        extend ActiveSupport::Concern
    
        included do
          def restrict_format_access!
            unless request.format.html? || request.format.to_s == '*/*'
              presenter = active_admin_config.get_page_presenter(:index)
              download_formats = (presenter || {}).fetch(:download_links, active_admin_config.namespace.download_links)
    
              unless build_download_formats(download_formats).include?(request.format.symbol)
                raise ActiveAdmin::AccessDenied.new(current_active_admin_user, :index)
              end
            end
          end
        end
      end
    end
    
  • Once the concern is created, we need to tell Active Admin to use it.

  • # /config/initializers/active_admin.rb
    Rails.application.config.to_prepare do
      ActiveAdmin::ResourceController.class_eval do
        include Admin::HtmxEnable
      end
    end
  • Loading Javascript

  • After htmx has loaded in new content, we need to apply behaviours to it again. But active admin doesn't have a single function that wraps all of it's javascript. So instead we have to reload the entire active_admin.js file 😆.

  • // app/assets/javascript/active_admin.js
    
    document.addEventListener('DOMContentLoaded', function() {
      document.body.addEventListener('htmx:afterSwap', function(event) {
        const script = document.createElement('script');
        script.id = 'application-js';
        script.src = '/assets/active_admin.js?' + new Date().getTime(); // Cache-busting
        document.head.appendChild(script);
      });
    });
  • Issues

    • Hx-boost uses inner-swap, which means that the body classes don't change. Active admin form styling depends on the body class. So if you load up an edit page, click on a side menu link to an index page, the body still has the edit class and the index page is missing CSS.

    • Doesn't play well with Arctic Admin's javascript - because Arctic Admin uses functions to identify dom elements, the same behaviour gets added multiple times - this breaks the filter panel on the right, causing repeated animations.


  • Website Page