PHPackages                             synatree/yii2-dynamic-relations - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. synatree/yii2-dynamic-relations

ActiveYii2-extension[Utility &amp; Helpers](/categories/utility)

synatree/yii2-dynamic-relations
===============================

Allows Yii2 views to contain a dynamically expanding set of fields based on model relations.

112.8k16[1 issues](https://github.com/synatree/yii2-dynamic-relations/issues)[2 PRs](https://github.com/synatree/yii2-dynamic-relations/pulls)PHP

Since Dec 21Pushed 10y ago4 watchersCompare

[ Source](https://github.com/synatree/yii2-dynamic-relations)[ Packagist](https://packagist.org/packages/synatree/yii2-dynamic-relations)[ RSS](/packages/synatree-yii2-dynamic-relations/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

Dynamic Relations Extension
===========================

[](#dynamic-relations-extension)

This extension came about after I googled in vain for such things as:

- Create 'child' models from a 'master' view dynamically
- Add Inputs to Yii2 views dynamically
- Use Yii2 widgets in related models
- Add fields to a form dynamically

Hopefully the above saves somebody else some time searching.

What does this do?
------------------

[](#what-does-this-do)

Sometimes a picture is worth 1000 words: [![Screenshot of Basic Functionality](https://camo.githubusercontent.com/91d05898aed07f58faa4ff9367dc187f396bfd57b722b033afcb283694dac9c4/687474703a2f2f73796e61747265652e636f6d2f6173736574732f706572736973742f796969322d64796e616d69632d72656c6174696f6e732d6578616d706c652e706e67 "Screenshot of Basic Functionality")](https://camo.githubusercontent.com/91d05898aed07f58faa4ff9367dc187f396bfd57b722b033afcb283694dac9c4/687474703a2f2f73796e61747265652e636f6d2f6173736574732f706572736973742f796969322d64796e616d69632d72656c6174696f6e732d6578616d706c652e706e67)

Allows Yii2 views to contain a dynamically expanding set of fields based on model relations.

This system allows you to define a view, conventionally called \_inline.php, that will be auto-loaded each time a user hits the "add" button on your form.

Behind the scenes, the module takes care of saving the related records if they are new, updating them if they have been changed, and removing them if deleted.

Basically this is a way to add an arbitrarily expanding set of related records to your model using Ajax.

It's also been designed to intellegently move the JavaScripts and event bindings that your view's widgets may use so as not to conflict with each other when multiple "identical" views are added via ajax. Frankly, it's managing the JavaScript conflicts that arise that is the largest time-saver here.

I'm not sure how big of a deal the security implications actually are, but to be safe I've also implemented the ajax request portions of the code tied to the user's session, so replaying the same requests after the user has lost their session should not be possible. The way it's setup also basically hides the real name and path of the inline view; I just didn't like the idea of the script leaking server-side file paths in the HTML code.

Installation
------------

[](#installation)

The preferred way to install this extension is through [composer](http://getcomposer.org/download/).

Either run

```
php composer.phar require synatree/yii2-dynamic-relations "dev-master"

```

or add

```
"synatree/yii2-dynamic-relations": "dev-master"

```

to the require section of your `composer.json` file.

Next, you must add the following to your module config:

```
    'modules' => [
    ...
		'dynamicrelations' => [
			'class' => '\synatree\dynamicrelations\Module'
		],
    ...
```

Usage
-----

[](#usage)

The first thing you should do is to create a view called \_inline.php for the model you which to use dynamically. This view can include arbitrary widgets, it's been tested with some widgets from Krajee.

This is the most complicated part, because we have to ensure that every time this view is invoked, the HTML and the script generated are unique.

You'll also have to tell DynamicRelations how to add and remove models by providing routes.

Finally, you'll have to maintain a certain structure in your field names so that the widget can pick up new vs existing models upon submit. Example:

```
use synatree\dynamicrelations\DynamicRelations;
use kartik\widgets\ActiveForm;
use kartik\datecontrol\DateControl;
use yii\helpers\Url;

/* @var $this yii\web\View */
/* @var $model app\models\BusinessHours */
/* @var $form kartik\widgets\ActiveForm */

// generate something globally unique.
$uniq = uniqid();

if( $model->primaryKey )
{
    // you must define an attribute called "data-dynamic-relation-remove-route" if you plan to allow inline deletion of models from the form.

	$removeAttr = 'data-dynamic-relation-remove-route="' .
		Url::toRoute(['business-hours/delete', 'id'=>$model->primaryKey]) . '"';
	$frag = "BusinessHours[{$model->primaryKey}]";
}
else
{
    $removeAttr = "";
    // new models must go under a key called "[new]"
    $frag = "BusinessHours[new][$uniq]";
}

?>
>

    .... More widgets use the same structure as above ....

```

The next step is to setup the controller to save the related models you're expecting to receive. In the below example, we only have to add one small line to each of the create and update action methods.

```
use synatree\dynamicrelations\DynamicRelations;
use app\models\BusinessHours;
use yii\web\Controller;

class SomeController extends Controller
{
    /**
	 * Creates a new SomethingModel model.
	 * If creation is successful, the browser will be redirected to the 'view' page.
	 * @return mixed
    */

    public function actionCreate()
    {
        $model = new SomethingModel();

            if ($model->load(Yii::$app->request->post()) && $model->save()) {
				// this next line is the only one added to a standard Gii-created controller action:
                DynamicRelations::relate($model, 'hours', Yii::$app->request->post(), 'BusinessHours', BusinessHours::className());
                //           Parent Model --^       ^-- Attribute    ^-- Array to search  ^-- Root Key  ^-- Model Class Name
                return $this->redirect(['view', 'id' => $model->primaryKey]);
            } else {
                return $this->render('create', [
                    'model' => $model,
                ]);
            }
    }

    public function actionUpdate($id)
    {
        ...
        if ($model->save()) {
            // this next line exactly the same as in actionCreate:
            DynamicRelations::relate($model, 'hours', Yii::$app->request->post(), 'BusinessHours', BusinessHours::className());
            return $this->redirect(['view', 'id' => $model->boatShowId]);
        } else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
        ...
    }
}
```

In order to support Ajax delete of related records, modify your related model controller:

```
 /**
     * Deletes an existing BusinessHours model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @return mixed
     */
    public function actionDelete($id)
    {
        $this->findModel($id)->delete();
        if(! Yii::$app->request->isAjax){
                return $this->redirect(['index']);
        }
        else
        {
                return "OK";
        }
    }
```

Finally, in your view for the parent model, include lines like the following for each related model you want to add dynamically.

```
use synatree\dynamicrelations\DynamicRelations;

```

That should do it. I hope this helps people, I really wanted this feature.

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance18

Infrequent updates — may be unmaintained

Popularity28

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 95.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/5013f51d2f9796b9f6e8487e4bebae5ed5e8f3f753cced498c23e871c4481251?d=identicon)[synatree](/maintainers/synatree)

---

Top Contributors

[![synatree](https://avatars.githubusercontent.com/u/7294077?v=4)](https://github.com/synatree "synatree (21 commits)")[![sblaut](https://avatars.githubusercontent.com/u/13192008?v=4)](https://github.com/sblaut "sblaut (1 commits)")

### Embed Badge

![Health badge](/badges/synatree-yii2-dynamic-relations/health.svg)

```
[![Health](https://phpackages.com/badges/synatree-yii2-dynamic-relations/health.svg)](https://phpackages.com/packages/synatree-yii2-dynamic-relations)
```

###  Alternatives

[knplabs/dictionary-bundle

Are you often tired to repeat static choices like gender or civility in your apps ?

88284.0k](/packages/knplabs-dictionary-bundle)[aura/dispatcher

Creates objects from a factory and invokes methods using named parameters; also provides a trait for invoking closures and object methods with named parameters.

3695.0k3](/packages/aura-dispatcher)[uestla/simplex-calculator

Simple tool for linear programming problems solving

427.6k](/packages/uestla-simplex-calculator)[whitecube/laravel-sluggable

Generate slugs for your models automatically - even with translated attributes

2027.2k](/packages/whitecube-laravel-sluggable)[zunnu/cake-htmx

Htmx plugin for CakePHP

187.1k1](/packages/zunnu-cake-htmx)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
