GithubHelp home page GithubHelp logo

marian-c / accountant Goto Github PK

View Code? Open in Web Editor NEW

This project forked from venantius/accountant

0.0 0.0 0.0 48 KB

ClojureScript navigation for single-page applications, made simple.

License: Eclipse Public License 1.0

Clojure 100.00%

accountant's Introduction

Accountant

Accountant is a ClojureScript library to make navigation in single-page applications simple.

By default, clicking a link in a ClojureScript application that isn't a simple URL fragment will trigger a full page reload. This defeats the purpose of using such elegant frameworks as Om, Reagent, et al.

With Accountant, links that correspond to defined Secretary routes will trigger dispatches to those routes and update the browser's path, but won't reload the page.

Accountant also lets you navigate the app to a new URL directly, rather than through <a> tags.

Be aware that Accountant relies on the browser's HTML5 history, so older browsers will be left behind.

Installation

Just add the following to your project.clj:

:dependencies [venantius/accountant "0.2.3"]

Usage

All you have to do to get Accountant working is the following:

(ns your-app-ns
  (:require [accountant.core :as accountant]))

(accountant/configure-navigation! {:nav-handler (fn [path] ...) :path-exists? (fn [path] ...)})

nav-handler is a fn of one argument, the path we're about to navigate to. You'll want to make whatever side-effect you need to render the page here. If you're using secretary, it'd look something like:

(fn [path]
  (secretary/dispatch! path))

If you're using bidi + just rendering via react, that might look like:

(fn [path]
  (om/update! app [:path] path))

path-exists? is a fn of one argument, a path, that takes the path we're about to navigate to. This should return truthy if the path is handled by your SPA, because accountant will preventDefault the event, to prevent the browser from doing a full page request.

Using secretary, path-exists? would look like:

(fn [path]
  (secretary/locate-route path))

Using bidi, path-exists? would look like:

(fn [path]
  (boolean (bidi/match-route app-routes path)))

You can also use Accountant to set the current path in the browser, e.g.

(accountant/navigate! "/foo/bar/baz")

If you want to dispatch the current path, just add the following:

(dispatch-current!)

Note that both navigate! and dispatch-current! can only be used after calling configure-navigation!

Caveat: UI Frameworks

Sometimes links may be used nested within UI components, especially when using third-party wrappers, like react-bootstrap etc. These links may have an empty href attribute or a value like #. Two things might happen: Either, if a route is defined for the root path (i.e. '/' or '/#'), accountant will suppress the browser navigation and dispatch via secretary or the browser will reload the page.

To prevent this accountant looks for an attribute data-trigger on every link. The presence of this attribute signals that this link is a means to trigger a callback, not a navigation. If data-trigger is defined on a link it gets completely ignored, just like a button.

Example: When using a DropdownButton with MenuItems each item will contain an <a href="#"...> element. Since this element can't be replaced, we can at least add arbitrary attributes to it:

(let [dropdown-button (reagent/adapt-react-class js/ReactBootstrap.DropdownButton)
      menuitem (reagent/adapt-react-class js/ReactBootstrap.MenuItem)]
  [dropdown-button {:id "foo" :title "..." :onSelect (fn [idx]...)}
    [menuitem {:id "1"
               :data-trigger true
               :eventKey "1"}]

License

Copyright © 2017 W. David Jarvis

Distributed under the Eclipse Public License, the same as Clojure.

accountant's People

Contributors

venantius avatar edvorg avatar smee avatar arohner avatar amonks avatar crteal avatar iku000888 avatar shinych avatar drtom avatar cap10morgan avatar eyelidlessness avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.