JS/JQuery : 在生成新字段的同时继续表单数组的索引
Posted
技术标签:
【中文标题】JS/JQuery : 在生成新字段的同时继续表单数组的索引【英文标题】:JS/JQuery : continue with the index of array of the form while generating new fields 【发布时间】:2017-12-24 01:25:00 【问题描述】:我有一个使用 php 和 foreach 循环动态生成的表单。
此表单的输入字段依次返回 3-D 数组中的数据,这样可以轻松回溯提交这些字段的位置以及如何存储它们。所以这是表格:
<?php
$i = 0;
foreach ($shop->fetch()->showResults() as $sr)
$j = 0;
if($i == 0)
echo '<div id="ser'.$sr->id.'" location = "'.$sr->id.'" class="tab-pane fade active in">';
$i++;
else
echo '<div id="ser'.$sr->id.'" location = "'.$sr->id.'" class="tab-pane fade">';
$i++;
$ser = new Service(Input::get('cd'));
$ser->fetchPriceInShop($sr->id, $ser->fetchData()->id);
foreach ($ser->fetchData() as $price)
echo '<input type="text" value="'.$price->duration.'" name="price['.$sr->id.']['.$j.'][duration]" placeholder="duration (in Minutes)">
<input type="text" value="'.$price->price.'" name="price['.$sr->id.']['.$j.'][price]" placeholder="Price ($ 100)">
<br>';
$j++;
echo '
<button style="float: right;" class="addPrice" type="button">+</button>
</div>';
?>
所以生成的表单是这样的:
<input type="text" value="10.00" name="price[1][0][price]" placeholder="Price ($ 100)">
<br><input type="text" value="20" name="price[1][1][duration]" placeholder="duration (in Minutes)">
<input type="text" value="20.00" name="price[1][1][price]" placeholder="Price ($ 100)">
<br><input type="text" value="30" name="price[1][2][duration]" placeholder="duration (in Minutes)">
<input type="text" value="30.00" name="price[1][2][price]" placeholder="Price ($ 100)">
<br>
现在,我正在尝试使此表单更灵活,我可以在其中添加更多字段并使用它们提交值。为此使用以下js:
$(".addPrice").on("click", function()
var location = $(this).parent().attr('location');
var element = '<input type="text" placeholder="duration (minutes)" name="prices['+location+'][index][duration]">';
element += '<input type="text" placeholder="price (aud)" name="prices['+location+'][index][price]"><br>';
$(this).parent().append(element);
);
我以某种方式设法获取第一个索引(位置),最后一个索引是静态的,但我不知道如何找到生成的数组的第二个索引。请帮我找出解决方案。
PS:我是堆栈溢出的菜鸟,所以请不要苛刻。我正在学习使用这个平台。
【问题讨论】:
您不应该尝试为每个输入字段指定一个唯一的名称。相反,给它们所有相同的数组名称,如name="price[]"
和name="duration[]"
。之后,您可以简单地在 PHP 中遍历这些数组来检索每个值。
对于 DRYness,如果您在 if/else 块之后编写两个 i++
语句,则可以将其合并为一个语句。这样,无论$i=0
是否都会保证递增。
也许重新配置您的多维数组结构以使用最深元素的索引。换句话说,声明为price[$sr->id]['price'][]
,那么您不必为$j
的递增而烦恼。然后在您的 jquery 中,您可以只使用:name="prices['+location+'][price][]"
,而无需搜索要使用的正确 index
。这与icecub建议的原则基本相同。
我刚刚意识到输入名称值中有一个错字——price
与 prices
。只是需要在每个人的代码中修复。
【参考方案1】:
我建议重新构建您的多维数组以避免不必要的计数/递增。
生成php代码的表单:
$i=0;
foreach($shop->fetch()->showResults() as $sr)
echo "<div id=\"ser$sr->id\" location=\"$sr->id\" class=\"tab-pane fade",(!$i++?" active in":""),"\">";
$ser=new Service(Input::get('cd'));
$ser->fetchPriceInShop($sr->id, $ser->fetchData()->id);
foreach($ser->fetchData() as $price)
echo "<input type=\"text\" value=\"$price->duration\" name=\"price[$sr->id][duration][]\" placeholder=\"duration (in Minutes)\">
<input type=\"text\" value=\"$price->price\" name=\"price[$sr->id][price][]\" placeholder=\"Price ($ 100)\">
<br>";
echo "<button style=\"float:right;\" class=\"addPrice\" type=\"button\">+</button>";
echo "</div>";
*注意$i++
条件首先检查它是否为零,然后递增。这可以保持您的预期用途。 Demo of this technique
jquery 代码:
$(".addPrice").on("click", function()
var location = $(this).parent().attr('location');
var element = '<input type="text" placeholder="duration (minutes)" name="price['+location+'][duration][]">';
element += '<input type="text" placeholder="price (aud)" name="price['+location+'][price][]"><br>';
$(this).parent().append(element);
);
我可能还想推荐使用data-location
而不是location
作为属性名称。
【讨论】:
我也想到了这一点,但我认为,也许是错误的,索引是有原因的,例如需要维护排序顺序。 @AlexanderHiggins 这种方法会如何破坏排序顺序?我忽略了什么吗?我认为唯一能做的就是强制 OP 在提交后重新编码数据处理——但不会以一种太麻烦的方式。 一般来说,如果数组被绑定到模型或序列化,数据结构已经改变。通俗的说,以xml为例,原来的可能序列化为 但通过改变它可能的结构。您可以向价格元素添加一个类,并使用该类计算元素。
var idx = parent.find('.price').length;
function parsePrice(el)
var parent = $(el).parent();
var location = parent.attr("location");
var idx = parent.find('.price').length;
var element = '<input type="text" placeholder="duration (minutes)" name="price[' + location + '][' + idx + '][duration]">';
element += '<input type="text" placeholder="price (aud)" name="price[' + location + ']['+idx+'][price]"><br>';
$(element).insertBefore(el);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="1" location="1" class="tab-pane fade active in">
<input type="text" value="10" name="price[1][0][duration]" placeholder="duration (in Minutes)">
<input class="price" type="text" value="10.00" name="price[1][0][price]" placeholder="Price ($ 100)">
<br><input type="text" value="20" name="price[1][1][duration]" placeholder="duration (in Minutes)">
<input class="price" type="text" value="20.00" name="price[1][1][price]" placeholder="Price ($ 100)">
<br><input type="text" value="30" name="price[1][2][duration]" placeholder="duration (in Minutes)">
<input class="price" type="text" value="30.00" name="price[1][2][price]" placeholder="Price ($ 100)">
<br>
<input type="button" onclick="parsePrice(this);" value="go" />
</div>
或者,您可以将元素分组到父容器中,例如 PHP 循环中的 div
:
foreach ($ser->fetchData() as $price)
echo '<div class="pricediv price-'.$sr->id.'"><input type="text" value="'.$price->duration.'" name="price['.$sr->id.']['.$j.'][duration]" placeholder="duration (in Minutes)">
<input type="text" value="'.$price->price.'" name="price['.$sr->id.']['.$j.'][price]" placeholder="Price ($ 100)">
</div>';
$j++;
然后选择这些元素的计数:
function parsePrice(el)
var parent = $(el).parent();
var location = parent.attr("location");
var idx = parent.find('div').length;
var element = '<input type="text" placeholder="duration (minutes)" name="price[' + location + '][' + idx + '][duration]">';
element += '<input type="text" placeholder="price (aud)" name="price[' + location + '][' + idx + '][price]"><br>';
$(element).insertBefore(el);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="1" location="1" class="tab-pane fade active in">
<div class="pricediv price-1"><input type="text" value="10" name="price[1][0][duration]" placeholder="duration (in Minutes)">
<input class="price" type="text" value="10.00" name="price[1][0][price]" placeholder="Price ($ 100)">
</div>
<div class="pricediv price-2"><input type="text" value="20" name="price[1][1][duration]" placeholder="duration (in Minutes)">
<input class="price" type="text" value="20.00" name="price[1][1][price]" placeholder="Price ($ 100)">
</div>
<div class="pricediv price-3"><input type="text" value="30" name="price[1][2][duration]" placeholder="duration (in Minutes)">
<input class="price" type="text" value="30.00" name="price[1][2][price]" placeholder="Price ($ 100)">
<br>
<input type="button" onclick="parsePrice(this);" value="go" />
</div>
【讨论】:
刚刚在 OP 的代码中发现拼写错误,检查输入的名称值price
与 prices
。我刚刚将我的更改为price
(任意)。
我会跟随你的。 +1 提醒。【参考方案3】:
您可以使用按标签名称获取元素来查找索引。
$(".addPrice").on("click", function()
var location = $(this).parent().attr('location');
var index=$(this).parent().getElementsByTagName("input").length/2;
var element = '<input type="text" placeholder="duration (minutes)" name="prices['+location+']['+index+'][duration]">';
element += '<input type="text" placeholder="price (aud)" name="prices['+location+']['+index+'][price]"><br>';
$(this).parent().append(element);
);
【讨论】:
虽然这是一个解决方案,但请考虑@icecub 为组使用相同名称属性的建议,这是正确的方法。如果您满意,请接受我的回答。以上是关于JS/JQuery : 在生成新字段的同时继续表单数组的索引的主要内容,如果未能解决你的问题,请参考以下文章
在表单字段中输入文本,在提交时生成多个 URL 并在新选项卡中打开链接