【问题标题】:Dynamically add form field rows - cakePHP动态添加表单字段行 - cakePHP
【发布时间】:2014-05-21 21:02:54
【问题描述】:

我有一个 invoice 表和一个 invoice_item 表。每个 Invoice 都有很多 invoiceItem。

在创建发票时,用户会看到一个包含发票表单字段的表单以及一个包含 invoiceItem 表单字段的行。

我想要做的是有一个动态(jQuery,AJAX)添加项目字段的新行的“添加新项目”链接。用户应该能够添加任意数量的行,并且每个新行都应该出现在最后一行的下方。

当然,行字段属性也必须正确,以便可以轻松地使用 saveAll 方法插入数据。

用 CakePHP 实现这一目标的最佳和最合适的方法是什么?我正在使用 CakePHP 2.4.7。

【问题讨论】:

    标签: php jquery ajax cakephp cakephp-2.4.7


    【解决方案1】:

    我想到了一个最简单的想法

    1- 使用名称数组 (<input type="text" name="items[]"/>) 输入您的项目

    2- 创建一个带有“addmore”类的按钮

    3- 使用 jquery 克隆复制该按钮上单击事件的输入

    我认为这会有所帮助

    【讨论】:

    • 问题是输入将具有相同的属性,导致提交表单时出现问题。
    • 没问题,唯一带有 [] 的 name 属性将返回一个包含所有值的数组
    【解决方案2】:

    以下是我如何处理包含隐藏 ID、标签和输入字段的数据,所有这些都包含在一个字段集中。你可以使用实际的表格来包装它。

    这是为两组字段生成的 HTML 以及单击以添加行的链接:

       <fieldset>
       <input type="hidden" name="data[VmfrDesignatedIncome][0][id]" value="668" id="VmfrDesignatedIncome0Id"/>
       <div class="input text">
       <label for="VmfrDesignatedIncome0Designation">Designation</label>
       <input name="data[VmfrDesignatedIncome][0][designation]" value="blah" maxlength="512" type="text" id="VmfrDesignatedIncome0Designation"/></div>
       </fieldset>
    
        <fieldset>
        <input type="hidden" name="data[VmfrDesignatedIncome][1][id]" value="669" id="VmfrDesignatedIncome1Id"/>
        <div class="input text">
        <label for="VmfrDesignatedIncome1Designation">Designation</label>  
    
        <input name="data[VmfrDesignatedIncome][1][designation]" value="blah2" maxlength="512" type="text" id="VmfrDesignatedIncome1Designation"/></div>
        </fieldset>
    
         <a href="#" id="addrow">Add row</a>
    

    这里是复制页面上最后一个字段集的 Javascript,然后修改 id、name 和字段值以将其中的数字加一。请注意,选择器必须使用 &gt; 子选择器准确选择每个标签或字段。

    /* As the strings to the function below may have [ or ]
    ** we want to stop it being treated as a regexp
    */
    RegExp.quote = function(str) {
         return str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
     };
    
    function findNumberAddOne(attributeString) {
        /*Finds the number in the given string
        ** and returns a string with that number increased by one
        */
        var re = new RegExp("(.*)([0-9])(.*)");
        var nPlusOne = attributeString.replace(re, "$2")+"+1";
        var newstr = attributeString.replace(re, "$1")+eval(nPlusOne)+attributeString.replace(re, "$3");
        return newstr;
    }
    
    $(document).ready(function() {
    /* Duplicate the last set of designated income fields and increase the relevants id/name etc.
    ** so that it works as a new row in the table when saved*/
        $('#addrow').click(function() { 
            $('fieldset:last').clone().insertAfter('fieldset:last');
            $('fieldset:last > input').attr('id',findNumberAddOne($('fieldset:last > input').attr('id')));
            $('fieldset:last > input').attr('value',''); /*Blank out the actual value*/
            $('fieldset:last > input').attr('name',findNumberAddOne($('fieldset:last > input').attr('name')));
            $('fieldset:last > div > label').attr('for',findNumberAddOne($('fieldset:last > div > label').attr('for')));
            $('fieldset:last > div > input').attr('id',findNumberAddOne($('fieldset:last > div > input').attr('id')));
            $('fieldset:last > div > input').attr('value',''); /*Blank out the actual value*/
            $('fieldset:last > div > input').attr('name',findNumberAddOne($('fieldset:last > div > input').attr('name')));
        });
    });
    

    【讨论】:

      【解决方案3】:

      请查看Dynamic form input fields in CakePHP 教程。我对 CakePHP 2.x 和 CakePHP 3.x 都使用了相同的方法。本教程中的一个问题是动态字段 ID 创建。每次它为相同的动态字段创建相同的 ID,例如为 Grade.0.subjectGrade.1.subject 字段创建 GradeSubject。如果您需要每个字段的动态 ID,您可以修改本教程,如下所示。

      根据教程只需将View/Elements/grades.ctp的内容更改为:

      <?php
          $key = isset($key) ? $key : '{{ key }}';
          // I changed <%= key %> to {{ key }}
      ?>
      <tr>
          <td>
              <?php echo $this->Form->hidden("Grade.{$key}.id") ?>
              <?php echo $this->Form->text("Grade.{$key}.subject",array("id"=>"Grade{$key}Subject")); ?>
          </td>   
          <td>
              <?php echo $this->Form->select("Grade.{$key}.grade", array(
                  'A+',
                  'A',
                  'B+',
                  'B',
                  'C+',
                  'C',
                  'D',
                  'E',
                  'F'
              ), array(
                  'empty' => '-- Select grade --',
                  "id"=>"Grade{$key}Grade"
              )); ?>
          </td>
          <td class="actions">
              <a href="#" class="remove">Remove grade</a>
          </td>
      </tr>
      

      并将您的 add.ctp javascript 代码更改为:

      <script>
          $(document).ready(function() {
              //I changed undescore default template settings
              _.templateSettings = {
                interpolate: /\{\{(.+?)\}\}/g
              }
      
              var
                  gradeTable = $('#grade-table'),
                  gradeBody = gradeTable.find('tbody'),
                  gradeTemplate = _.template($('#grade-template').remove().text()),
                  numberRows = gradeTable.find('tbody > tr').length;
      
              gradeTable
                  .on('click', 'a.add', function(e) {
                      e.preventDefault();
      
                      $(gradeTemplate({key: numberRows++}))
                          .hide()
                          .appendTo(gradeBody)
                          .fadeIn('fast');
                  })
                  .on('click', 'a.remove', function(e) {
                          e.preventDefault();
      
                      $(this)
                          .closest('tr')
                          .fadeOut('fast', function() {
                              $(this).remove();
                          });
                  });
      
                  if (numberRows === 0) {
                      gradeTable.find('a.add').click();
                  }
          });
      </script>
      

      【讨论】:

      • 请在 CakePHP 3 中进行哪些更改才能使其正常工作?
      • @pmelon 无需对 CakePHP 3 进行基本更改。无需根据您的需求安排输入字段。
      • 我正在努力(我不是专业的 PHP 编码员)才能让它工作 - 一切都很好,但没有保存成绩信息。我认为这是因为我的控制器。任何人都可以为waltherlalk.com/blog/dynamic-form-input-fields 教程发布一个示例 CakePHP 3 控制器吗?
      猜你喜欢
      • 1970-01-01
      • 2020-12-15
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 2012-08-17
      • 2016-08-26
      • 2019-04-19
      • 1970-01-01
      相关资源
      最近更新 更多