CakePHP 3.x - 编辑:日期在提交时具有空字段,尽管它们已经存在
CakePHP 3.x - Edit: Dates having empty fields upon submission despite them already existing
我有三个table:
- 预订(表格所在的位置)
- 会话(属性
date_start
和 date_end
是)
在 Sessions table 中,我有一个使用 Daterangepicker jQuery 脚本的日期字段。
<input class='form-control' type="text" name="daterange" id="daterange"
placeholder='Session dates'/>
在 MySQL 中,我的会话 table 中有两个属性,分别称为 date_start
和 date_end
。当有人使用 'daterange' 输入时,他们能够使用从 Daterangepicker 构建的日历到 select 两个日期。 Upon choosing those two dates, those two dates become date_start
and date_end
, and when choosing new dates, those dates are saved successfully.
但是,这个特定的表单是编辑视图,而不是添加,我的问题是如果我不更改 daterange
表单输入然后提交表单,它无法成功保存任何内容并且表示属性 date_start 和 date_end 为空,需要填写(它们在 MySQL 中不是空值)。我使用 Javascript 脚本将现有日期范围输入到字段中,如下所示:
<script>
$(document).ready(function () {
var daterange = '<?= h($booking->session->date_start->i18nFormat('dd/MM/YYYY') . ' - ' . $booking->session->date_end->i18nFormat('dd/MM/YYYY'));?>';
$('#daterange').val(daterange);
});
</script>
例如,如果 date_start = 2017-02-02
和 date_end = 2017-02-03
,那么 daterange
表单输入将在转换为我的本地日期格式后显示:
02/02/2017 - 03/02/2017
$booking 指的是控制器中设置为视图的语句:
$booking = $this->Bookings->get($id,[
'contain'=>['Sessions']
]);
当我打印 $booking->session['date_start']
或 $booking->session['date_end']
时,我可以看到日期。在 CakePHP 变量中,我还可以正确地看到日期。提交的时候才看到请求数据是空的,patchEntity的debug也一样显示。
例如,如果在使用编辑表单之前说 date_start = 2017-02-02 和 date_end = 2017-02-03,然后执行 pr($booking->session['date_start'])
,我会打印 2/2/2017(本地日期格式)。
此外,这些是隐藏的 date_start
和 date_end
输入,如果 daterange
输入被填充,它们会自动填充。
<?php
echo $this->Form->hidden('session[date_start][year]', ['id' => 'start_year']);
echo $this->Form->hidden('session[date_start][month]', ['id' => 'start_month']);
echo $this->Form->hidden('session[date_start][day]', ['id' => 'start_day']);
echo $this->Form->hidden('session[date_end][year]', ['id' => 'end_year']);
echo $this->Form->hidden('session[date_end][month]', ['id' => 'end_month']);
echo $this->Form->hidden('session[date_end][day]', ['id' => 'end_day']);
?>
以及执行此操作的相应 Daterangepicker JS:
<script type="text/javascript">
$(function () {
$('input[name="daterange"]').daterangepicker({
autoUpdateInput: false,
locale: {
cancelLabel: 'Clear'
},
format: "DD/MM/YYYY",
startDate: new Date(new Date().getTime() + 24 * 60 * 60 * 1000),
endDate: new Date(new Date().getTime() + 24 * 60 * 60 * 1000),
minDate: new Date(new Date().getTime() + 24 * 60 * 60 * 1000)
});
$('input[name="daterange"]').on('apply.daterangepicker', function (ev, picker) {
$(this).val(picker.startDate.format('DD/MM/YYYY') + ' - ' + picker.endDate.format('DD/MM/YYYY'));
$("#start_year").val(picker.startDate.format('YYYY'));
$("#start_month").val(picker.startDate.format('MM'));
$("#start_day").val(picker.startDate.format('DD'));
$("#end_year").val(picker.endDate.format('YYYY'));
$("#end_month").val(picker.endDate.format('MM'));
$("#end_day").val(picker.endDate.format('DD'));
});
$('input[name="daterange"]').on('cancel.daterangepicker', function (ev, picker){
$(this).val('');
});
});
</script>
总结:除非我使用相应的表单输入主动更改日期,否则现有日期由于某种原因被清空,并且提交无法保存任何表单。
更新: 到目前为止,我尝试了两件事:根据 ahoffner 的建议,如果在控制器中为空,则取消设置 date_start
和 date_end
,这不工作。我还尝试删除隐藏的表单输入。这允许我在日期未更改的情况下提交,但如果我更改了它们,虽然表单仍会成功提交,但日期不会更改。
更新 2: 根据 ahoffner 的要求,下面是 $this->request->data()。在这个特定的提交中,我将 amount
更改为 300,并且没有修改日期。结果保存失败
Array
(
[session] => Array
(
[studio_id] => 2
[date_start] => Array
(
[year] =>
[month] =>
[day] =>
)
[date_end] => Array
(
[year] =>
[month] =>
[day] =>
)
[session_genre] => test
[engineer_id] => 2
[no_people] => 3
[studio_usage] => test
[otherpeople_req] =>
[special_req] =>
[status] => confirmed
)
[optionsRadios] => manydays
[singledate] =>
[daterange] => 09/02/2017 - 10/02/2017
[firstname] =>
[lastname] =>
[email] =>
[phoneno] =>
[textbox] =>
[amount] => 300
)
Bookingtable的初始化函数如下:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('bookings');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Artists', [
'foreignKey' => 'artist_id',
'joinType' => 'INNER'
]);
$this->hasMany('Payments', [
'foreignKey' => 'booking_id'
]);
$this->hasOne('Sessions', [
'foreignKey' => 'booking_id'
]);
}
It's only when submitting, and seeing the request data that they're empty..
当您将数组代替实体值传递给 patchEntity 时,odd/special 事情可能会发生。
如 $this->request->data()
的输出所示, 是 为 date_start
设置的值 & 最后,一个数组包含:
Array
(
[year] =>
[month] =>
[day] =>
)
当调用 patchEntity
时,它会尝试将 $booking->session->date_start
和 date_end
设置为该数组 (['year' => '', 'month' => '', 'day' => '']
)。
CakePHP 将在调用 patchEntity 或 newEntity 时更新提供的每个数组键 的实体值。即使值是空的,或者在这种情况下,包含一个 non-empty 数组 - 它仍然会尝试更新该键的值。
由于该字段上的类型可能是 date
- 它最终会在编组值时尝试将其类型转换为 date-formatted 字符串。如果这些键都是空白的,looking at the source, 它基本上只是删除该数组,将其转换为 null
。如果这些键有值,它会将它们转换为日期字符串(如“2017-02-02”)。
同样,解决此问题的一种方法是确保不将带有空键的数组传递给 patchEntity,使用这种格式的请求数据看起来更像是:
$data = $this->request->data();
if(empty($data['session']['date_start']['year']) || empty($data['session']['date_start']['month']) || empty($data['session']['date_start']['day'])) {
unset($data['session']['date_start']);
}
if(empty($data['session']['date_end']['year']) || empty($data['session']['date_end']['month']) || empty($data['session']['date_end']['day'])) {
unset($data['session']['date_end']);
}
$booking = $this->Bookings->patchEntity($booking, $data);
然而,这些在提交时为空白可能是有原因的 - 当它们不应该放在第一位时。解决这个问题也会解决这个问题,因为他们最终不会制作这个空白数组。根据示例代码检查这些字段的值($("#start_year").val()
等),这些字段不应为空。 'apply.daterangepicker'
函数是否按预期调用?是否按预期应用了值(picker.startDate.format('YYYY')
等)?
我有三个table:
- 预订(表格所在的位置)
- 会话(属性
date_start
和date_end
是)
在 Sessions table 中,我有一个使用 Daterangepicker jQuery 脚本的日期字段。
<input class='form-control' type="text" name="daterange" id="daterange"
placeholder='Session dates'/>
在 MySQL 中,我的会话 table 中有两个属性,分别称为 date_start
和 date_end
。当有人使用 'daterange' 输入时,他们能够使用从 Daterangepicker 构建的日历到 select 两个日期。 Upon choosing those two dates, those two dates become date_start
and date_end
, and when choosing new dates, those dates are saved successfully.
但是,这个特定的表单是编辑视图,而不是添加,我的问题是如果我不更改 daterange
表单输入然后提交表单,它无法成功保存任何内容并且表示属性 date_start 和 date_end 为空,需要填写(它们在 MySQL 中不是空值)。我使用 Javascript 脚本将现有日期范围输入到字段中,如下所示:
<script>
$(document).ready(function () {
var daterange = '<?= h($booking->session->date_start->i18nFormat('dd/MM/YYYY') . ' - ' . $booking->session->date_end->i18nFormat('dd/MM/YYYY'));?>';
$('#daterange').val(daterange);
});
</script>
例如,如果 date_start = 2017-02-02
和 date_end = 2017-02-03
,那么 daterange
表单输入将在转换为我的本地日期格式后显示:
02/02/2017 - 03/02/2017
$booking 指的是控制器中设置为视图的语句:
$booking = $this->Bookings->get($id,[
'contain'=>['Sessions']
]);
当我打印 $booking->session['date_start']
或 $booking->session['date_end']
时,我可以看到日期。在 CakePHP 变量中,我还可以正确地看到日期。提交的时候才看到请求数据是空的,patchEntity的debug也一样显示。
例如,如果在使用编辑表单之前说 date_start = 2017-02-02 和 date_end = 2017-02-03,然后执行 pr($booking->session['date_start'])
,我会打印 2/2/2017(本地日期格式)。
此外,这些是隐藏的 date_start
和 date_end
输入,如果 daterange
输入被填充,它们会自动填充。
<?php
echo $this->Form->hidden('session[date_start][year]', ['id' => 'start_year']);
echo $this->Form->hidden('session[date_start][month]', ['id' => 'start_month']);
echo $this->Form->hidden('session[date_start][day]', ['id' => 'start_day']);
echo $this->Form->hidden('session[date_end][year]', ['id' => 'end_year']);
echo $this->Form->hidden('session[date_end][month]', ['id' => 'end_month']);
echo $this->Form->hidden('session[date_end][day]', ['id' => 'end_day']);
?>
以及执行此操作的相应 Daterangepicker JS:
<script type="text/javascript">
$(function () {
$('input[name="daterange"]').daterangepicker({
autoUpdateInput: false,
locale: {
cancelLabel: 'Clear'
},
format: "DD/MM/YYYY",
startDate: new Date(new Date().getTime() + 24 * 60 * 60 * 1000),
endDate: new Date(new Date().getTime() + 24 * 60 * 60 * 1000),
minDate: new Date(new Date().getTime() + 24 * 60 * 60 * 1000)
});
$('input[name="daterange"]').on('apply.daterangepicker', function (ev, picker) {
$(this).val(picker.startDate.format('DD/MM/YYYY') + ' - ' + picker.endDate.format('DD/MM/YYYY'));
$("#start_year").val(picker.startDate.format('YYYY'));
$("#start_month").val(picker.startDate.format('MM'));
$("#start_day").val(picker.startDate.format('DD'));
$("#end_year").val(picker.endDate.format('YYYY'));
$("#end_month").val(picker.endDate.format('MM'));
$("#end_day").val(picker.endDate.format('DD'));
});
$('input[name="daterange"]').on('cancel.daterangepicker', function (ev, picker){
$(this).val('');
});
});
</script>
总结:除非我使用相应的表单输入主动更改日期,否则现有日期由于某种原因被清空,并且提交无法保存任何表单。
更新: 到目前为止,我尝试了两件事:根据 ahoffner 的建议,如果在控制器中为空,则取消设置 date_start
和 date_end
,这不工作。我还尝试删除隐藏的表单输入。这允许我在日期未更改的情况下提交,但如果我更改了它们,虽然表单仍会成功提交,但日期不会更改。
更新 2: 根据 ahoffner 的要求,下面是 $this->request->data()。在这个特定的提交中,我将 amount
更改为 300,并且没有修改日期。结果保存失败
Array
(
[session] => Array
(
[studio_id] => 2
[date_start] => Array
(
[year] =>
[month] =>
[day] =>
)
[date_end] => Array
(
[year] =>
[month] =>
[day] =>
)
[session_genre] => test
[engineer_id] => 2
[no_people] => 3
[studio_usage] => test
[otherpeople_req] =>
[special_req] =>
[status] => confirmed
)
[optionsRadios] => manydays
[singledate] =>
[daterange] => 09/02/2017 - 10/02/2017
[firstname] =>
[lastname] =>
[email] =>
[phoneno] =>
[textbox] =>
[amount] => 300
)
Bookingtable的初始化函数如下:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('bookings');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Artists', [
'foreignKey' => 'artist_id',
'joinType' => 'INNER'
]);
$this->hasMany('Payments', [
'foreignKey' => 'booking_id'
]);
$this->hasOne('Sessions', [
'foreignKey' => 'booking_id'
]);
}
It's only when submitting, and seeing the request data that they're empty..
当您将数组代替实体值传递给 patchEntity 时,odd/special 事情可能会发生。
如 $this->request->data()
的输出所示, 是 为 date_start
设置的值 & 最后,一个数组包含:
Array
(
[year] =>
[month] =>
[day] =>
)
当调用 patchEntity
时,它会尝试将 $booking->session->date_start
和 date_end
设置为该数组 (['year' => '', 'month' => '', 'day' => '']
)。
CakePHP 将在调用 patchEntity 或 newEntity 时更新提供的每个数组键 的实体值。即使值是空的,或者在这种情况下,包含一个 non-empty 数组 - 它仍然会尝试更新该键的值。
由于该字段上的类型可能是 date
- 它最终会在编组值时尝试将其类型转换为 date-formatted 字符串。如果这些键都是空白的,looking at the source, 它基本上只是删除该数组,将其转换为 null
。如果这些键有值,它会将它们转换为日期字符串(如“2017-02-02”)。
同样,解决此问题的一种方法是确保不将带有空键的数组传递给 patchEntity,使用这种格式的请求数据看起来更像是:
$data = $this->request->data();
if(empty($data['session']['date_start']['year']) || empty($data['session']['date_start']['month']) || empty($data['session']['date_start']['day'])) {
unset($data['session']['date_start']);
}
if(empty($data['session']['date_end']['year']) || empty($data['session']['date_end']['month']) || empty($data['session']['date_end']['day'])) {
unset($data['session']['date_end']);
}
$booking = $this->Bookings->patchEntity($booking, $data);
然而,这些在提交时为空白可能是有原因的 - 当它们不应该放在第一位时。解决这个问题也会解决这个问题,因为他们最终不会制作这个空白数组。根据示例代码检查这些字段的值($("#start_year").val()
等),这些字段不应为空。 'apply.daterangepicker'
函数是否按预期调用?是否按预期应用了值(picker.startDate.format('YYYY')
等)?