# Join Action

### Join-Action

I2D provides a unique way of performing a join between **data** and the **graphical** **Elements**. Using **Join-Actions** one can define **enter(New), exit(Obsolete), update** actions on Dom elements.&#x20;

It is a new way to define the relationship between data and the elements.

```
let joinHandle = renderer.join([], el, {
                         joinOn: function(d){ },
                         action:{
                            enter: function (newDataArr) {},
                            exit: function (nodes) {},
                            update: function (nodes) {}
                         }
                      }
             );
```

The join method takes **data array**, **element selector,** and **action** **object** as arguments. **Action object** comprises of **joinOn (**&#x6A;oin key) and **actions - enter, update, and exit.**

Join API returns a set of [handle](https://github.com/I2Djs/I2Djs/wiki/Join-Action/_edit#join-handle)s to interact with the data/nodes. Using handle one can **push** the new data or **pop** or **remove** specific value from the data array, which internally triggers the respective actions. This mechanism boosts the application performance by avoiding unnecessary join executions.

### #.join(dataArray, selector, **Actions**);

**#dataArray**

Data is specified as an array of values.

```
let data = [{id:1, label: 'First'},{id:2, label: 'Second'},{id:3, label:'third'}]
```

#### **#Selector**

A selector is a valid CSS selector string - **(.)Class, (#)Id, NodeName** . It supports multiple selectors, comma separated, to perform join across DataArray and the individual selector elements. In the below example join takes place between DataArray - 'circle' Elements and DataArray - 'text' elements.

This approach helps in keeping the logic compact by eliminating redundant Join code.

#### #Actions Object

ActionsObject is comprised of actions **(Enter, Exit, update)** and the Join key specifier clause (**joinOn**).

**JoinOn \[optional] :**&#x20;

It's an access function to specify the join Key. If not specified, default behavior join-by-index will be considered.&#x20;

#### Actions **:**&#x20;

* **Enter \[optional]:** It's a function that defines an action for the new data. It receives an object as an input, with elementSelector property holding the corresponding new data array. New Data array has to be used with **createEls()** to create Elements, internally it binds the data object to the element. In the below example, the Enter action creates Circle and Text elements for the new Data.
* **Update \[optional]:** The update method defines an action on the nodes of the retained dataset. Update action receives an object with elementSelector property holding respective nodes collection.
* **Exit \[optional]:** The Exit method defines action on the nodes corresponding to the obsolete dataset. Just like update action, exit action also receives an object with elementSelector property holding respective nodes collection.

#### Example

```
let data = [{id:1, label: 'First'},{id:2, label: 'Second'},{id:3, label:'third'}]


let joinRef = renderer.join(data,'circle,text',{
                         joinOn:function(d){
                             return d.id;
                         },
                         action:{
                             enter: function(data){
                                 this.createEls(data.circle,{
                                          el:'circle',
                                          attr:{
                                                 x:function(d){return d.id*10},
                                                 y:function(d){return d.id*10},
                                                 r:5
                                          },
                                          style:{
                                                 fill:'green'
                                          }
                                });
                                this.createEls(data.text,{
                                          el:'text',
                                          attr:{
                                                 x:function(d){return d.id*10},
                                                 y:function(d){return d.id*10 + 20},
                                                 text: function(d) { return d.label }
                                          },
                                          style:{
                                                 fill: 'black',
                                                 text-anchor: 'middle'
                                          }
                                });
                             },
                             exit: function(nodes){
                                 nodes.circle.remove();
                                 nodes.text.remove();
                             },
                             update: function(nodes) {
                                 nodes.circle.setStyle('fill', 'red');
                                 nodes.text.text('fill', function(d){
                                    return d.label;
                                 });

                             }
                     }
                })
```

### Join Handles:

Join API returns handles to interact with the Data. Using handle one can **push** the new data or **pop** data or **remove** specific data/Data array, which internally triggers the respective actions. This mechanism boosts the application performance by avoiding unnecessary join executions.

**joinRef.join(\[Data]):**  It's useful in re-executing the complete actions for the new data set. Accepts Data Array and Performs complete join-actions executions.

```
joinRef.join(data)
```

**#.push(***data***):**  If you push one or more new data elements, Enter action will be triggered for the new data elements.

```
joinRef.push({id:100}) // triggers enter action
```

**#.pop():**  Pop removes the last element from the data array and triggers Exit action.

```
joinRef.pop() // triggers Exit action for the Popped object 
```

**#.remove(***data***):**  Accepts Data Value or array of values. Respective data will be removed from the Data array and triggers the Exit action.

```
joinRef.remove([{id:50},{id:20}]) // removes 2 data elements from array, triggers exit action
```

**#.update():**  To manually trigger the update action.

```
joinRef.update()
```
