Tagalog (Wikang Tagalog) translation by Anna Nelson (you can also view the original English article)

Ang tutorial na ito ay bahagi ngserye tungkol sa pagbuo ng iyong startup gamit ang PHP sa Envato Tuts+. Sa seryeng ito, gagabayan ko kayo sa paglulunsad ng isang startup mula sa konsepto sa kasalukuyan gamit ang aking Meeting Planner app bilang isang makatotohanan na halimbawa. Bawat hakbang sa kahabaan ng proseso, ibibigay ko ang open-source code ng aking Meeting Planner app bilang halimbawa kung saan maaari mong malaman ang pinagmulan. Tatalakayin ko din angmga isyu tungkol sa negosyo kung meron tayong madaanan.
Panimula
Para sa pagtuturong ito ngayon, gagabayan ko kayo tungo sa pangunahing pangkat ng mga komprehensibong pagbabago papunta sa meeting schedule interface. Ang layunin ko ay gamitin ang Ajax upang magawang posible ang lahat ng karaniwang scheduling activities ng hindi nirerefresh ang page. Ang ilang aspeto nito ay simple para sa iba habang ang iba ay bahagyang nahihirapan. Sa episode na ito, magfofocus ako sa ilang mga direktang mga bahagi: kung paano gumawa ng mga Ajax UX requests sa iyong PHP-based na Yii application.
Sa pangalawang bahagi, tatalakayin ko ang mas mahirap na self-debugging ng Ajax at pagre-re-initialize ng Bootstrap widgets matapos ang pangunahing pagload ng page. Ibabahagi ko rin kung papaani ko ginamit ang Google Chrome browser upang matulungan akong kilalanin ang isang sirang code.
Sa totoo lang, habang ang mga pangunahing updates ay maayos naman, may mga naranasan akong ilang roadblocks at mga hirap na minsan ay iniisip kong baka kailangan ko nang sumuko sa aking goal na beta release.
Ang kakaiba dito, may mga code paths na mukha namang
nakakatulong saking matapos at pagkatapos ay biglang magkakaroon ng sari-saring
problema—at kakailanganin ko uling magsimula gamit ang panibagong approach. Sa huli, nagawa ko ring makumpleto ang isang full
scheduling gamit ang Ajax para sa beta release.
Subaybayan niyo ako ngayong araw upang magabayan ko kayo sa pinakamahalgang bahagi nito.
Kung hindi nyo pa nasusubukan ang Meeting Planner,
humayo kayo at subukang i-schedule ang iyong unang meeting gamit ang mga
makabago nitong interactive capabilities. Nakikisali ako sa mga comment thread sa ibaba, kaya
naman sabihin nyo sa akin kung anong sa tingin nyo! Maaari ninyo rin akong ma-reach sa Twitter @reifman. Mas interesado ako kung makakapag-suggest kayo ng mga
bagong itatampok o mga paksa sa aming mga pagtuturo sa hinaharap.
Bilang paalala, ang lahat ng mga code para sa Meeting Planner ay nakasulat sa Yii2 Framework para sa PHP. Kung gusto mong matuto nang iba pa tungkol sa Yii2, tingnan ang aming parallel series Programming Sa Yii2.
Pagsi-streamline ng Scheduling UX
Ang pangunahing layunin ko sa bahaging ito ng produkto ay mai-implement lahat ng pangunahing scheduling features gamit ang Ajax at tanggalin ang page refreshes na sa kasalukuyan ay kailangan para sa pageedit ng paksa, pagdadagdag ng mg kalahok, pagdadagdag ng mga oras at petsa, mga lugar at mga notes.
Background
Habang bumubuo ako ng Ajax sa site kanina, mayroon akong ilang mga ideya kung anong mga uubra at kung alin-alin ang mahirap.
Samahan nyo ako habang ipinapakita ko ang mga
pangunahing elemento ng pag—aajaxify ng scheduling.
Pag-eedit ng Pangunahing Subject

