[DEPRECATED] AjaxFranceLabs Framework architecture and mechanism

Ajaxfrancelabs is deprecated as of Datafari v6.0 aside from specific admin and search expert functionalities. Please refer to https://datafari.atlassian.net/wiki/spaces/DATAFARI/pages/1517813761 for any search UI related task.

AjaxFranceLabs is a contribution from our company so that the community can manipulate Datafari through an Ajax Framework.

Spiritually, it is a child of the AjaxSolr framework, and you will see many similarities, in particular at the architecture level. The AjaxSolr has been a great source of inspiration for us.

Still, the code itself has been done from scratch (except for 2 classes which are almost copy pastes), as there were parts that were rather different, because of the differences between Datafari and Solr.

Although it is not part of the framework per se, we gave a particular care to the widgets that make use of our framework, because we know that you'll probably start with these widgets in order to get a hands on on our framework (you may even want to keep them as they are).

Code Structure

The framework contains the following folders:

  • core: the main classes of the framework

  • manager: implemented managers

  • module: the different modules

  • widgets: the different interface widgets

A widget is a part of the user interface (UI) which is attached to a DOM element.
A module is an extension of the widgets.
Eg: my result widget displays all the documents found by the search query and my favorite module will add “stars” to those documents title in order to save them to my favorite documents.

Architecture diagram

Interaction between the different components

The manager acts as a master controller. The widgets and modules are dealing with the manager in order to get the information they need and to modify the query request.

The parameter store stores the different parameter necessary to process the search query.

When a request query has to be processed, the manager calls a web service which receives the search query. This web service answers back to the manager, which stores the result in a variable (response) that the different components can access.

Class diagram

Core

AjaxFranceLabs offers different utility methods:

  • string tinyUrl(url, length)

    A method that reduces the length of the url given in parameter. Adds ‘…’ at the end if the url have been tined. Leaves everything after the last / (page name) in the url. length is set to 75 by default.

  • string tinyString(str, length)

    A method that reduces the length of the given string in parameter. Adds ‘…’ at the end if the string have been tined. length is set to 25 by default.

  • string truncate(string, length)

    Reduces the size of a string if the length of it is superior at length. This method will not slice a word in two if the max length is reach but keep it and add ‘…’ at the end.

  • <void addMultiElementClasses(source)

    Adds the following classes to the different elements of the source:

    • first | middle | last

    • odd | even

    • e-* where * is the index of the element in the source

    Thus you have all the necessary selectors for JavaScript and CSS.

  • void clearMultiElementsClasses(source)

    Remove the classes first, middle, last, even, odd, e-* from the elements of source.

  • boolean isString(obj)

    Returns true if obj is a string.

  • boolean isRegExp(obj)

    Returns true if obj is a RegExp

  • boolean equals(foo, bar)

    Compares the two objects given. Evaluates RegExp.

  • boolean empty(mixed_var)

    Returns true if the mixed_var is empty (‘0’, 0, null, undefined, false, “”)

  • string trim(str, charlist)

    Removes the invisible characters on the beginning and end of the string str. charlist is an optional parameter.

  • string extractLast(term)

    Returns the last term of term (used for the autocomplete widget).

  • array split(val)

    Splits val on the invisible character \u200c (used for the autocomplete widget).

  • object extend(target, …)

    Extends the object target with the other arguments given.

  • string capitalize(string)

Sets the first letter of a word to upper case. The word is given as a parameter.

The main classes of the framework are:

  • AbstractManager

  • AbstractWidget

  • AbstractFacetWidget

  • AbstractModule

  • Parameter

  • ParameterStore

Any class class has to extend one of these or the AjaxFranceLabs.Class. For this, use the .extend method provided by the AjaxFranceLabs.Class and any of the previous one.

Architecture of the main classes of the framework

AbstractManager

The manager is the main class of the framework. It is the master controller, the crossroad of all the information going in and out.
This class has to be extended in order to implement executeRequest() which have to make the call to the web service.

Insert architecture of the abstract manager here

Variables

  • constellio: boolean set to true by default. Set to false when using Solr. When set to true, the manager will load your constellio collections

  • serverUrl: address where the web service calls have to be made

  • servlet: servlet that have to be used for the web service calls

  • response: contains the last response from a search query on the search engine

  • widgets: contains all the widgets of the manager

  • modules: contains all the modules of the manager

  • store: a store that contains all the parameters of the search query

  • collections: the list of collections of the Constellio

  • collection: the collection currently used

