diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..14bc68c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/nbproject/private/ \ No newline at end of file diff --git a/LICENSE b/LICENSE index 26845e7..794ef06 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Che Guevara +Copyright (c) 2016 relbraun Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md new file mode 100644 index 0000000..585155a --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# yii2-repeater + +Repeater like http://briandetering.net/repeater + +##How to use + +install using composer: +`composer require kv4nt/yii2repeater` + +put this code in your form: +``` + '@app/modules/admin/views/***/repeater_view_file', + 'appendAction' => \yii\helpers\Url::to(['add-item-action']), + 'removeAction' => \yii\helpers\Url::to(['remove-item-action']), + 'form' => $form, + 'models' => $models, //The existing related model | example: $model->items + ]) ?> +``` +in your desired controller ypu have to put tis code: +``` +public function actions() + { + return [ + 'add-item-action' => [ + 'class' => 'kv4nt\yii2repeater\actions\AppendAction', + 'model' => 'app\models\Item', + 'contentPath' => '@app/modules/admin/views/***/repeater_view_file', //related to current controller + ], + 'remove-item-action' => [ + 'class' => 'kv4nt\yii2repeater\actions\DeleteAction', + 'model' => 'app\models\Item', + ] + ]; + } +``` +And this is an example of the repeater_view_file.php reminded above: +``` +
+
+ + 'form-control']) ?> +
+
+ + 'form-control']) ?> +
+
+``` \ No newline at end of file diff --git a/Repeater.php b/Repeater.php new file mode 100644 index 0000000..b6c7ad2 --- /dev/null +++ b/Repeater.php @@ -0,0 +1,68 @@ +getView(); + $this->view->registerJs('var deleteQuestionMessage="' . Yii::t('yii2-repeater', 'Do you really want to delete this item?') . '";', yii\web\View::POS_HEAD); + RepeaterAsset::register($view); + $data = Json::encode(['append' => $this->appendAction, 'remove' => $this->removeAction]); + echo "
"; + echo "
"; + foreach ($this->models as $k => $model) + { + $content = $this->render($this->modelView, array_merge(['model' => $model, 'form' => $this->form, 'id' => $model->id], $this->additionalData)); + echo $this->render('repeater', ['content' => $content, 'model' => $model, 'id' => $model->id]); + } + echo "
"; + $js = "new window.repeater($data)"; + $this->view->registerJs($js); + } + +} diff --git a/RepeaterAsset.php b/RepeaterAsset.php new file mode 100644 index 0000000..216bbeb --- /dev/null +++ b/RepeaterAsset.php @@ -0,0 +1,23 @@ +controller->viewPath = dirname(__DIR__) . '/views'; + $id = \Yii::$app->request->post('id'); + $model = new $this->model(); + return $this->controller->renderPartial('repeater', ['model' => $model, 'contentPath' => $this->contentPath, 'id' => $id]); + } + +} diff --git a/actions/DeleteAction.php b/actions/DeleteAction.php new file mode 100644 index 0000000..fce25e8 --- /dev/null +++ b/actions/DeleteAction.php @@ -0,0 +1,34 @@ +request->post('id'); + $model = $this->model; + /** @var ActiveRecord $model */ + $model = $model::findOne($id); + $response = 0; + if ($model) + { + $response = $model->delete(); + } + + Yii::$app->response->format = Response::FORMAT_JSON; + return ['status' => $response]; + } + +} diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..052239b --- /dev/null +++ b/composer.json @@ -0,0 +1,18 @@ +{ + "name": "kv4nt/yii2repeater", + "description": "An interface to add and remove a repeatable group of input elements for yii2", + "license": "MIT", + "homepage": "https://bitbucket.org/sagabeta/repeater", + "type": "yii2-extension", + "require": { + "php": "^5.4.3 || ^7.0", + "yiisoft/yii2-bootstrap": "*" + }, + "autoload": { + "psr-4": { + "kv4nt\\yii2repeater\\": "" + } + }, + "minimum-stability" : "stable", + "license": "MIT" +} diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..e69de29 diff --git a/js/js.js b/js/js.js new file mode 100644 index 0000000..9d31815 --- /dev/null +++ b/js/js.js @@ -0,0 +1,49 @@ +/** + * Created by Arielb on 11/24/2016. + */ +jQuery(function($){ + + var Repeater = function(url){ + var appendUrl = url.append, + deleteUrl = url.remove; + var self = this; + this.id = 1; + this.archive = []; + var $wrap = $('.ab-repeater .list-area'), + $recover = $('.ab-repeater .recover-btn'); + this.recover = function(){ + $wrap.append(this.archive.pop()); + if(this.archive.length === 0){ + $recover.prop('disabled', true); + } + }; + $(document).on('click', '.repeater-item .remove', function(){ + + if(confirm(deleteQuestionMessage)){ + self.archive.push($(this).parents('.repeater-item').clone()); + var $item = $(this).parents('.repeater-item'); + var data ={id:$item.data('id')}; + $.post(deleteUrl,data, function(data){ + $item.remove(); + $recover.prop('disabled', false); + }); + } + }); + + $('.new-repeater').click(function(){ + var data ={id:self.id}; + data[yii.getCsrfParam()]=yii.getCsrfToken(); + data.additionalData = $('.repeater-item').find('input,select,textarea').serialize(); + data.id = self.id; + $.post(appendUrl,data, function(data){ + $wrap.append($(data)); + }); + self.id++; + }); + $recover.click(function(){ + self.recover(); + }) + }; + + window.repeater = Repeater; +}); \ No newline at end of file diff --git a/views/repeater.php b/views/repeater.php new file mode 100644 index 0000000..df1e082 --- /dev/null +++ b/views/repeater.php @@ -0,0 +1,20 @@ + + +
+
+ + render($contentPath, ['model' => $model, 'id' => $id]); + } + ?> + +
+ X +
+
+