Browse Source

hasMany以及array表单支持嵌套table

jqh 3 years ago
parent
commit
c051cc10bb

+ 7 - 6
resources/views/form/hasmany.blade.php

@@ -20,7 +20,7 @@
                     <div class="form-group row">
                         <label class="{{$viewClass['label']}} control-label"></label>
                         <div class="{{$viewClass['field']}}">
-                            <div class="remove btn btn-white btn-sm pull-right"><i class="feather icon-trash">&nbsp;</i>{{ trans('admin.remove') }}</div>
+                            <div class="{{$columnClass}}-remove btn btn-white btn-sm pull-right"><i class="feather icon-trash">&nbsp;</i>{{ trans('admin.remove') }}</div>
                         </div>
                     </div>
                 @endif
@@ -63,21 +63,22 @@
         forms = '.has-many-{{ $columnClass  }}-forms';
 
     function replaceNestedFormIndex(value) {
-        return String(value).replace(/{{ Dcat\Admin\Form\NestedForm::DEFAULT_KEY_NAME }}/g, nestedIndex);
+        return String(value)
+            .replace(/{{ Dcat\Admin\Form\NestedForm::DEFAULT_KEY_NAME }}/g, nestedIndex)
+            .replace(/{{ Dcat\Admin\Form\NestedForm::DEFAULT_PARENT_KEY_NAME }}/g, nestedIndex);
     }
 
     $(container).on('click', '.{{$columnClass}}-add', function () {
-
         var tpl = $('template.{{ $columnClass }}-tpl');
 
         nestedIndex++;
 
-        var template = replaceNestedFormIndex(tpl.html());
-        $(forms).append(template);
+        $(forms).append(replaceNestedFormIndex(tpl.html()));
     });
 
     $(container).on('click', '.{{$columnClass}}-remove', function () {
-        var $form = $(this).closest('.has-many-{{ $columnClass  }}-form');
+        var $form = $(this).closest('.has-many-{{ $columnClass }}-form');
+
         $form.hide();
         $form.find('.{{ Dcat\Admin\Form\NestedForm::REMOVE_FLAG_CLASS }}').val(1);
         $form.find('[required]').prop('required', false);

+ 6 - 5
resources/views/form/hasmanytable.blade.php

@@ -81,20 +81,21 @@
 {{--<hr style="margin-top: 0px;">--}}
 
 <script>
+(function () {
     var nestedIndex = {!! $count !!},
         container = '.has-many-table-{{ $columnClass }}';
 
     function replaceNestedFormIndex(value) {
-        return String(value).replace(/{{ Dcat\Admin\Form\NestedForm::DEFAULT_KEY_NAME }}/g, nestedIndex);
+        return String(value).replace(/{{ $parentKey ?: Dcat\Admin\Form\NestedForm::DEFAULT_KEY_NAME }}/g, nestedIndex);
     }
 
     $(document).off('click', container+' .add').on('click', container+' .add', function (e) {
-        var tpl = $('template.{{ $columnClass }}-tpl');
+        var $con = $(this).closest(container);
+        var tpl = $con.find('template.{{ $columnClass }}-tpl');
 
         nestedIndex++;
 
-        var template = replaceNestedFormIndex(tpl.html());
-        $(this).closest(container).find('.has-many-table-{{ $columnClass }}-forms').append(template);
+        $con.find('.has-many-table-{{ $columnClass }}-forms').append(replaceNestedFormIndex(tpl.html()));
 
         e.preventDefault();
         return false
@@ -107,5 +108,5 @@
         $form.find('[required]').prop('required', false);
         $form.find('.{{ Dcat\Admin\Form\NestedForm::REMOVE_FLAG_CLASS }}').val(1);
     });
+})();
 </script>
-

+ 3 - 1
src/Form/Field/ArrayField.php

@@ -57,7 +57,9 @@ class ArrayField extends HasMany
 
     public function buildNestedForm($key = null)
     {
-        $form = new NestedForm($this->column);
+        $form = new NestedForm($this->getNestedFormColumnName());
+
+        $this->setNestedFormDefaultKey($form);
 
         $form->setForm($this->form)
             ->setKey($key);

+ 50 - 2
src/Form/Field/HasMany.php

@@ -22,7 +22,17 @@ class HasMany extends Field
      *
      * @var string
      */
-    protected $relationName = '';
+    protected $relationName;
+
+    /**
+     * @var string
+     */
+    protected $parentRelationName;
+
+    /**
+     * @var string|int
+     */
+    protected $parentKey;
 
     /**
      * Relation key name.
@@ -350,6 +360,41 @@ class HasMany extends Field
         );
     }
 
+    public function setParentRelationName($name, $parentKey)
+    {
+        $this->parentRelationName = $name;
+        $this->parentKey = $parentKey;
+
+        return $this;
+    }
+
+    public function getNestedFormColumnName()
+    {
+        if ($this->parentRelationName) {
+            $key = $this->parentKey ?? (NestedForm::DEFAULT_KEY_PREFIX.NestedForm::DEFAULT_PARENT_KEY_NAME);
+
+            return $this->parentRelationName.'.'.$key.'.'.$this->column;
+        }
+
+        return $this->column;
+    }
+
+    protected function getNestedFormDefaultKeyName()
+    {
+        if ($this->parentRelationName) {
+            // hasmany嵌套table时,需要重新设置行的默认key
+            return $this->parentRelationName . '_NKEY_';
+        }
+    }
+
+    protected function setNestedFormDefaultKey(Form\NestedForm $form)
+    {
+        if ($this->parentRelationName) {
+            // hasmany嵌套table时需要特殊处理
+            $form->setDefaultKey(Form\NestedForm::DEFAULT_KEY_PREFIX.$this->getNestedFormDefaultKeyName());
+        }
+    }
+
     /**
      * Build a Nested form.
      *
@@ -358,7 +403,9 @@ class HasMany extends Field
      */
     public function buildNestedForm($key = null)
     {
-        $form = new Form\NestedForm($this->column, $key);
+        $form = new Form\NestedForm($this->getNestedFormColumnName(), $key);
+
+        $this->setNestedFormDefaultKey($form);
 
         $form->setForm($this->form);
 
@@ -576,6 +623,7 @@ class HasMany extends Field
             'options'      => $this->options,
             'count'        => count($this->value()),
             'columnClass'  => $this->columnClass,
+            'parentKey'    => $this->getNestedFormDefaultKeyName(),
         ]);
 
         return parent::render();

+ 27 - 3
src/Form/NestedForm.php

@@ -10,7 +10,9 @@ use Illuminate\Support\Collection;
 
 class NestedForm extends WidgetForm
 {
-    const DEFAULT_KEY_NAME = '__LA_KEY__';
+    const DEFAULT_KEY_PREFIX = 'new_';
+    const DEFAULT_PARENT_KEY_NAME = '__PARENT_NESTED__';
+    const DEFAULT_KEY_NAME = '__NESTED__';
 
     const REMOVE_FLAG_NAME = '_remove_';
 
@@ -24,10 +26,15 @@ class NestedForm extends WidgetForm
     /**
      * NestedForm key.
      *
-     * @var
+     * @var string
      */
     protected $key;
 
+    /**
+     * @var string
+     */
+    protected $defaultKey;
+
     /**
      * Fields in form.
      *
@@ -289,6 +296,11 @@ class NestedForm extends WidgetForm
             $this->form->builder()->pushField((clone $field)->display(false));
         }
 
+        if ($field instanceof Form\Field\HasMany) {
+            // HasMany以及array嵌套table,需要保存上级字段名
+            $field->setParentRelationName($this->relationName, $this->key);
+        }
+
         $this->callResolvingFieldCallbacks($field);
 
         $field->setRelation([
@@ -341,6 +353,18 @@ class NestedForm extends WidgetForm
         return $this;
     }
 
+    public function getDefaultKey()
+    {
+        return $this->defaultKey ?: (static::DEFAULT_KEY_PREFIX.static::DEFAULT_KEY_NAME);
+    }
+
+    public function setDefaultKey($key)
+    {
+        $this->defaultKey = $key;
+
+        return $this;
+    }
+
     /**
      * Set `errorKey` `elementName` `elementClass` for fields inside hasmany fields.
      *
@@ -353,7 +377,7 @@ class NestedForm extends WidgetForm
 
         $elementName = $elementClass = $errorKey = [];
 
-        $key = $this->key ?: 'new_'.static::DEFAULT_KEY_NAME;
+        $key = $this->key ?? $this->getDefaultKey();
 
         if (is_array($column)) {
             foreach ($column as $k => $name) {