Sinimulan kong i-edit ang meeting subject panel sapagkat ito ay binubuo ng ng ilang mga static fields, isang input at isang text area. Gayunpaman, ang subject field ay gumagamit ng jQuery Typeahead widget. Widgets ay maaaring makapagkumplika ng mga bagay sapagkat kailangan mong mai-initialize ang mga ito ng hindi isinasantabi ang konsepto ng Ajax.
Sa kaso nito, pinreload ko ng nakatago ang form at ini-load ang widget library kasabay nito. Hindi naman ito masyadong mahirap. Sa susunod na episode, makikita niyong ang Bootstrap Switch widget sa date time at place panels ay magpapahirap sa hakbag na ito.
Pagpi-preaload ng Lahat ng JavaScript
Kaya naman, para mas pasimplehin ang page-ajax ng bawat scheduling panel (mga kalahok, paksa, mga petsa at oras, mga lugar at mga notes), Ikakarga ko ang mga ito up front at i-eexpand ang mga laman ng meeting.js.
Pinalawak ko rin ang definition ng MeetingAsset.php upang makapagsama ng mas maraming JavaScript:
<?php namespace frontend\assets; use yii\web\AssetBundle; class MeetingAsset extends AssetBundle { public $basePath = '@webroot'; public $baseUrl = '@web'; public $css = [ 'css/bootstrap-combobox.css', ]; public $js = [ 'js/meeting.js', 'js/meeting_time.js', 'js/jstz.min.js', 'js/bootstrap-combobox.js', 'js/create_place.js', ]; public $depends = [ 'yii\web\YiiAsset', 'yii\bootstrap\BootstrapAsset', ]; }
Ang MeetingAsset ay kinargahan ng Meeting view.php na file:
<?php use yii\helpers\BaseHtml; use yii\helpers\Html; use yii\widgets\DetailView; use yii\widgets\ListView; use common\components\MiscHelpers; use frontend\assets\MeetingAsset; MeetingAsset::register($this);
Paglo-load ng Subject Panel
Ang mga detalye subject at meeting ay kasama sa
_panel_what.php na partial. Sa ibaba, isinet-up ko ito na nakatago sa load sa loob
ng #editWhat
:
<?php if ($model->has_subject || $model->subject == \frontend\models\Meeting::DEFAULT_SUBJECT) { ?> <div id="collapseWhat" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingWhat"> <div class="panel-body"> <div id="showWhat"> <?php if (empty($model->message)) { echo Html::encode($this->title); // note: required because couldn't prevent extra space } else { echo Html::encode($this->title).': '.Html::encode($model->message).' '; } ?> </div> <div id="editWhat" class="hidden"> <?= $this->render('_form', [ 'model' => $model, 'subjects' => $model->defaultSubjectList(), ]) ?> </div> </div> </div> <?php } else { ?>
Ikinabit ko ang edit button (gamit ang pencil icon) sa
_panel_what.php upang mai-call ang isang JavaScript showWhat()
toggle function
upang maipakita o maitago ang editing form. Narito ang code:
<?php if ($model->isOrganizer() && $model->status <= Meeting::STATUS_CONFIRMED) { //['update', 'id' => $model->id] echo Html::a('', 'javascript:void(0);', ['class' => 'btn btn-primary glyphicon glyphicon-pencil', 'title'=>'Edit','onclick'=>'showWhat();']); } ?>
Ang showWhat()
function mula sa meeting.js ay makikita
sa ibaba:
// show the message at top of what subject panel function showWhat() { if ($('#showWhat').hasClass( "hidden")) { $('#showWhat').removeClass("hidden"); $('#editWhat').addClass("hidden"); }else { $('#showWhat').addClass("hidden"); $('#editWhat').removeClass("hidden"); $('#meeting-subject').select(); } }; function cancelWhat() { showWhat(); }
Narito ang itaas na bahagi ng /frontend/views/meeting/_form.php na itinatago o pinapakita nito. Dito dapat lalabas ang input at textarea fields:
<?php use yii\helpers\Html; use yii\widgets\ActiveForm; use \kartik\typeahead\TypeaheadBasic; use common\components\MiscHelpers; /* @var $this yii\web\View */ /* @var $model frontend\models\Meeting */ /* @var $form yii\widgets\ActiveForm */ ?> <div class="meeting-form"> <?php $form = ActiveForm::begin(); ?> <div class="row"> <div class="col-md-6"> <?php echo $form->field($model, 'subject')->widget(TypeaheadBasic::classname(), [ 'data' => $subjects, 'options' => ['placeholder' => Yii::t('frontend','what\'s the subject of this meeting?'), 'id'=>'meeting-subject', //'class'=>'input-large form-control' ], 'pluginOptions' => ['highlight'=>true], ]); ?> </div> </div>
Paga-update ng Paksa at Detalye ng Meeting gamit ang Ajax
Kapag inupdate ng user ang meeting form, tatawagin ng
Ajax ang sumusunod:
// meeting subject panel function updateWhat(id) { // ajax submit subject and message $.ajax({ url: $('#url_prefix').val()+'/meeting/updatewhat', data: {id: id, subject: $('#meeting-subject').val(), message: $('#meeting-message').val() }, success: function(data) { $('#showWhat').text($('#meeting-subject').val()); showWhat(); } }); }
Ang function na actionUpdatewhat
ay nasa loob ng
MeetingController.php:
public function actionUpdatewhat($id,$subject='',$message='') { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; if (!Meeting::isAttendee($id,Yii::$app->user->getId())) { return false; } $m=Meeting::findOne($id); $m->subject = $subject; $m->message = $message; $m->update(); return true; }
Pansinin ang Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
na nagcoconfigure sa Yii method upang
maging JSON, at hindi HTML.
Isa pa, ang Meeting:isAttendee()
function ay isang
authentication check upang siguruhing ang nakalog-in na user ay isang attendee
bago i-update ang datos ng meeting.
Ang Natutunan ko Hanggang Rito
Tulad ng nakikita nyo, kakailanganin ng ilang mga code upang mai-ajaxify ang lahat ng mga ito.
Isa sa mga hamon ay ang pagpalipat-lipat sa maraming files ng sabay-sabay at dalawang magkaibang languages. Ang PHP at JavaScript ay magkaiba ang pamamaraan ng paggawa ng mga bagay-bagay. Halimbawa, ang pag-concatenate ng strings ay ginagawa sa pamamagitan ng period sa PHP, at plus sign naman sa JavaScript. Ang pagpapapalit-palit ng mga languages na sinusubukang gumawa ng query parameter strings ay maaaring magresulta sa maraming errors.
Kakailanganin din ng masinsinang security checks sa
loob ng aking PHP-based na Ajax functions. Sa pagtuturo ngayong araw, makikita mo ang simula
nito, ngunit kakailanganin ko pang magdadagdag ng ilan pang masuring security
checks bago maaaring gawing live ang code.
At sa huli, habang ginagawa ko ito, sinubukan kong gamitin muli ang ilang notations at structural approaches ng sa gayon ay ang lahat ng code ay may parehong composition at termonolohiya dito–sa kabila ng paggamit nito ng magkakaibang data elements.
Pagpapadala ng Meeting Notes

Ang mga meeting notes ay mga static na textarea fields rin. Gayunpaman, maaaring magkaroong ng tumatakbong thread ng mga notes na kakailanganin i-update sa page kapag may nagdagdag ng isa (e.g. higit pa sa isang meeting subject). At mahalaga ding sabihin sa user na ino-notify ang mga kalahok sa bagong note na ito.
Halimbawa, tinanggal ko ang submit button UX sa
scheduling ng sa gayon ay pagpaplano ay magiging mabilis at mabisa. Ang mga user ng New Meeting Planner ay madalas na
nalilito dito kaya naman nagdagdag ako ng alerts para malaman nilang inaayos ko
ito.

Mga coding notes sa pamamagitang ng Ajax
Una, nariyan ang _panel.php para sa Meeting note. Gumawa na ako ng mga natatagong error alerts na maaaring i-display sa pamamagitan ng jQuery pag kinakailangan. Pinaplano kong pasimplehin at i-standardize ang mga error alerts ang mga ito sa hinaharap, kasama na ang pagpapadali sa paggamit nito ng localization sa mga messages.
Sa halimbawa sa ibaba, ang parehong noteMessage1
at
noteMessage
2 ay naka-load ng nakatago.
<?php use yii\helpers\Html; use yii\bootstrap\Collapse; ?> <div id="noteMessage" class="alert-info alert fade in hidden"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> <span id="noteMessage1"> <?= Yii::t('frontend',"Thanks for your note. We'll automatically share it with other participants.")?></span> <span id="noteMessage2"> <?= Yii::t('frontend','Please be sure to type a note.')?></span> </div> <div class="panel panel-default"> <!-- Default panel contents --> <div class="panel-heading" role="tab" id="headingNote" > <div class="row"> <div class="col-lg-10 col-md-10 col-xs-10"><h4 class="meeting-view"> <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseNote" aria-expanded="true" aria-controls="collapseNote"><?= Yii::t('frontend','Notes') ?></a></h4> <span class="hint-text"><?= Yii::t('frontend','send a message to others') ?></span> </div> <div class="col-lg-2 col-md-2 col-xs-2" > <div style="float:right;"> <?= Html::a('', 'javascript:void(0);', ['class' => 'btn btn-primary glyphicon glyphicon-plus', 'title'=>'Edit','onclick'=>'showNote();']); ?> </div> </div> </div> </div> <div id="collapseNote" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingNote"> <div class="panel-body nopadding"> <div id="editNote" class="hidden"> <?= $this->render('_form', [ 'model' => $model, ]) ?> </div> </div> <div id ="noteThread" class="nopadding"> <?= $this->render('_thread', [ 'model' => $model, 'noteProvider'=>$noteProvider, ]) ?> </div> </div> </div>
Ito ang jQuery na naghahanap ng blank note, nagpapakita ng tamang error o nagpapasa ng content sa Ajax upang manghingi ng note thread update, at nagpapakita ng success alert.
function updateNote(id) { note = $('#meeting-note').val(); if (note =='') { displayAlert('noteMessage','noteMessage2'); return false; } // ajax submit subject and message $.ajax({ url: $('#url_prefix').val()+'/meeting-note/updatenote', data: {id: id, note: note}, success: function(data) { $('#editNote').addClass("hidden"); $('#meeting-note').val(''); updateNoteThread(id); displayAlert('noteMessage','noteMessage1'); return true; } // to do - error display flash }); } function updateNoteThread(id) { // ajax submit subject and message $.ajax({ url: $('#url_prefix').val()+'/meeting-note/updatethread', data: {id: id}, type: 'GET', success: function(data){ $('#noteThread').html(data); // data['responseText'] }, error: function(error){ } }); }
Isa sa mga to-dos ay ang paghahandle ng errors sa Ajax. Hindi madaling gawin ito at nangangailangan ng mabusising arkitektura sa lahat ng lugar upang masuportahan ito – sa ngayon, tinuloy ko na ang process ng hindi hinahandle ang ganitong klase ng error.
Narito ang displayAlert()
JavaScript function na
ginamit ko uli at binuo para sa iba ibang uri ng panels at ng kanilang mga
alert messages:
function displayAlert(alert_id,msg_id) { // which alert box i.e. which panel alert switch (alert_id) { case 'noteMessage': // which msg to display switch (msg_id) { case 'noteMessage1': $('#noteMessage1').removeClass('hidden'); // will share the note $('#noteMessage2').addClass('hidden'); $('#noteMessage').removeClass('hidden').addClass('alert-info').removeClass('alert-danger'); break; case 'noteMessage2': $('#noteMessage1').addClass('hidden'); $('#noteMessage2').removeClass('hidden'); // no note $('#noteMessage').removeClass('hidden').removeClass('alert-info').addClass('alert-danger'); break; } break; case 'participantMessage': // which msg to display $('#participantMessageTell').addClass('hidden'); // will share the note $('#participantMessageError').addClass('hidden'); $('#participantMessageOnlyOne').addClass("hidden"); $('#participantMessageNoEmail').addClass("hidden"); switch (msg_id) { case 'participantMessageTell': $('#participantMessageTell').removeClass('hidden'); // will share the note $('#participantMessage').removeClass('hidden').addClass('alert-info').removeClass('alert-danger'); break; case 'participantMessageError': $('#participantMessageError').removeClass("hidden"); $('#participantMessage').removeClass("hidden").removeClass('alert-info').addClass('alert-danger'); break; case 'participantMessageNoEmail': $('#participantMessageNoEmail').removeClass("hidden"); $('#participantMessage').removeClass("hidden").removeClass('alert-info').addClass('alert-danger'); break; case 'participantMessageOnlyOne': $('#participantMessageOnlyOne').removeClass("hidden"); $('#participantMessage').removeClass("hidden").removeClass('alert-info').addClass('alert-danger'); break; } break; case 'placeMessage': // which msg to display $('#placeMsg1').addClass('hidden'); // will share the note $('#placeMsg2').addClass('hidden'); // will share the note $('#placeMsg3').addClass('hidden'); // will share the note switch (msg_id) { case 'placeMsg1': $('#placeMsg1').removeClass('hidden'); // will share the note $('#placeMessage').removeClass('hidden').addClass('alert-info').removeClass('alert-danger'); break; case 'placeMsg2': $('#placeMsg2').removeClass('hidden'); // will share the note $('#placeMessage').removeClass('hidden').removeClass('alert-info').addClass('alert-danger'); break; } break; case 'timeMessage': // which msg to display $('#timeMsg1').addClass('hidden'); // will share the note $('#timeMsg2').addClass('hidden'); // will share the note //$('#timeMsg3').addClass('hidden'); // will share the note switch (msg_id) { case 'timeMsg1': $('#timeMsg1').removeClass('hidden'); // will share the note $('#timeMessage').removeClass('hidden').addClass('alert-info').removeClass('alert-danger'); break; case 'timeMsg2': $('#timeMsg2').removeClass('hidden'); // will share the note $('#timeMessage').removeClass('hidden').removeClass('alert-info').addClass('alert-danger'); break; } break; } }
Paga-update ng Thread ng mga Notes
Kapag ang user ay nagpasa ng bagong note, Ang
MeetingNoteCOntroller.php actionUpdatethread()
ay tinatawag sa pamamagitan ng
Ajax. Narito ang PHP:
public function actionUpdatethread($id) { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $m=Meeting::findOne($id); $noteProvider = new ActiveDataProvider([ 'query' => MeetingNote::find()->where(['meeting_id'=>$id]), 'sort'=> ['defaultOrder' => ['created_at'=>SORT_DESC]], ]); $result = $this->renderPartial('_thread', [ 'model' =>$m, 'noteProvider' => $noteProvider, ]); return $result; }
Nageksperimento ako minsan sa pamamagitan ng simpleng pagbabalik ng pinakabagong item na may laman (i.e. pinakabagong note) at pagsisingit nito sa taas ng mga naunang items. Ngunit, medyo magulo ito, lalo na sa mga oras at petsa at mga lugar na nakikita sa mga table rows.
Sa ngayon, papalitan ko ang buong updated thread ng content at papalitan ang buong panel gamit ang Ajax. Narito na ang _thread.php partial na nagloload ng lahat ng notes na ito, kasama na ang bago:
<?php use yii\widgets\ListView; use yii\helpers\Html; if ($timeProvider->count>0): ?> <table class="table"> <?= ListView::widget([ 'dataProvider' => $timeProvider, 'layout' => '{items}', 'itemView' => '_list', ]) ?> </table> <?php endif; ?>
Sana naman ay sapat na ito upang mapag-aralan at masubukan sa ngayon.
Literal na gumugol ako ng lima hanggang pitong mahahabang coding days kasama na ang mga puyatan para lang makumpleto ang code sa likod ng episode na ito at ng kasunod. Ni hindi ako nagpupuyat ng matagal nang panahon. Gayunpaman, mahusay pa rin ang mga naging resulta.
Ano na bang susunod?
Sana ay naging malaking tulong ang makita ang mga basics ng Ajax development para sa Yii at PHP. Totoong marami akong natutunan sa prosesong ito, at nagawang pabilisin at padaliin ang pagsischedule ng meetings.
Sa susunod na episode, tatalakyin ko ang mga natitirang features na pagdadagdag ng mga oras at petsa at mga lugar gamit ang tulong ng mga Google Chrome Browser debugging tools.
Habang kayo’y nagaantay ng susunod na episode, i-schedule na ang una mong meeting at subukan ang scheduling features ng Ajax. Isa pa, mas ikatutuwa ko kung ibabahagi ninyo ang inyong karanasan sa comments, at ako’y laging matutuwang makinig sa inyong mga panukala. Maaari nyo rin akong makontak ng direkta sa Twitter @reifman.
Ang Meeting Planner preview release ay maaari nyo nang makita. Maaari nyo na itong ibahagi sa inyong mga kaibigan at katoto upang magamit din nila.
Sa huli, nagsisimula na akong magexperimento gamit sa
WeFudner base sa implementasyon ng bagong patakaran ng SEC sa pagka-crowdfund. Maaari ninyong i-follow ang aming profile doon kung
nais ninto. Magsusulat din ako ng mas malawak pa tungkol dito sa
mga hinaharap na pagtuturo.
Abangan ang aking ilalabas na serye ng tutorial ukol
sa Pagbuo ng Iyong Startup Gamit ang PHP.
Related Links
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post