我有一个选择菜单供用户选择每种的数量 他想要的注册类型。
<form method="post" action="{{route('conferences.storeQuantities',
['id' => $conference->id, 'slug' => $conference->slug])}}">
<ul class="list-group">
{{ csrf_field() }}
@foreach($registration_types as $rtype)
<li>
<select id="rtype_{{ $rtype->id }}"
data-price="{{ $rtype->price }}"
name="rtypes[{{ $rtype->name }}]">
<option value="0">0</option>
@for ($i = $rtype->min_participants; $i <= $rtype-> max_participants; $i++)
<option value="{{ $i }}">{{ $i }}</option>
@endfor
</select>
</li>
@endforeach
</ul>
</form>
但是此字段有一些验证规则无法正常工作。基本上,有四件事需要验证:
问题:但它无法正常工作,例如,如果用户为注册类型“常规”选择数量“ 1”,而为注册类型“加号”选择“ 0”,则显示验证message()
规则的RegistrationTypeQuantity
中定义的错误。但是用户应该只能为1种注册类型选择数量。
你知道如何解决吗?
storeQuantities()中使用的RegistrationTypeQuantity
规则基本上是对数量求和,然后检查数量是否大于0:
public function passes($attribute, $value)
{
$quantity = 0;
foreach($value as $key=>$v) {
if ( is_null($v)) return false;
$rtype = RegistrationType::where('name',$key)->first();
if ( ! $rtype) return false;
// $rtype was found
if ( ($v < $rtype->min_participants || $v > $rtype->max_participants) )
return false;
}
// track total quantity selected
$quantity += (int)$v;
// make sure there was at least one purchase
if ($quantity === 0) {
return false;
}
return true;
}
用户为每种注册类型存储所选数量的方法
public function storeQuantities(Request $request, $id, $slug = null)
{
$request->validate([
'rtypes' => ['required', 'array', new RegistrationTypeQuantity],
]);
if ($validator->fails())
{
return redirect()->back()->withErrors($validator, 'quantitiesError');
}
$rtypeQuantities = $request->get('rtypes');
$total = 0;
$selectedRtypes = [];
foreach ($rtypeQuantities as $rtypeName => $quantity) {
if ($quantity) {
$rtype = RegistrationType::where('name', $rtypeName)->firstOrFail();
//dd($rtype);
$price = $rtype->price;
$selectedRtypes[$rtype->name]['quantity'] = $quantity;
$selectedRtypes[$rtype->name]['price'] = $price;
$selectedRtypes[$rtype->name]['subtotal'] = $price * $quantity;
$total += $selectedRtypes[$rtype->name]['subtotal'];
$selectedRtypes[$rtype->name]['total'] = $total;
$selectedRtypes[$rtype->name]['questions'] = $rtype->questions;
$selectedRtypes[$rtype->name]['id'] = $rtype->id;
}
}
if($selectedRtypes){
Session::put('selectedRtypes', $selectedRtypes);
Session::put('customQuestions', $selectedRtypes[$rtype->name]['questions']);
Session::put('total', $total);
}
return redirect(route('conferences.registration', ['id' => $id, 'slug' => $slug]));
}
}
选择菜单的HTML以选择数量:
<div class="card">
<div class="card-header d-flex justify-content-between">
<span>Registration Type</span>
<span>Quantity</span>
<span>Price</span>
</div>
<div class="card_body">
<form method="post"
action="https://proj.test/conference/1/conference-test/registration">
<ul class="list-group list-group-flush">
<input type="hidden" name="_token" value="">
<li class="list-group-item d-flex align-items-center justify-content-between">
<div class="w-100 text-truncate">
<span>general</span>
</div>
<select class="custom-select form-control rtype_name" id="rtype_1"
data-price="5"
name="rtypes[geral]">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
<span>X 5.00€</span>
</li>
<li class="list-group-item d-flex align-items-center justify-content-between">
<div class="w-100 text-truncate">
<span>plus</span>
</div>
<select class="custom-select form-control rtype_name" id="rtype_3"
data-price="10"
name="rtypes[plus]">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
<span>X 10.00€</span>
</li>
</ul>
</form>
</div>
</div>
验证规则有更好的解释:
如果有两种与会议相关联的注册类型(常规和加号),则注册类型“常规”的列“ min_participants”为“ 1”,max_participants列为“ 1”,注册类型“ plus”具有列“ min_participants”为“ 1”,max_participants为“ 2”。
如果用户在选择菜单中单击“下一步”,注册类型为“常规”的数量为“ 0”,注册类型为“加号”的数量为“ 0”,则应失败因为用户需要至少选择一种注册类型的数量,因为注册需要关联一些注册类型
如果用户在选择菜单中单击“下一步”,注册类型为“常规”的数量为“ 2”,注册类型为“加号”的数量为“ 0”,则应失败因为“一般”的“ max_participants”为“ 1”,并且用户选择了数量“ 2”(例如,在源代码中引入了2,因为在选择菜单2中不应为一般注册类型显示,而仅应在1和1)
如果用户在选择菜单中单击“下一步”,注册类型为“常规”的数量为“ 1”,注册类型为“加号”的数量为“ 1”,则应通过
如果用户在选择菜单中单击“下一步”,注册类型为“常规”的数量为“ 1”,注册类型为“加号”的数量为“ 0”,则应通过因为应该允许用户进行注册,而没有为所有注册类型选择数量,因为用户可能只想以注册类型“常规”进行注册,而不希望以注册类型“加号”进行注册。因此,对于用户为所有注册类型选择数量,它不是强制性的。
答案 0 :(得分:0)
我没有查看所有详细信息,但是对我来说问题出在这里:
public function passes($attribute, $value)
{
foreach($value as $key=>$v) {
$quantity = 0;
您在每次迭代中将数量设置为0。也许你应该这样做
public function passes($attribute, $value)
{
$quantity = 0;
foreach($value as $key=>$v) {
因此,在开始循环之前,应使用0初始化此变量。
答案 1 :(得分:0)
根据discussion that took place和对current vs desired validation results的分析。
遵循验证规则的工作代码:
public function passes($attribute, $value)
{
// we get the products quantity
$count = array_sum($value);
// FAIL in advance if no products were selected
if($count == 0){
return false;
}
foreach($value as $key=>$v) {
$rtype = RegistrationType::where('name',$key)->first();
if ( !$rtype ){
return false;
}
// Only if at least one product was selected, test against DB params
if ( $v != 0 && ($v < $rtype->min_participants || $v > $rtype->max_participants) ){
return false;
}
}
// If no rejectig conditions were found, validation should PASS
return true;
}