用 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 F ram ework 编写的。如果您想了解更多关于 Yii2 的信息,请查看我们的并行系列 Programming With Yii2。
设计解决方案
随着时间的推移使用会议计划器,我经常想要一种方法来连续创建一系列日期和时间,例如接下来的三天上午 8:30 或接下来的三周周三晚上 7 点。当您有多种约会选择时,它只会让您更轻松地与人安排时间。
随着我对用户界面进行更深入的打磨,我终于有时间专注于这个问题。在我写任何代码之前,我决定在我想要的上面粗略地勾勒一下。
我决定创建一个重复数量,例如接下来的三个或五个,以及一个重复单位,例如小时、天或周。
换句话说,假设我正在邀请编辑机器人助理 Tom McFarlin 喝咖啡,并想提供接下来三个早晨中的任何一个,然后我选择 两天 后 在我选择的一天之后重复。
保持简单
我不希望人们总是为了安排会议而面对复杂的表格,因此我将日期时间重复功能与下面显示的高级选项链接分开。触摸或单击此链接将打开如下所示的表单:
开始编写代码
为了设计可在桌面和移动设备上使用的表单,我利用了 Bootstrap。本质上,我为表单创建了多行,这些行具有在移动设备上折叠的各种列宽。我们看看吧。
大多数 html 魔法都发生在 /frontend/views/meeting-time/_form.php 中。首先,这是包含Date、Time、Duration和高级选项链接的行:
<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 --> ...
高级选项toggleTimeAdvanced()链接的jQuery通过删除类打开重复表单: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_quantityandrepeat_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 框架的 /frontend/controllers/MeetingTimeController.php 中的 MVC 代码。下面,您可以看到actionAdd 响应 jQuery 提交的 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,以将 MeetingTime 开始和结束时间选择增加$repeat_unit,例如小时、天或周:
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 结合为您的用户构建简单的交互体验有所帮助。
如果您之前没有,请尝试在 Meeting Planner安排会议, 并使用重复的日期/时间选项,让我知道您的想法。
有自己的想法吗?想法?反馈?您可以随时在 Twitter @lookahead_io上 直接与我联系。观看使用 PHP 构建您的初创公司系列中即将发布的教程 。
在接下来的几周内,我将继续完善用户体验,以使服务尽可能易于使用。例如,您可能会注意到会议记录现在位于它们自己的选项卡上:
而且,为了消除人们在是/否开关的可用性列和选择最终位置的第二列之间存在的混淆,我将其分成了一个较低的按钮子面板,Finalize the Time。只有组织者和被指定为组织者的参与者才能看到这个下部面板,简化了典型参与者的共同视图:
Bootstrap、jQuery 和 Ajax 也部分或全部与构建这两个特性相关联。
我希望到现在为止,在本系列中,您已经有了自己的创业想法并考虑编写一些代码。请继续关注以了解有关我如何构建和启动我的更多信息。
- 保持简单