LogoLogo
ClausesDatafieldsSpecial FunctionsStylingQ&AAPI
  • Welcome!
  • Getting started
    • What is Clause9?
    • Structuring your clause library
    • Structuring your clauses
    • Drafting modes in Clause9
    • Creating a questionnaire
    • Sample clauses
    • Videos
      • Concepts and datafields
      • Conditions
      • Q&As
      • Binders
      • Styling
      • Enumerations
      • Tables
      • Definitions
      • Snippets
      • Cross-references
      • Special functions
      • Examples of common clauses
      • Import clauses from MS Word
      • Grammatical conjugations
      • Action buttons
      • Alternative clauses
  • Assemble document
    • Document toolbar
    • Clause hierarchies
    • Focus Mode
    • Bulk generation of documents
    • Exporting documents
    • Assemble Document - FAQ
    • How to: Assemble Document
      • Insert images
  • Assemble Document Operations Panel
    • Operations panel
    • File pane
    • Edit pane
    • Document pane
    • Binder pane in the operations panel
    • Search pane
    • Browse pane
    • Terms pane
    • Data dashboard
    • Advanced pane
    • Styling pane
    • Miscellaneous pane
    • Visibility settings & actions menu
  • Binders
    • Binders: general
    • Styling cross-references to subdocuments
    • Global and local definition lists
    • Document and binder properties
    • Styling of a Binder versus subdocuments
    • (Un)locking documents in a binder
    • Binders - FAQ
    • How to: binders
      • Make a subdocument in a binder conditional
  • Clauses
    • Introduction to clauses
    • Clause structure
    • Grammar sheet
    • Writing conditions
    • Examples of conditions
    • Using codes instead of text fragments
    • Bold, italic and underline
    • Special codes
    • Enabled?
    • Links
    • Cross-references
    • Introduction to tables
    • Deviating table styling
    • Shrinking clauses
    • Action buttons
    • Enumerations
    • File position
    • Snippets
    • Parameters
    • Conjugations
    • Mixing data types
    • For-loops
    • Clause versioning
    • Abstract article references
    • Advanced multi-language features
    • Clauses - FAQ
    • How to: clauses
      • Create an ad-hoc clause
      • Create a library clause
      • Make a clause repeat
      • Make a paragraph within a clause conditional
      • Use a shortcut to refer to a concept
      • Insert a line break or page break
      • Creating a list with both predefined options and free input
      • Defining alternative clauses
      • Creating cross-references
      • Creating signature blocks
      • Creating advanced party introduction clauses
      • Automatically numbered annexes or schedules
      • Reuse any clause in a different context
      • Setting MS Word document properties
      • Add action buttons to clauses
      • Electronically signing documents
  • concepts
    • Introduction to concepts
    • Creating concepts
    • Concept labels
    • Links
    • Organising concepts
    • Concepts - FAQ
    • How to: concepts
      • Add predefines to a datafield
  • Datafields
    • Introduction to datafields
    • Types of datafields
    • Rules of thumb for using datafields
    • Data-expressions
    • Datafield aliases
    • Datafield labels
    • Datafield special tags
    • Datafield descriptions
    • Repeating list datafields
    • Datafield predefines
    • Datafields - FAQ
    • How to: datafields
      • Change datafield type
      • Change the datafield's name or alias
  • Definitions
    • Introduction to definitions
    • How to: definitions
      • How do definitions work?
      • Create a definition
  • Files
    • How files are organised
    • Browse files
    • File types
    • Custom styling
    • Legal comments
    • File description
    • Attributes
    • Reporting
    • File name
    • File category
    • Access rights
    • How to: files
      • Creating advanced folders
      • Naming your files
      • Shortcuts to folders or files
  • Q&A
    • About cards
    • Cards pane
    • About changes
    • Changes pane
    • Types of changes
    • Adding conditions
    • Question options
    • Copying & pasting answers
    • Comments, notes & documentation
    • Interactive Q&A inspection
    • Embedding questions into a document
    • “Changes” button
    • Batch create pane
    • Identifiers pane
    • Import pane
    • Edit clauses pane
    • Q&A options
    • Q&A - FAQ
    • How to: Q&A
      • Create predefined answers to a question
      • Add disclaimers
      • Create categories of questions
      • Modify the exported filename
      • Create a question to change the language of a document
      • Send a questionnaire to someone without a ClauseBase account
      • Create questions for repeating list datafields
      • Selecting legal entities & addresses
      • Create a questionnaire using "batch create"
      • Launch other Q&As
    • Leveraging ClauseBuddy Smart Templates in Clause9
  • Import
    • Introduction to importing clauses
    • Uploading clauses
    • Defined terms in Import mode
    • Datafields in Import mode
    • Cross-references in Import mode
    • Assigning folders
    • Conversion process
    • Exporting
    • Stashing intermediate results
    • Tips, tricks & limitations
  • Styling
    • Styling overview
    • Base styling
    • Numbering
    • Definitions styling
    • Enumerations styling
    • Locale styling
    • References styling
    • Page styling
    • Styling of a Binder versus subdocuments
    • Styling: tips and tricks
    • Advanced styling topics
    • Copying headers and footers from an MS Word file
    • How to: styling
      • Using custom fonts
      • Change bullet styling
  • Special functions
    • Introduction
    • Calculations
    • Concepts
    • Conditions
    • Conjugations
    • Content Control Elements
    • Datafields
    • Dates & durations
    • Languages
    • Lists
    • Numbers
    • References
    • Repeating (looping)
    • Special items
    • Text structure
    • Text modification
    • User
    • Q&A
  • Settings
    • Account
    • Preferences
    • Access bundles
    • Favourites
    • Saved searches
    • Saved datafields
    • Styles
    • Default styles
  • Admin
    • General
    • Users
    • User rights
    • Profiles
    • Groups
    • Styles
    • Default styles
    • Attribute models
    • Usage page
    • Custom homepage
    • Global placeholders
    • Access rights
    • How to: admin
      • Adding a new user
      • Disabling a user
      • Managing group memberships
  • Miscellaneous
    • Advanced tips & tricks
    • Typing special symbols on your keyboard
    • Shortcuts
    • Grammar style guide
    • Inserting MS Word files
    • Globo-panel
    • Creating high-quality documents
    • Excel calculations and lookups
  • Integrations
    • Overview
    • Spreadbases
    • E-signing documents
    • Drag & drop integrations
  • For developers
    • Clause9 API
    • Custom functions
    • Example custom functions
