3

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

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

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

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

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

4

3 回答 3

1

下面是我如何处理包含隐藏 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 和字段值以将其中的数字加一。请注意,选择器必须使用>子选择器准确选择每个标签或字段。

/* 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')));
    });
});
于 2014-08-01T13:47:12.880 回答
0

请查看CakePHP教程中的动态表单输入字段。我对 CakePHP 2.x 和 CakePHP 3.x 都使用了相同的方法。本教程中的一个问题是动态字段 ID 创建。每次它为相同的动态字段创建相同的 ID,例如GradeSubject同时为Grade.0.subjectGrade.1.subject字段创建。如果您需要每个字段的动态 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.ctpjavascript代码更改为:

<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>
于 2015-10-26T06:20:17.240 回答
-1

最简单的想法出现在我的脑海中

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

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

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

我认为这会有所帮助

于 2014-04-09T02:04:25.783 回答