本教程是 Envato Tuts +上的“ 使用PHP构建启动”系列 的一部分。 在本系列文章中,我 将以 我的 Meeting Planner 应用程序作为真实示例 ,指导您完成从概念到现实的启动 。 在此过程的每一步中,我都会将Meeting Planner代码作为开放源代码示例发布,您可以从中学习。 我还将解决与启动相关的业务问题。
利用Bootstrap,Ajax和jQuery
通过我们的启动系列 , Meeting Planner和Simple Planner取得了长足的发展。 最近,我一直在尝试调整详细区域,以使使用该服务安排会议的难度更高。
如果您还记得我们最近的一集“ 构建您的启动:用于调度的动态Ajax表单(Envato Tuts +)” ,则知道Ajax和jQuery对可用性有多大帮助。 使调度与Ajax交互已改变了站点的可用性。
接下来,我想改善使用该服务时遇到的一个痛点。 坦白说,在发出邀请以建议日期和时间的多个选项时,这非常耗时。 每次我为自己的创业公司发送会议邀请时,我都必须手动创建两个或三个日期/时间选项,这很烦人。
在今天的一集中,我将指导您一步一步地安排具有多个相关日期和时间的会议。 具体来说,我将描述如何使用Bootstrap,Ajax和jQuery解决选择日期和时间的问题。
通过Bootstrap,可以轻松地为台式机,平板电脑和移动设备设计功能,而Ajax和jQuery则使该功能快速且交互式。
如果您还没有尝试过Meeting Planner或Simple Planner ,请继续并安排您的第一次会议 。 选择日期和时间选项时,请查找本教程的主题。
我确实参与了下面的评论主题,所以请告诉我您的想法! 您也可以通过Twitter @lookahead_io与我联系 。 如果您想为以后的教程提出新功能或主题,我特别感兴趣。
提醒一下,Meeting Planner的所有代码都是在PHP的Yii2框架中编写的。 如果您想了解有关Yii2的更多信息,请查看我们的平行系列“ 使用Yii2编程” 。
设计解决方案
随着时间的推移,我会定期使用Meeting Planner,希望有一种连续创建一系列日期和时间的方法,例如接下来的三天(上午8:30)或接下来的三周(星期三晚上7点)。 当您有多种选择要见面的时间时,它只会使与人的约会变得更加容易。
当我深入研究用户界面时,我终于有时间专注于这个问题。 在编写任何代码之前,我决定粗略地勾勒出我想要的东西。
我决定创建一个重复数量(例如下三个或五个)和一个重复单位(例如小时,天或周)。
换句话说,假设我邀请编辑机器人助理汤姆·麦克法兰(Tom McFarlin)喝咖啡,并希望在接下来的三个早晨提供早餐,然后我选择了两天又几天来重复选择的一天。
保持简单
我不希望人们总是为了安排会议而面对复杂的表格,所以我用下面显示的高级选项链接分隔了日期时间重复功能。 触摸或单击此链接将打开如下所示的表单:
编写代码入门
为了设计可与台式机和移动设备一起使用的表单,我利用了Bootstrap。 本质上,我为表单创建了多行,具有不同的列宽,这些行宽在移动设备上折叠。 我们看看吧。
大多数HTML魔术都发生在/frontend/views/meeting-time/_form.php中。 首先,这是带有“ 日期” ,“ 时间” ,“ 持续时间”和“ 高级选项”链接的行:
<div class="meeting-time-form">
<div class="row">
<div class="col-xs-12 col-md-4 col-lg-3">
<?php $form = ActiveForm::begin();?>
<?= Html::activeHiddenInput($model, 'url_prefix',['value'=>MiscHelpers::getUrlPrefix(),'id'=>'url_prefix']); ?>
<?= Html::activeHiddenInput($model, 'tz_dynamic',['id'=>'tz_dynamic']); ?>
<?= Html::activeHiddenInput($model, 'tz_current',['id'=>'tz_current']); ?>
<strong><?php echo Yii::t('frontend','Date') ?></strong>
<div class="datetimepicker-width">
<?= DateTimePicker::widget([
'model' => $model,
'attribute' => 'start',
'template' => '{input}{button}',
//'language' => 'en',
'size' => 'ms',
'clientOptions' => [
'autoclose' => true,
'format' => 'M d, yyyy',
'todayBtn' => true,
//'pickerPosition' => 'bottom-left',
'startView'=>2,
'minView'=>2,
// to do - format three day ahead
'initialDate'=> Date('Y-m-d',time()+3600*72),
]
]);?></div>
<p></p>
</div>
<div class="col-xs-12 col-md-4 col-lg-3">
<strong><?php echo Yii::t('frontend','Time') ?></strong>
<div class="datetimepicker-width">
<?= DateTimePicker::widget([
'model' => $model,
'attribute' => 'start_time',
'template' => '{input}{button}',
//'language' => 'en',
'size' => 'ms',
'clientOptions' => [
'autoclose' => true,
'format' => 'H:ii p',
'todayBtn' => false,
'minuteStep'=> 15,
'showMeridian'=>true,
//'pickerPosition' => 'bottom-left',
'startView'=>1,
'minView'=>0,
'maxView'=>1,
// to do - format one day ahead
//'initialDate'=> Date('Y-m-d'),
// $( "th.switch" ).text( "Pick the time" );
]
]);?>
</div>
<p></p>
</div>
<div class="col-xs-6 col-md-2 col-lg-2">
<?php
$durationList = [1=>'1 hour',2=>'2 hours',3=>'3 hours',4=>'4 hours',5=>'5 hours',6=>'6 hours',12=>'12 hours',24=>'24 hours',48=>'48 hours',72=>'72 hours'];
echo $form->field($model, 'duration',['options' => ['id'=>'duration','class' => 'duration-width' ]])
->dropDownList(
$durationList, // Flat array ('id'=>'label')
['prompt'=>'select a duration'] // options
);
?>
</div>
<div class="col-xs-6 col-md-2 col-lg-2" style="margin-top:3em;">
<?= Html::a(Yii::t('frontend','advanced options'),'javascript:void(0);', ['onclick'=>'toggleTimeAdvanced();']);?>
</div>
</div>
通过在Bootstrap中使用成功的列尺寸,行将在桌面上展开(如下所示),并在移动设备上自身折叠成三行(如下所示):
<div class="col-xs-12 col-md-4 col-lg-3">
<!-- Date -->
...
<div class="col-xs-12 col-md-4 col-lg-3">
<!-- Time -->
...
<div class="col-xs-6 col-md-2 col-lg-2">
<!-- Duration -->
...
<div class="col-xs-6 col-md-2 col-lg-2" style="margin-top:3em;">
<!-- Advanced options -->
...
高级选项链接的jQuery toggleTimeAdvanced()
通过删除hidden
类来打开重复表单:
function toggleTimeAdvanced() {
if ($('#timeAdvanced').hasClass('hidden')) {
$('#timeAdvanced').removeClass('hidden');
} else {
$('#timeAdvanced').addClass('hidden');
$("select#meetingtime-repeat_quantity").prop('selectedIndex', 0);
}
注意:所有jQuery都可以在/frontend/web/js/meeting.js中找到。
当您关闭重复设置时,它还会将重复设置重置为零,这是一项设计决策,可以防止人们关闭高级表单时创建重复项。
这是timeAdvanced
子表单:
<div class="row hidden" id="timeAdvanced">
<div class="col-xs-12 col-md-2 col-lg-2">
<?php
$repeat_quantity = [0=>'no repeating',1=>'1 additional option',
2=>'2 additional options',3=>'3 additional options',
4=>'4 additional options',5=>'5 additional options'];
echo $form->field($model, 'repeat_quantity',['options' => ['id'=>'repeat_quantity','class' => 'repeat-width' ]])->label('Add')
->dropDownList(
$repeat_quantity
,
['options'=>['1'=>['Selected'=>true]]]
);
?>
</div>
<div class="col-xs-12 col-md-6 col-lg-6">
<?php
$repeat_unit = ['hour'=>'successive hour e.g. 9 am, 10 am and 11 am',
'day'=>'successive day e.g. Monday, Tuesday & Wednesday',
'week'=>'successive week e.g. next Friday & Friday after'];
echo $form->field($model, 'repeat_unit',['options' => ['id'=>'repeat_unit','class' => 'repeat-width' ]])->label('On each')
->dropDownList(
$repeat_unit
);
?>
</div>
</div>
我使用的Bootstrap在台式机上显示为一行,在移动设备上显示为两行:
<div class="col-xs-12 col-md-2 col-lg-2">
<!-- repeat quantity -->
<div class="col-xs-12 col-md-6 col-lg-6">
<!-- repeat unit -->
看起来是每天早上9点连续添加3个其他选项 :
接下来,我更新了addTime()
函数以捕获并将repeat_quantity
和repeat_unit
字段提交给基于PHP的控制器:
function addTime(id) {
start_time = $('#meetingtime-start_time').val();
start = $('#meetingtime-start').val();
duration = $('#meetingtime-duration').val();
repeat_quantity = $('#meetingtime-repeat_quantity').val();
repeat_unit = $('#meetingtime-repeat_unit').val();
if (start_time =='' || start=='') {
displayAlert('timeMessage','timeMsg2');
return false;
}
// ajax submit subject and message
$.ajax({
url: $('#url_prefix').val()+'/meeting-time/add',
data: {
id: id,
start_time: encodeURIComponent(start_time),
start:encodeURIComponent(start),
duration:encodeURIComponent(duration),
repeat_quantity:encodeURIComponent(repeat_quantity),
repeat_unit:encodeURIComponent(repeat_unit),
},
success: function(data) {
loadTimeChoices(id);
insertTime(id);
displayAlert('timeMessage','timeMsg1');
return true;
}
});
创业很难,因为您总是急于完成新功能。 例如,某人(可能是我,因为我是唯一的编码员)从未转移所选的持续时间; 因此,我也添加了。 直到今天,所有会议都是1小时,尽管用户有要求。 说够了。 #startuplife。
然后,在基于Yii Framework的/frontend/controllers/MeetingTimeController.php中切换到MVC代码。 在下面,您可以看到响应jQuery提交的actionAdd
AJAX方法:
public function actionAdd($id,$start,$start_time,$duration=1,$repeat_quantity=0,$repeat_unit='hour') {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$timezone = MiscHelpers::fetchUserTimezone(Yii::$app->user->getId());
date_default_timezone_set($timezone);
$cnt=0;
while ($cnt<=$repeat_quantity) {
$model = new MeetingTime();
$model->start = urldecode($start);
$model->start_time = urldecode($start_time);
if (empty($model->start)) {
$model->start = Date('M d, Y',time()+3*24*3600);
}
$model->tz_current = $timezone;
$model->duration = $duration;
$model->meeting_id= $id;
$model->suggested_by= Yii::$app->user->getId();
$model->status = MeetingTime::STATUS_SUGGESTED;
$selected_time = date_parse($model->start_time);
if ($selected_time['hour'] === false) {
$selected_time['hour'] =9;
$selected_time['minute'] =0;
}
// convert date time to timestamp
$model->start = strtotime($model->start) + $selected_time['hour']*3600+ $selected_time['minute']*60;
if ($cnt>0) {
switch ($repeat_unit) {
case 'hour':
$model->start+=($cnt*3600);
break;
case 'day':
$model->start+=($cnt*24*3600);
break;
case 'week':
$model->start+=($cnt*7*24*3600);
break;
}
}
$model->end = $model->start + (3600*$model->duration);
$model->save();
$cnt+=1;
}
return true;
}
基本上,我使用$cnt
计数器创建了一个循环,以$repeat_unit
(例如,小时,天数或周数)增加MeetingTime的开始和结束时间选择:
if ($cnt>0) {
switch ($repeat_unit) {
case 'hour':
$model->start+=($cnt*3600);
break;
case 'day':
$model->start+=($cnt*24*3600);
break;
case 'week':
$model->start+=($cnt*7*24*3600);
break;
}
}
$model->end = $model->start + (3600*$model->duration);
因此,这是我每天上午9:00添加三个额外时隙的结果:
因此,现在,安排与人的会议并为他们提供几个连续的日期和时间作为聚会的选择变得更加容易。
收盘时
我希望这对您了解Bootstrap如何用于创建更好的表单以及如何与Ajax和jQuery结合以为您的用户建立简单的交互体验有所帮助。
如果您没有早些尝试,请尝试在会议计划器中安排重复日期/时间选项的会议,并告诉我您的想法。
有自己的想法吗? 有想法吗? 反馈? 您随时可以直接通过Twitter @lookahead_io与我联系 。 在“ 使用PHP构建您的启动”系列中观看即将发布的教程。
在接下来的几周中,我将继续完善用户体验,以使该服务尽可能易于使用。 例如,您可能会注意到会议记录现在位于其自己的选项卡上:
并且,为了消除人们在“ 是/否”开关的可用性列和选择最终位置的第二列之间所造成的困惑,我将其分为一个较低的按钮子面板,即“ 完成时间” 。 只有组织者和指定为组织者的参与者才能看到此下部面板,从而简化了典型参与者的通用视图:
Bootstrap,jQuery和Ajax也部分或全部捆绑在一起来构建这两个功能。
我希望到目前为止,在本系列文章中,您有自己的启动想法,并正在考虑编写一些代码。 请继续关注以了解有关我如何构建和启动我的我的更多信息。