Powered by GitBook
On this page
  • Example 1: Making sure percentages add up in a Q&A
  • Questions to create
  • Clojure code
  • Improvement
  • Showing the current total
  • Example 2: Creating a custom interface for a question
  • Questions to create
  • Clojure code
  • Example 3: Changing other Q&A answers upon changing a specific answer
  • Questions to create
  • Clojure code
Export as PDF
  1. For developers

Example custom functions

Example 1: Making sure percentages add up in a Q&A

Clause9’s standard Q&A conditions functionality let you easily check whether a certain number-answer is in a certain range — e.g., higher than 40 and lower than 100. However, the standard conditions do not allow you to create conditions that combine various answers together.

For example, assume you are making an employment contract for situations where employees can divide their time between three different positions (e.g., sales, marketing and IT). Obviously, for a full-time position, the percentages need to add up to 100% — if not, then some warning needs to be shown.

Questions to create

  • Create three different questions with number (integer) answers. Assign those questions the identifiers f1, f2 and f3 respectively in their options.

  • Create a warning question with a content such as “Warning: the percentages do not add up to 100%”.

Clojure code

Insert the following Clojure code in the condition attached to the warning-question, so that the warning-question will only be shown when the result of the Clojure-code is true.

(defn value-or-0 [id] 
    (or (answer id) 0))

(not= 100 
      (+ (value-or-0 "f1") (value-or-0 "f2") (value-or-0 "f3")))

We first define a Clojure-function that fetches the answer of the question with the specified identifier. If that answer happens to be nil — which would be the case when the end-user has not yet filled in any value — we return 0, otherwise we return the answer.

We then add the three percentages, and check whether they add up to exactly 100. If so, the result will be false (so that the warning will not be shown); otherwise the result will be true, so that the warning will indeed be shown.

Improvement

When none of the three percentages is filled in, the warning is also shown. It is probably advisable to only start showing the warning when at least one of the three percentages if filled in.

A first way to solve this, is by adding a subgroup of non-Clojure subconditions:

A second way to solve it, is by adapting the Clojure-code as follows:

(defn value-or-0 [id] 
    (or (answer id) 0))

(and (or (answer "f1") (answer "f2") (answer "f3"))
     (not= 100 
       (+ (value-or-0 "f1") (value-or-0 "f2") (value-or-0 "f3"))))

