Это руководство является частью серии « Создай свой стартап с помощью PHP» на Envato Tuts +. В этой серии я проведу вас через запуск стартапа от концепции до реальности, используя мое приложение Meeting Planner в качестве примера из реальной жизни. На каждом этапе я буду публиковать код Планировщика собраний в качестве примеров с открытым исходным кодом, из которых вы можете извлечь уроки. Я также буду решать вопросы, связанные с бизнесом по мере их возникновения.
Использование Bootstrap, Ajax и jQuery
Благодаря нашей серии стартапов Meeting Planner и Simple Planner прошли невероятно долгий путь. Недавно я пытался настроить подробные области, чтобы сделать использование сервиса для планирования встреч еще более легким.
Если вы помните наш недавний эпизод « Построение стартапа: динамические формы Ajax для планирования» (Envato Tuts +) , вы знаете, насколько полезны Ajax и jQuery для удобства использования. Интерактивное планирование с Ajax изменило удобство использования сайта.
Затем я хотел улучшить одну болевую точку, с которой столкнулся при использовании сервиса. Честно говоря, отправление приглашений занимало много времени, предлагая несколько вариантов дат и времени. Каждый раз, когда я отправлял приглашение на собрание для своего собственного стартапа, мне приходилось вручную создавать две или три опции даты / времени — и это было довольно неприятно.
В сегодняшнем эпизоде я расскажу вам, как я упростил планирование встречи с несколькими связанными датами и временем за один шаг. В частности, я опишу, как я использовал Bootstrap, Ajax и jQuery для решения проблемы выбора даты и времени.
Bootstrap упростил разработку этой функции для настольных компьютеров, планшетов и мобильных устройств, а Ajax и jQuery сделали ее быстрой и интерактивной.
Если вы еще не опробовали Планировщик собраний или Простой планировщик , запланируйте свою первую встречу . Ищите тему этого урока, выбирая дату и время.
Я принимаю участие в комментариях ниже, так что скажите мне, что вы думаете! Вы также можете связаться со мной в Твиттере @lookahead_io . Мне особенно интересно, если вы хотите предложить новые функции или темы для будущих уроков.
Напоминаем, что весь код для Meeting Planner написан на Yii2 Framework для PHP. Если вы хотите узнать больше о Yii2, ознакомьтесь с нашей параллельной серией Программирование с Yii2 .
Разработка решения
С течением времени, используя Планировщик совещаний, я регулярно хотел создать серию дат и времен подряд, например, следующие три дня в 8:30 или следующие три недели в среду в 19:00. Это просто облегчает график с людьми, когда у вас есть несколько вариантов, когда вы собираетесь встретиться.
Поскольку я углубился в более глубокую доработку пользовательского интерфейса, у меня наконец-то появилось время сосредоточиться на этой проблеме. Прежде чем написать какой-либо код, я решил сделать набросок выше того, что хотел.
Я решил создать повторяющееся количество, например следующие три или пять, и единицу повторения, например часы, дни или недели.
Другими словами, допустим, я приглашаю помощника редактора-дроида Тома Макфарлина на кофе и хочу предложить любое из следующих трех утра, затем я выбираю два и несколько дней, чтобы повторить после моего выбранного дня.
Сохраняя это простым
Я не хотел, чтобы люди всегда сталкивались со сложной формой, просто чтобы запланировать встречу, поэтому я отделил функцию повторения даты и времени ссылкой на дополнительные параметры, показанную ниже. Если дотронуться или щелкнуть эту ссылку, откроется форма, показанная ниже:
Начинаем писать код
Чтобы разработать форму для работы как с настольными, так и с мобильными устройствами, я использовал Bootstrap. По сути, я создал несколько строк для формы с различной шириной столбцов, которые сворачиваются на мобильном устройстве. Давайте посмотрим.
Большая часть магии HTML происходит здесь, в /frontend/views/meeting-time/_form.php. Во-первых, вот строка со ссылкой Дата , Время , Продолжительность и дополнительные параметры :
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
<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(‘Ym-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(‘Ym-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, строка расширяется на рабочем столе (показано ниже) и сворачивается в три строки на мобильном устройстве (показано выше):
01
02
03
04
05
06
07
08
09
10
11
12
|
<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
класс:
1
2
3
4
5
6
7
|
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
времени timeAdvanced
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<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 eg 9 am, 10 am and 11 am’,
‘day’=>’successive day eg Monday, Tuesday & Wednesday’,
‘week’=>’successive week eg 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 отображается в одном ряду на настольных компьютерах и в двух рядах на мобильных устройствах:
1
2
3
4
|
<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 —>
|
Вот как выглядит добавление 3 дополнительных опций каждый следующий день в 9 часов утра :
Затем я обновил addTime()
для захвата и отправки полей repeat_quantity
и repeat_unit
в контроллер на основе PHP:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
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.
Затем я переключился на код MVC в своем / YB Framework /frontend/controllers/MeetingTimeController.php. Ниже вы можете увидеть метод actionAdd
AJAX, который отвечает на actionAdd
jQuery:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
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
на $repeat_unit
, например, часы, дни или недели:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
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 частично или полностью связаны с созданием обеих этих функций.
Я надеюсь, что в этой серии у вас есть собственные идеи для стартапов и вы думаете о написании кода. Оставайтесь с нами, чтобы узнать больше о том, как я строю и запускаю свою.