connectionInfo: { autocomplete: { serverUrl: 127.0.0.1, servlet: 'select', queryString: 'callFunction=getInformations&type=user } }

Methods

  • init: import collections if using constellio, initializes the widgets and modules

  • addModule: adds the module provided in parameter to the module collection (“array”)

  • addWidget: adds the widget provided in parameter to the widget collection (“array”)

  • handleResponse: executes the afterRequest method from all the widgets and modules after the search query has been processed

  • makeRequest: executes the beforeRequest method from all the widgets and modules before processing the search query

  • executeRequest: must be implemented in a Manager object, this is the method which calls the web service.

  • getWidgetByID: gets the handle to the widget with ID specified as input.

  • makeDefaultRequest: performs a select all (*:*) request and updates the address bar with the search query.

Parameter and ParameterStore

Insert architecture parameter/parameterstore

Parameter

Variables

  • name: name of the parameter

  • value: value of the parameter

  • locals: local variables for nested request

Methods

  • val: if a parameter is given, change the value of the parameter, return the value instead

  • local: if value is given, changes the value of the local parameter, returns its value instead

  • remove: removes a local parameter

  • string: toString method of the parameter

  • parseString: parses a string to create the parameter

  • valueString: transforms value into a string if it is an array and encodes special characters

  • parseValueString: decodes special characters and transforms the string in array if necessary

  • escapeValue: quotes the string

ParameterStore

Variables

  • params: a collection of the parameters

Methods

  • isMultiple: returns true if the parameter has multiple value

  • get: returns the parameter, creates it if it does not exists

  • values: return the value(s) of the parameter

  • add: add a new parameter, creates an empty Parameter if only name is given

  • remove: deletes a parameter

  • addByValue: creates a new Parameter

  • removeByValue: removes a parameter with the given name and value

  • string: the toString method of the parameterStore that returns all the parameters on a string form

  • parseString: parses a string to creates the parameters

  • find: check if a parameter exists with the given name and value

  • isParamDefined: helper function to check whether the given parameter name in input is defined or not inside the parameter store.

AbstractWidget

All the widgets have to extend the AjaxFranceLabs.AbstractWidget class or the AjaxFranceLabs.AbstractFacetWidget class.

AbstractWidget

Variables

  • id: a unique id for the widget

  • elm: element where the widget will be build

  • manager: a reference to the widget’s manager

  • type: the type of the widget

Methods

  • buildWidget: a method that build the main DOM structure of your widget.

  • beforeRequest: code that have to be executed before the manager send the search query to the web service. This is mainly used when you have to add parameters to the search query, like the content of the search bar.

  • afterRequest: code that will be executed after the search query is done. This is mainly used when you have to update the content of your widget, for example, empty previous result list and include the new result instead.

  • reset: implement this method to reset the widget (notably after user input).

AbstractFacetWidget

Variables

  • field: the referring field

  • selectionType: can take 3 values depending on how you can select facet values:

    • AND: intersection of facet values

    • OR: document contains at least one facet value

    • ONE: can select one facet value at a time

  • returnUnselectedFacetValues: if set to true, values for the unselected facet will be returned anyway (default: false)

Methods

  • selectHandler: callback method when a facet element is selected.

  • unselectHandler: callback method when a facet element is unselected.

AbstractModule

Modules are extension of widgets, they will modify them once they are built.

Variables

  • id: a unique id for the module

  • manager: a reference to the module’s manager

Methods

  • beforeRequest: code that have to be executed before the manager send the search query to the web service.

  • afterRequest: code that will be executed after the search query is done.

Sequence diagram

Execution of a search query

  1. The element (widget, external user or program) triggers a request to the search web service from the manager using the method makeRequest()

  2. The manager first calls the beforeRequest() method of all the widgets and modules it controls. Thus the different widget can, for example, add parameters to the search query

  3. The manager then executes the search query on the web service using the method executeRequest() and wait for its response

  4. When the manager receives the response, it stores it into a local variable (reponse) accessible from all the widgets and modules it controls

  5. Finally, the manager executes the afterRequest() method of all the widgets and modules it controls, thus, they can update their data

Widget calling a web service

In order to illustrate this example, I will take the case of the AutocompleteWidget

  1. A user types some text in an input field which has an autocomplete widget attached to it

  2. The autocomplete widget retrieves the data entered by the user into the field and triggers the executeRequest() method from its manager to retrive the suggestions

  3. The manager answers to the autocomplete widget when it receives the results

  4. The autocomplete widget displays the results