drab v0.10.5 Drab View Source

Drab allows to query and manipulate the User Interface directly from the Phoenix server backend.

Drab operates on top of the Phoenix application, to run it you must already have it configured. In case you operate the app under an umbrella, all Drab configuration and installation should be done in the Web application (in most cases the one ending with _web).

All Drab functions (callbacks and event handlers) should be placed in a module called a ‘commander’. It is very similar to controller, but it does not render any pages - it works with the live page instead. For example, pages generated by DrabExample.PageController are handled by commander with the corresponding name, in this case DrabExample.PageCommander:

defmodule DrabExample.PageCommander do
  use Drab.Commander

  onload :page_loaded

  # Drab Callbacks
  def page_loaded(socket) do
    set_prop socket, "div.jumbotron h2", innerHTML: "This page has been DRABBED"
  end

  # Drab Events
  defhandler button_clicked(socket, sender) do
    set_prop socket, this(sender), innerText: "already clicked"
  end
end

More on commander is in Drab.Commander documentation.

Drab handler are launched from the client (browser) side by running javascript function Drab.exec_elixir(), or defining the handler function name directly in the html:

<button drab-click="button_clicked">Clickety click</button>

More on event handlers in Drab.Core documentation.

Debugging Drab in IEx

When started with iex (iex -S mix phx.server) Drab shows the helpful message on how to debug its functions:

    Started Drab for /drab/docs, handling events in DrabPoc.DocsCommander
    You may debug Drab functions in IEx by copy/paste the following:
import Drab.{Core, Query, Modal, Waiter}
socket = Drab.get_socket(pid("0.443.0"))

    Examples:
socket |> select(:htmls, from: "h4")
socket |> exec_js("alert('hello from IEx!')")
socket |> alert("Title", "Sure?", buttons: [ok: "Azaliż", cancel: "Poniechaj"])

All you need to do is to copy/paste the line with socket = ... and now you can run Drab function directly from IEx, observing the results on the running browser in the realtime.

Modules

Drab is modular. You may choose which modules to use in the specific Commander by using :module option in use Drab.Commander directive or set it globally by :default_modules config option. By default, Drab.Live, Drab.Element and Drab.Modal are loaded.

Every module must have the corresponding javascript template, which is added to the client code in case the module is loaded. This is why it is good to keep the modules list small, if you are not using all modules.

Drab.Core module is always loaded.

List of Drab Modules

Drab.Core

Contains core functions, like exec_js. It is always loaded, as it is essential for the rest of Drab.

Drab.Live, the living assigns

This module is responsible for the living assigns. Contains function to push (poke) and pull (peek) new assign values to the browser, live. Works only with pages compiled with Drab.Live.EExEngine (pages with .drab extension).

Drab.Element, DOM element manipulation

Use functions from this module to get (query) or set (set_prop) properties or attributes of DOM elements. All functions are based on CSS selectors.

Drab.Modal, Bootstrap modal window

This module contains only one function, modal, which shows synchronous modal windows. It requires Bootstrap to work. Good to ask for a customer input.

Drab.Waiter, waits for the user input

This is an optional module, so must be listed in :module option in use Drab.Commander directive or in :default_modules config option. Analogically to modal, waits for the user input.

Drab.Query, the jQuery module

This is an optional module, so must be listed in :module option in use Drab.Commander directive or in :default_modules config option. Also, jQuery must be available as a global (see “Manuall Installation” in README). Drab.Query has a number of useful functions, brings jQuery to the server side.

Drab.Browser, browser related functions

This module is standalone (does not contain its own JS), so it does not have to be listed in use Drab.Commander or in the setup. Contains browser related functions, like get the local time, language or set the url in the browser bar.

Handling Exceptions

Drab intercepts all exceptions from event handler function and let it die, but before it presents the error message in the logs and an alert for a user on the page.

By default it is just an alert(), but you can easly override it by creating the template in the priv/templates/drab/drab.error_handler.js folder with your own javascript presenting the message. You may use the local variable message there to get the exception description, like:

alert(<%= message %>);

Drab in production and behind a proxy

When using in production, an app is often behind an apache/nginx server for domain virtualization or balancing, so the external port (80) is different from the actual app port (i.e. 4000). The necessary mapping between the two ports is usually done by configuring a proxy, but a particularly care have to be taken to correctly handle websocket calls, as they are at the core of Drab mechanism to communicate between the client browser and the backend server.

You can find more information and examples to how to configure your nxinx or apache environments on the Drab wiki page at https://github.com/grych/drab/wiki/Drab-in-production-and-behind-a-proxy

Learnig Drab

There is a tutorial/demo page.

The point to start reading docs should be Drab.Core.

Link to this section Summary

Functions

Returns a specification to start this module under a supervisor

Extract Drab PID from the socket

Link to this section Types

Link to this type t() View Source
t() :: %Drab{
  commander: atom(),
  commanders: list(),
  controller: atom(),
  priv: map(),
  socket: Phoenix.Socket.t(),
  store: map(),
  topics: list()
}

Link to this section Functions

Returns a specification to start this module under a supervisor.

See Supervisor.

Extract Drab PID from the socket