updated core to 7.58 (right after the site was hacked)
This commit is contained in:
693
sites/all/modules/contrib/fields/hierarchical_select/API.txt
Normal file
693
sites/all/modules/contrib/fields/hierarchical_select/API.txt
Normal file
@@ -0,0 +1,693 @@
|
||||
|
||||
Terminology
|
||||
-----------
|
||||
- item: an item in the hierarchy. A hierarchy can also be seen as a tree. In
|
||||
that case, an item can be either a parent or a child. However, if
|
||||
"multiple parents" are supported (i.e. a child can have multiple
|
||||
parents), then it's actually not a tree but a directed acyclic graph
|
||||
(see http://en.wikipedia.org/wiki/Directed_acyclic_graph), in which
|
||||
each case technically is a "node".
|
||||
An example: in the case of taxonomy, this is the term id (tid).
|
||||
- label: the label associated with an item in the hierarchy. You may now it
|
||||
as "title" or something else similar.
|
||||
An example: in the case of taxonomy, this is the actual term.
|
||||
- item type: a per-level, human-readable name that describes what kind of
|
||||
items that level contains.
|
||||
- entity: an item is often associated with an entity. E.g. a term is usually
|
||||
associated with a node.
|
||||
- form element: a form element allows the developer to assign a new value to
|
||||
a #type property in a form item. Examples of form elements
|
||||
supported by Drupal core are: select, checkboxes, textfield.
|
||||
- form item: an instance of a form element, with various other properties
|
||||
defined, such as #title, #default_value and #description. These
|
||||
are used to define a form in Drupal.
|
||||
- Hierarchical Select: this is the name of the module.
|
||||
- hierarchical_select: this is the internal name of the Hierarchical Select
|
||||
form element.
|
||||
- hierarchical select: (note the difference in case) this is the part of the
|
||||
widget with the multiple selects.
|
||||
- dropbox: this is the part of the widget where the selections are stored when
|
||||
multiple selections are allowed.
|
||||
|
||||
|
||||
Form API usage
|
||||
--------------
|
||||
You have to make sure your form item is using the "hierarchical_select" form
|
||||
element type:
|
||||
|
||||
$form['select_some_term'] = array(
|
||||
'#type' => 'hierarchical_select',
|
||||
'#title' => t('Select the tag you wish to use.'),
|
||||
'#size' => 1,
|
||||
'#config' => array(
|
||||
'module' => 'hs_taxonomy',
|
||||
'params' => array(
|
||||
'vid' => $vid,
|
||||
),
|
||||
'save_lineage' => 0,
|
||||
'enforce_deepest' => 0,
|
||||
'resizable' => 1,
|
||||
'level_labels' => array(
|
||||
'status' => 0,
|
||||
'labels' => array(
|
||||
0 => t('Main category'),
|
||||
1 => t('Subcategory'),
|
||||
2 => t('Third level category'),
|
||||
),
|
||||
),
|
||||
'dropbox' => array(
|
||||
'status' => 0,
|
||||
'title' => t('All selections'),
|
||||
'limit' => 0,
|
||||
'reset_hs' => 1,
|
||||
'sort' => 1,
|
||||
),
|
||||
'editability' => array(
|
||||
'status' => 0,
|
||||
'item_types' => array(),
|
||||
'allowed_levels' => array(
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 1,
|
||||
),
|
||||
'allow_new_levels' => 0,
|
||||
'max_levels' => 3,
|
||||
),
|
||||
'entity_count' => array(
|
||||
'enabled' => 0,
|
||||
'require_entity' => 0,
|
||||
'settings' => array(
|
||||
'count_children' => 0,
|
||||
'entity_types' => array(),
|
||||
),
|
||||
),
|
||||
// These settings cannot be configured through the UI: they can only be
|
||||
// overridden through code.
|
||||
'animation_delay' => 400,
|
||||
'special_items' => array(),
|
||||
'render_flat_select' => 0,
|
||||
),
|
||||
'#default_value' => '83',
|
||||
);
|
||||
|
||||
Now, let's explain what we see here:
|
||||
1) We've set the #type property to "hierarchical_select" instead of "select".
|
||||
2) The #size property is inherited by the selects of the hierarchical select.
|
||||
You can use it to change a vertical size of the select (i.e. change how many
|
||||
items are displayed in the select, similar to a form select multiple).
|
||||
3) There's a new property: #config. This must be an
|
||||
array. These are the items it can contain:
|
||||
- module (required)
|
||||
This will be passed through in the AJAX requests, to let Hierarchical
|
||||
Select know which module's hooks should be used.
|
||||
|
||||
- params (optional, may be necessary for some implementations)
|
||||
An array of parameters that will also be passed through in every AJAX
|
||||
request.
|
||||
e.g. In the case of taxonomy, this is the vocabulary id (vid). In case of
|
||||
content_taxonomy, there's three parameters: vid, tid and depth (tid allows
|
||||
one to define a new root, depth allows one to limit the depth of the
|
||||
displayed hierarchy).
|
||||
|
||||
- save_lineage (optional, defaults to 0)
|
||||
Triggers the lineage saving functionality. If enabled, the selection can
|
||||
consist of multiple values.
|
||||
|
||||
- enforce_deepest (optional, defaults to 0)
|
||||
Triggers the enforcing of a selection in the deepest level. If enabled, the
|
||||
selection will always be a single value.
|
||||
|
||||
- resizable (optional, defaults to 1)
|
||||
Makes the hierarchical select resizable.
|
||||
|
||||
- level_labels['status'] (optional, defaults to 0)
|
||||
Whether level labels should be enabled or not. When save_lineage is
|
||||
enabled, this will result in *empty* level labels.
|
||||
|
||||
- level_labels['labels'] (optional)
|
||||
An array of labels, one per level. The label for the first level should be
|
||||
the value of key 0.
|
||||
When enforce_deepest is set to:
|
||||
- 0, then you can provide n level labels, with n the number of levels
|
||||
- 1, then you can provide only one level label.
|
||||
|
||||
- dropbox['status'] (optional, defaults to 0)
|
||||
Whether the dropbox is enabled or not (the dropbox allows the user to make
|
||||
multiple selections).
|
||||
|
||||
- dropbox['title'] (optional, defaults to "All selections:")
|
||||
The title of the dropbox. The dropbox is the area where all selections are
|
||||
displayed when the dropbox is enabled.
|
||||
|
||||
- dropbox['limit'] (optional, defaults to 0, which means "no limit")
|
||||
Limit the number of selection that can be added to the dropbox. So this
|
||||
allows you the restrict the number of items that can be selected when
|
||||
the dropbox has been enabled.
|
||||
|
||||
- dropbox['reset_hs'] (optional, defaults to 1, which means "do reset")
|
||||
Determines what will happen to the hierarchical select when the user has
|
||||
added a selection to the dropbox.
|
||||
|
||||
- dropbox['sort'] (optional, defaults to 1, which means "do sort")
|
||||
Determines whether the items in the dropbox will be automatically sorted.
|
||||
|
||||
- editability['status] (optional, defaults to 0)
|
||||
Allow the user to create new items in the hierarchy.
|
||||
|
||||
- editability['item_types'] (optional, defaults to the empty array)
|
||||
Only meaningful when editable is set to TRUE.
|
||||
Set the item type for each level. E.g.: "country" for the first level,
|
||||
"region" for the second and "city" for the third. When the user then wants
|
||||
to create a new item, the default label for the new item will be of the
|
||||
form "new <item type>", e.g. "new region".
|
||||
|
||||
- editability['allowed_levels'] (optional, defaults to 1 for each level)
|
||||
Only meaningful when editable is set to TRUE.
|
||||
Specify in which levels the user is allowed to create new items. In the
|
||||
example, the user is only allowed to create new items in the third level.
|
||||
When a setting for a level is ommitted, it defaults to 1 (i.e. allowed for
|
||||
that level). This means you only have to specify in which levels the user
|
||||
is not allowed to create new items.
|
||||
This only applies to *existing* levels: it does not affect the
|
||||
allow_new_levels setting (the next setting).
|
||||
|
||||
- editability['allow_new_levels'] (optional, defaults to 0)
|
||||
Only meaningful when editable is set to TRUE.
|
||||
Allow the user to create new levels, i.e. when a certain item does not yet
|
||||
have children, the user can create a first child for it (thus thereby
|
||||
creating a new level).
|
||||
|
||||
- editability['max_levels'] (optional, defaults to 3)
|
||||
Only meaningful when editable_settings['allow_new_levels'] is set to TRUE.
|
||||
Limits the maximum number of levels. Don't set this too high or you'll end
|
||||
up with very deep hierarchies. This only affects how deep new levels can be
|
||||
created, it will not affect the existing hierarchy.
|
||||
|
||||
- entity_count['enabled'] (optional, defaults to 0)
|
||||
Enables the display of entity counts, between parentheses, for each item in
|
||||
the hierarchy.
|
||||
|
||||
- entity_count['require_entity'] (optional, defaults to 0)
|
||||
Whether an item should only be displayed if it has at least one associated
|
||||
entity.
|
||||
|
||||
- entity_count['settings']['count_children'] (optional, defaults to 0)
|
||||
Whether the entity count should also count associated children of the entity.
|
||||
|
||||
- entity_count['settings']['entity_types'] (optional, defaults to array())
|
||||
Which types of entities should be counted. This is a list of checkboxes that
|
||||
allow the user to select entity types by bundles.
|
||||
|
||||
- animation_delay (optional, defaults to 400)
|
||||
The delay of each animation (the drop in left and right animations), in ms.
|
||||
|
||||
- special_items (optional, defaults to the empty array)
|
||||
Through this setting, you can mark each item with special properties it
|
||||
possesses. There currently are two special properties: 'exclusive' and
|
||||
'none'.
|
||||
Note: you should include these items in the hierarchy as if it were a
|
||||
normal item and then you can mark them as special through this property.
|
||||
* 'exclusive': Sometimes it's desirable to have exclusive lineages. When
|
||||
such an option is selected, the user should not be able to
|
||||
select anything else. This also means that nothing else in
|
||||
the dropbox can be selected: if the dropbox contains
|
||||
anything, it will be reset.
|
||||
Can be applied to multiple items.
|
||||
e.g. an 'entire_tree' item:
|
||||
'special_items' => array(
|
||||
'entire_tree' => array('exclusive'),
|
||||
)
|
||||
* 'none': Sometimes you want to replace the default '<none>' option by
|
||||
something else. This replacement should of course also exist in
|
||||
the root level.
|
||||
Can be applied to only one item.
|
||||
e.g. an 'any' item (used in hs_taxonomy_views):
|
||||
'special_items' => array(
|
||||
'any' => array('none', 'exclusive'),
|
||||
)
|
||||
And a final example for a better overview:
|
||||
'special_items' => array(
|
||||
'entire_tree' => array('exclusive'),
|
||||
'any' => array('none', 'exclusive'),
|
||||
)
|
||||
|
||||
- render_flat_select (optional, defaults to 0)
|
||||
Because the hierarchical_select form element consists of multiple form
|
||||
items, it doesn't work well in GET forms. By enabling this setting, a flat
|
||||
select will also be rendered, that contains only the selected lineages.
|
||||
Combine that with Drupal.HierarchicalSelect.prepareGETSubmit in the JS code
|
||||
(or, alternatively, the 'prepare-GET-submit' event that can be triggered,
|
||||
see the JavaScript events section for details) and you have a work-around
|
||||
(which, admittedly, only works when JS is enabled).
|
||||
|
||||
3) We *don't* specify a list of options: Hierarchical Select automatically
|
||||
generates the options for us, thanks to the 'module' and 'params' settings.
|
||||
|
||||
|
||||
Concepts
|
||||
--------
|
||||
- Item Unicity: each item in the hierarchy must be *unique*. It doesn't have
|
||||
to be numerical, it can also be a string.
|
||||
If your hierarchy does not have unique items by nature or by
|
||||
design (your items may be unique per level instead), that's
|
||||
not a problem. You can simply prepend the item's ancestors to
|
||||
get a unique item.
|
||||
e.g. you have an item "foobar" at the first, second and third
|
||||
levels. By prepending the ancestors using the dash as the
|
||||
separator, you'd get an item "foobar-foobar-foobar" at the
|
||||
third level.
|
||||
Also see the "Reserved item values" section.
|
||||
- #options: it's gone, because it was the inherent cause for scalability
|
||||
problems: if a hierarchy consists of 10,000 or even 100,000 items,
|
||||
this results in huge HTML being generated. Huge HTML means more
|
||||
processing power necessary, and more bandwidth necessary. So where
|
||||
does Hierarchical Select get its "options"? It uses the hooks that
|
||||
every implementation has to implement to only get what it needs.
|
||||
- The General Concept: you should think of Hierarchical Select as an abstract
|
||||
widget that can represent *any* hierarchy. To be able
|
||||
to display any hierarchy, you obviously need some
|
||||
universal way to "browse" a hierarchy.
|
||||
If you are familiar with C++ or Java iterators, this
|
||||
should come natural: the hooks you have to implement
|
||||
is what allows Hierarchical Select to iterate over your
|
||||
hierarchy. Then the heart of the iterator would be the
|
||||
root_level() and children() hooks. params() allows you
|
||||
to define which information is necessary before you can
|
||||
determine *which* hierarchy or which *part* of the
|
||||
hierarchy is being browsed. lineage() must return the
|
||||
lineage, i.e. the item itself and all its ancestors,
|
||||
this allows a hierarchy to be generated from just one
|
||||
(selected) item.
|
||||
|
||||
|
||||
Reserved item values
|
||||
--------------------
|
||||
- Ensure that your items don't have a "none", "all", "create_new_item" nor
|
||||
"label_\d+" values (the latter means "label_" followed by one or more
|
||||
digits). Your values should also not contain a pipe ("|"), since pipes are
|
||||
used to separate the selection of values that are sent back to the server
|
||||
in the callbacks.
|
||||
- Valid 'empty' selections (i.e. if you want to set the #default_value
|
||||
property of your form item), are -1 and the empty array. The empty string is
|
||||
also considered valid, because Drupal core's Taxonomy module uses this as
|
||||
the empty selection.
|
||||
|
||||
|
||||
Developer mode
|
||||
--------------
|
||||
When you are writing your implementation of the Hierarchical Select API, you
|
||||
will often wonder what Hierarchical Select is doing internally with the data
|
||||
you're feeding it. That's why there's a developer mode: it will show you this
|
||||
data, even the data generated in AJAX callbacks. It'll also show you the time
|
||||
it took to generate the lineage, to fill up the levels and to calculate the
|
||||
child info, to track down badly performing code.
|
||||
Also, when you're just creating a new HS config and it doesn't quite work
|
||||
right, it can be helpful to enable the developer mode. It will perform some
|
||||
basic diagnostics that might help you track down the cause.
|
||||
To use this, you must have a browser with console.log() support. Install
|
||||
Firebug Lite (http://getfirebug.com/lite.html) if your browser does not
|
||||
suport this. Next, go to Hierarchical Select's .module file and set the define
|
||||
for the HS_DEVELOPER_MODE constant to TRUE.
|
||||
When you now open Firebug (Firefox) or the Web Inspector (Safari), you'll see
|
||||
the debug output. New output is added after each callback to the server.
|
||||
|
||||
|
||||
Hierarchical Select implementations: gotcha's
|
||||
---------------------------------------------
|
||||
- "warning: Missing argument 1 for drupal_retrieve_form() …"
|
||||
This implies that your implementation's module weight is heavier than
|
||||
hierarchical_select.module. In that case, Hierarchical Select will not be
|
||||
able to detect hierarchical_select form items, preventing it from applying
|
||||
some magic, and AJAX updates won't work.
|
||||
|
||||
|
||||
Hierarchical Select compatibility: gotcha's
|
||||
-------------------------------------------
|
||||
- "Invalid response from server"
|
||||
This typically means that some functions could not be found when
|
||||
Hierarchical Select does an AJAX callback to the server, which in turn means
|
||||
that some code (some PHP file) has not been included, while it should have
|
||||
been. Instead of using module_load_include() or even require_once, you
|
||||
should use form_load_include(). This function is new in Drupal 7 and will
|
||||
ensure that all required PHP files are included automatically.
|
||||
|
||||
|
||||
Hierarchical Select API Tutorial
|
||||
--------------------------------
|
||||
Written by Stephen Barker of Digital Frontiers Media
|
||||
(http://drupal.org/user/106070) and reviewed by Wim Leers:
|
||||
http://drupal.org/node/532724
|
||||
|
||||
|
||||
Hierarchical Select Small Hierarchy
|
||||
-----------------------------------
|
||||
Hierarchical Select includes a Hierarchical Select API implementation that
|
||||
allows one to use a hardcoded hierarchy. When it becomes to slow, you should
|
||||
move the hierarchy into the database and write a proper implementation.
|
||||
Below you can find an example of how to use the hs_smallhierarchy module. Just
|
||||
change the $hierarchy array to suit your needs and off you go! Look at the
|
||||
code of hs_smallhierarchy.module for full details, but this code example
|
||||
should get you started.
|
||||
|
||||
$hierarchy = array(
|
||||
'win' => array(
|
||||
'label' => 'Windows',
|
||||
'children' => array(
|
||||
'xp' => array('label' => 'XP'),
|
||||
'vista' => array(
|
||||
'label' => 'Vista',
|
||||
'children' => array(
|
||||
'x86' => array('label' => '32-bits'),
|
||||
'x64' => array('label' => '64-bits'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$form['select_some_term'] = array(
|
||||
'#type' => 'hierarchical_select',
|
||||
'#title' => t('Select the tag you wish to use.'),
|
||||
'#size' => 1,
|
||||
'#config' => array(
|
||||
'module' => 'hs_smallhierarchy',
|
||||
'params' => array(
|
||||
'hierarchy' => $hierarchy,
|
||||
'id' => 'my-hierarchy-about-windows',
|
||||
'separator' => '|',
|
||||
),
|
||||
'save_lineage' => 0,
|
||||
'enforce_deepest' => 0,
|
||||
'resizable' => 1,
|
||||
'level_labels' => array(
|
||||
'status' => 0,
|
||||
'labels' => array(
|
||||
0 => t('Main category'),
|
||||
1 => t('Subcategory'),
|
||||
2 => t('Third level category'),
|
||||
),
|
||||
),
|
||||
'dropbox' => array(
|
||||
'status' => 0,
|
||||
'title' => t('All selections'),
|
||||
'limit' => 0,
|
||||
'reset_hs' => 1,
|
||||
'sort' => 1,
|
||||
),
|
||||
'editability' => array(
|
||||
'status' => 0,
|
||||
'item_types' => array(),
|
||||
'allowed_levels' => array(
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 1,
|
||||
),
|
||||
'allow_new_levels' => 0,
|
||||
'max_levels' => 3,
|
||||
),
|
||||
'entity_count' => array(
|
||||
'enabled' => 0,
|
||||
'require_entity' => 0,
|
||||
'settings' => array(
|
||||
'count_children' => 0,
|
||||
'entity_types' => array(),
|
||||
),
|
||||
),
|
||||
// These settings cannot be configured through the UI: they can only be
|
||||
// overridden through code.
|
||||
'animation_delay' => 400,
|
||||
'exclusive_lineages' => array(),
|
||||
'render_flat_select' => 0,
|
||||
),
|
||||
'#description' => 'Put your description here',
|
||||
'#default_value' => 'win|xp|x86',
|
||||
);
|
||||
|
||||
|
||||
Hooks
|
||||
-----
|
||||
1) hook_hierarchical_select_params();
|
||||
Returns an array with the names of all parameters that are necessary for
|
||||
this implementation to work.
|
||||
|
||||
2) hook_hierarchical_select_root_level($params, $dropbox = FALSE);
|
||||
Returns the root level of the hierarchy: an array of (item, label) pairs.
|
||||
The $dropbox parameter can is optional and can even ommitted, as it's only
|
||||
necessary if you need the dropbox to influence your hierarchy.
|
||||
|
||||
3) hook_hierarchical_select_children($parent, $params, $dropbox = FALSE);
|
||||
Gets the children of $parent ($parent is an item in the hierarchy) and
|
||||
returns them: an array of (item, label) pairs, or the empty array if the
|
||||
given $parent has no children.
|
||||
The $dropbox parameter can is optional and can even ommitted, as it's only
|
||||
necessary if you need the dropbox to influence your hierarchy.
|
||||
|
||||
4) hook_hierarchical_select_lineage($item, $params);
|
||||
Calculates the lineage of $item (array of items, with $item the last) and
|
||||
returns it. Necessary when the "enforce_deepest" option is enabled.
|
||||
|
||||
5) hook_hierarchical_select_valid_item($item, $params);
|
||||
Validates an item, returns TRUE if valid, FALSE if invalid.
|
||||
|
||||
6) hook_hierarchical_select_item_get_label($item, $params);
|
||||
Given a valid item, returns the label. Is only used for rendering the
|
||||
selections in the dropbox.
|
||||
|
||||
7) hook_hierarchical_select_create_item($label, $parent, $params);
|
||||
Given a parent item and the label of a new item, create a new item as a
|
||||
child of the parent item. When $parent == 0, this means a new item is being
|
||||
created at the root level.
|
||||
Optional hook. When this hook is not implemented, this functionality will
|
||||
never be used, even when you configure it that way in code.
|
||||
|
||||
8) hook_hierarchical_select_entity_count($item, $params);
|
||||
Given a item, get the number of entities (most of the time the entity type
|
||||
is 'node') that are related to the given item. Used for the entity_count
|
||||
and require_entity settings.
|
||||
Optional hook. When this hook is not implemented, this functionality will
|
||||
never be used, even when you configure it that way (i.e. when you enable
|
||||
the entity_count and require_entity settings).
|
||||
|
||||
9) hook_hierarchical_select_implementation_info();
|
||||
Return metadata about this implementation.
|
||||
This information is used to generate the implementations overview at
|
||||
admin/settings/hierarchical_select/implementations. The expected format is:
|
||||
|
||||
array(
|
||||
'hierarchy type' => t('Taxonomy'),
|
||||
'entity type' => t('Node'),
|
||||
'entity' => t('Story'),
|
||||
'context type' => t('Node form'),
|
||||
'context' => '',
|
||||
);
|
||||
|
||||
another example:
|
||||
|
||||
array(
|
||||
'hierarchy type' => t('Taxonomy'),
|
||||
'entity type' => t('Node'),
|
||||
'entity' => '',
|
||||
'context type' => t('Views exposed filter'),
|
||||
'context' => t('some view'),
|
||||
);
|
||||
|
||||
10) hook_hierarchical_select_config_info();
|
||||
Return metadata about each available user-editable configuration for this
|
||||
implementation.
|
||||
Optional hook. This information is used to generate the configurations
|
||||
overview at admin/settings/hierarchical_select/configs. The expected
|
||||
format is:
|
||||
|
||||
$config_info[$config_id] = array(
|
||||
'config_id' => $config_id,
|
||||
'hierarchy type' => t('Taxonomy'),
|
||||
'hierarchy' => t($vocabulary->name),
|
||||
'entity type' => t('Node'),
|
||||
'entity' => implode(', ', array_map('t', $entities)),
|
||||
'edit link' => "admin/content/taxonomy/edit/vocabulary/$vid",
|
||||
);
|
||||
|
||||
|
||||
Standardized configuration form
|
||||
-------------------------------
|
||||
Hierarchical Select 3 comes with a standardized configuration form:
|
||||
hierarchical_select_common_config_form(). This function accepts a lot of
|
||||
parameters, which allows you to use names typical to your module's hierarchy
|
||||
(e.g. 'leaf' instead of 'term' and 'tree' instead of 'vocabulary'). A submit
|
||||
handler is also provided, of course.
|
||||
An example:
|
||||
|
||||
// I'm not configuring all parameters here. For an example of that, see one
|
||||
// of the included modules.
|
||||
$form['foobar_hierarchical_select_config'] = hierarchical_select_common_config_form($module, $params, $config_id, $defaults, $strings, $max_hierarchy_depth, $preview_is_required);
|
||||
|
||||
// Add the the submit handler for the Hierarchical Select config form.
|
||||
$parents = array('foobar_hierarchical_select_config');
|
||||
$form['#submit'][] = 'hierarchical_select_common_config_form_submit';
|
||||
$form['#hs_common_config_form_parents'] = $parents;
|
||||
|
||||
|
||||
Configuration management
|
||||
------------------------
|
||||
It's now possible to export Hierarchical Select configurations, and there is a
|
||||
function to set the configuration of a certain Hierarchical Select. Combine
|
||||
the two and you can manage your Hierarchical Select configurations in code!
|
||||
An example:
|
||||
|
||||
// The exported configuration.
|
||||
$config = array( … );
|
||||
$config_id = $config['config_id];
|
||||
|
||||
// Apply the configuration.
|
||||
require_once(drupal_get_path('module', 'hierarchical_select') .'/includes/common.inc');
|
||||
hierarchical_select_common_config_set($config_id, $config);
|
||||
|
||||
|
||||
JavaScript events
|
||||
-----------------
|
||||
The Hierarchical Select module's JavaScript code triggers several events, to
|
||||
allow for advanced interactions.
|
||||
|
||||
You can find all hierarchical_select form items using this selector:
|
||||
|
||||
$('.hierarchical-select-wrapper');
|
||||
|
||||
You can find a *specific* hierarchical_select form item using this selector:
|
||||
|
||||
$('#hierarchical-select-x-wrapper');
|
||||
|
||||
where x is a number, or more accurately: a hsid (hierarchical select id).
|
||||
Retrieving all hsids in the current document can be done like this:
|
||||
|
||||
for (var hsid in Drupal.settings.HierarchicalSelect.settings) {
|
||||
// …
|
||||
}
|
||||
|
||||
Alternatively, you can use one of the transliterated class names. A wrapper
|
||||
for Hierarchical Select looks like this:
|
||||
<div class="hierarchical-select-wrapper
|
||||
hierarchical-select-level-labels-style-none
|
||||
hierarchical-select-wrapper-for-name-edit-taxonomy-1
|
||||
hierarchical-select-wrapper-for-config-taxonomy-1
|
||||
hierarchical-select-wrapper-processed"
|
||||
id="hierarchical-select-35-wrapper">
|
||||
…
|
||||
</div>
|
||||
Hence, you could also use selectors such as these, to achieve the same effect,
|
||||
but with more robust code:
|
||||
$('.hierarchical-select-wrapper-for-config-taxonomy-1:first')
|
||||
.trigger('enforce-update');
|
||||
$('.hierarchical-select-wrapper-for-name-edit-taxonomy-1:first')
|
||||
.trigger('enforce-update');
|
||||
|
||||
The following events are triggered:
|
||||
- change-hierarchical-select
|
||||
- update-hierarchical-select
|
||||
- create-new-item
|
||||
- cancel-new-item
|
||||
- add-to-dropbox (check https://www.drupal.org/node/1277068)
|
||||
- remove-from-dropbox
|
||||
- enforced-update
|
||||
- prepared-GET-submit
|
||||
All events are triggered *after* the animations have completed.
|
||||
|
||||
However, it's often useful to do something *before* an event (especially
|
||||
because all of the above events perform an AJAX request to the server). So,
|
||||
the equivalent "before" events exist as well:
|
||||
- before-update-hierarchical-select
|
||||
- before-create-new-item
|
||||
- before-cancel-new-item
|
||||
- before-add-to-dropbox
|
||||
- before-remove-from-dropbox
|
||||
- before-enforced-update
|
||||
There is one exception: when the cache is enabled, the "before update
|
||||
hierarchical select" event will not be triggered. This makes sense, because
|
||||
updates from the cache are instantaneous.
|
||||
|
||||
An example of binding a function to the 'create-new-item' event of the second
|
||||
(hsid == 1) hierarchical_select form item on the page:
|
||||
|
||||
$('#hierarchical-select-1-wrapper')
|
||||
.bind('create-new-item', function() {
|
||||
// …
|
||||
});
|
||||
|
||||
And finally, you can trigger a special event to enforce an update (this can be
|
||||
useful when you have changed a hierarchy through another form item, or for
|
||||
live previews, or …). You can then also pass additional information that will
|
||||
be POSTed. You can even disable normal updates, to manage that completely
|
||||
yourself via enforced updates. This allows you to write a Hierarchical Select
|
||||
implementation that gets some of its information ($params) from another form
|
||||
item!
|
||||
Suppose you'd like to enforce an update of the first (hsid == 0)
|
||||
hierarchical_select form item on the page:
|
||||
|
||||
$('#hierarchical-select-0-wrapper')
|
||||
.trigger('enforce-update');
|
||||
|
||||
Now let's move on to a more advanced example, in which we will disable normal
|
||||
updates and let another form item (here a select) provide a part of the
|
||||
information that will be used to render the Hierarchical Select. Effectively,
|
||||
this other form item will *influence* the hierarchy that will be presented by
|
||||
Hierarchical Select!
|
||||
|
||||
$(document).ready(function() {
|
||||
Drupal.settings.specialfilter = {};
|
||||
|
||||
// .specialfilter-first: a select form item
|
||||
// .specialfilter-second: a hierarchical_select form item
|
||||
|
||||
update = function() {
|
||||
var selection = Drupal.settings.specialfilter.currentSelection;
|
||||
|
||||
// Send an extra parameter via POST: dynamicParameter. This is the stored
|
||||
// selection.
|
||||
$('.specialfilter-second')
|
||||
.trigger('enforce-update',
|
||||
[
|
||||
{ name : 'dynamicParameter', value : selection }
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
attachHSBindings = function() {
|
||||
// When a user navigates the hierarchical_select form item, we still want to
|
||||
// POST the the extra dynamicParameter, or otherwise we will no longer have
|
||||
// a hierarchy in the hierarchical_select form item that really depends on
|
||||
// the select.
|
||||
$('.specialfilter-second .hierarchical-select > select')
|
||||
.change(function() { update(); });
|
||||
|
||||
$('.specialfilter-second')
|
||||
.unbind('enforced-update').bind('enforced-update', function() { return attachHSBindings(); });
|
||||
};
|
||||
|
||||
// Initialize after 25 ms, because otherwise the event binding of HS will
|
||||
// not yet be ready, and hence this won't have any effect
|
||||
setTimeout(function() {
|
||||
// Get the initial selection (before the user has changed anything).
|
||||
Drupal.settings.specialfilter.currentSelection = $('.specialfilter-first').attr('value');
|
||||
|
||||
// When the select form item changes, we want to *store* that selection, and
|
||||
// update the hierarchical_select form item.
|
||||
$('.specialfilter-first')
|
||||
.change(function() {
|
||||
// Store the current selection.
|
||||
Drupal.settings.specialfilter.currentSelection = $(this).attr('value');
|
||||
|
||||
update();
|
||||
});
|
||||
|
||||
$('.specialfilter-second')
|
||||
.trigger('disable-updates');
|
||||
|
||||
attachHSBindings();
|
||||
}, 25);
|
||||
});
|
||||
|
||||
The 'enforced-update' (notice the past tense!) event is triggered upon
|
||||
completion.
|
||||
An even more rarely used special event can be triggered to prepare the
|
||||
hierarchical_select form element for a get submit: the 'prepare GET submit'
|
||||
event. To use this event, the 'render_flat_select' setting should be enabled
|
||||
in the config.
|
||||
Reference in New Issue
Block a user