This code specifies that two conditions must be met for the warning-question to be shown:

  1. at least one of the percentages-questions must have its answer filled in

  2. all three percentages together must not be equal to 100

Showing the current total

Instead of showing a static warning (“Warning: the percentages do not add up to 100%”), it is more helpful to show the current total amount.

(defn value-or-0 [id] 
    (or (answer id) 0))

(defn total []
    (+ (value-or-0 "f1") (value-or-0 "f2") (value-or-0 "f3")))

(assoc question :title 
       {:en (str "Warning: the percentages do not add up to 100% " 
                 "(current total: " (total) "%)")})

To change the title of the warning, we assoc a new value in var question. (This var is predefined by Clause9’s Clojure runtime when customising questions.)

If other languages besides English would be required, then the specified map should be extended — e.g. with a string for French (:fr) or Dutch (:nl).

By the way, because the function value-or-0 is now used both in this custom function and in the previous Clojure-code for calculating the warning’s visibility condition, it could be useful to move this function to the central repository, and replace the calls — e.g., instead of (value-or-0 "f1") we would get (call "value-or-0", "f1"). The contents of the central repository function can then simply be (or (answer $1) 0) — the $1 refers to the first parameter that gets passed into this function, which would be "f1" in the given example.


Example 2: Creating a custom interface for a question

Suppose you allow your end-users to choose the legal entity for which the contract is being composed. Besides changing the address, VAT number, etc. this would also change the logo in the header of the document.

While Clause9’s standard tools allow you to predefine a list of entities, and then insert the relevant logo into the document’s header, the logo will not be visible towards the end-users until the document is effectively exported to DOCX / PDF (because headers and footers are deliberately not shown within the browser).

Using a “custom block” question and some Clojure code, you can however easily show this logo within the list of questions.

Questions to create

  • Create a question with text-answers that has three predefines: “Microsoft”, “Google” and “Apple”. Assign identifier “entity” to this question.

  • Create a “custom block” question.

Clojure code

Insert the following code into the custom block’s code box:

(when-let [entity-name  (answer "entity")]
  [:img {:style {:padding "10px"}
         :width "200px"
         :src (case entity-name
                 "Microsoft" "https://bit.ly/2MhZegg"
                 "Google" "https://bit.ly/2TWJwvp"
                 "Apple" "https://apple.co/3gEE4XE")}])
  • This code only shows something on the screen when the answer to the question with identifier entity is set (i.e., when one of the three entities is chosen).

    • an image HTML-component

    • with a 10px style padding and a fixed width of 200px

    • with a reference to a URL that depends on the entity-name chosen

The results is as follows:


Example 3: Changing other Q&A answers upon changing a specific answer

Through change sets, Clause9 allows you to change datafields, terms, styling, etc. that apply when certain answers are given. However, it is not possible for an answer to change some other answer. Clojure functions allow you to resolve this limitation.

Suppose you are creating a contract and you want to give the user the option to pre-fill answers in a single click. For example, suppose you want to give the users the option to choose between “neutral” and “aggressive” default answers.

Questions to create

  1. Create a text-question with title “Which style do you want?” with identifier “style” that contains two predefined answers: “neutral” and “aggressive”. Set the “Free answers?” option to “Not allowed”.

  2. Create a yes/no-question “Is recourse allowed?” with identifier “recourse”.

  3. Create a currency-question “Which liability cap applies?” with identifier “cap” that contains two predefined answers (200 EUR and 5000 EUR).

Clojure code

(defn action-fn [q a]
  (case a
    "neutral" (do (set-answer "recourse" true)
                  (set-answer "cap" (->CurrencyValue 50000000 :EUR)))
    "aggressive" (do (set-answer "recourse" false)
                  (set-answer "cap" (->CurrencyValue 2000000 :EUR)))
    nil))

(assoc question :action-fn action-fn)

This code extends the question var (which is assigned the current question by Clause9 upon initialization of the Clojure environment) with an action-function.

This action-function takes two arguments (the question and the answer-value). It then checks which answer was given, and sets the answer of the two other questions to the desired values.

Note that the currency-values are integers multiplied by 10000 to make room for potential decimals.

The result is as follows:

PreviousCustom functions

Last updated 1 year ago

To do so, show the options of the warning-question, click on the button and add the following Clojure code:

The code uses so-called “Hiccup-style” Clojure-code for creating user interfaces in a browser (see an ). It essentially creates:

Add a to the first question, and insert the following code:

in-depth introduction