前例のない柔軟性と私の個人的な理解から、このエンジンを心から愛しています。
タスクは簡単に見えましたが、出会ったように、私はいくつかの難しい瞬間に会いました。
だから、彼のサイトでイベントのポップアップリストを使ってカレンダーを作りたい人は-Habrokatの下でお願いします!
タスクを完了するには、次のものが必要です。
- ニュース付きのドキュメント(コンテナ)。 これらは通常のmodxドキュメントである必要があります。
- JavaスクリプトjQueryUIおよびqTip。 1つ目はカレンダーを描画してその動作を保証し、2つ目はポップアップイベントです。
- eventCalendarスニペットはすぐにまとめます。
- 2つのチャンク(htmlデザイン)。 1つ目はスクリプトの呼び出しとカレンダーのデザインがある一般的なもので、2つ目はポップアップウィンドウでの1つのイベントの登録です。
- イベントドキュメントのTVパラメータ。 modx管理領域で作成されます。
最初に、イベントドキュメントのTVパラメーターを作成します。 [要素 ] -> [要素の管理] -> [パラメーター(TV)]-> [新しいパラメーター(TV) ]のmodx管理パネルに移動します。
: event_date
: event_date
: Date
: , , .
イベントを入力すると、このパラメーターが下に表示され、クリックすると、カレンダーにこのイベントを表示する日付を選択するウィンドウが表示されます。
次に、jQueryUI.datepickerのイベントの配列を返すスニペットを作成する必要があります。 一般に、このプラグインは
イベントを出力し、日付を選択します。 別の機能にそれを使用することは適切な解決策ではない可能性がありますが、このように使用する理由はいくつかあります。
まず、私はすでにサイトにjQueryUIを持っているのに、なぜ他のものに接続するのですか?
第二に、日付ピッカーは高度にカスタマイズ可能であり、表示される日付の範囲を指定したり、イベントをハングさせて日付を選択したり、月を変更したりすることができます。
これにより、独自の自転車を発明することなく、ajaxリクエストを含むイベントの素敵なカレンダーを作成できます。
そう思った。
実際、このアプローチにはいくつかの不都合が伴うことが判明しましたが、それらについては後で詳しく説明します。
スニペットイベントカレンダー。 サーバー側で作業します。
そのため、スニペットを作成しています。 しばらくの間、クラスを書かずに「hello world!」を推測することはできません。事前に申し訳ありません。
<?php class eventsCalendar { var $id; // - var $dateFormat = '%d %b %Y %H:%M'; // , strftime() var $dateTV = 'event_date'; // TV modx var $tplEvent = 'tplEvent'; // var $tplMain = 'tplCalendar'; // var $conv = 0; // cp1251 utf8. - . /* */ function error($err) { $arr = array( 'no_id' => ' id ', 'no_action' => ' ajax .', 'no_result' => ' .' ); return $arr[$err]; } /* , , */ function getEvents($id = '', $month = '', $year = '') { global $modx; if (empty($id)) {return $this->error('no_id');} if (empty($month)) {$month = date('m');} if (empty($year)) {$year = date('Y');} if (strlen($month) == 1) {$month = '0'.$month;} /* , id */ $tmp = $modx->getDocumentChildrenTVars($id, array('id',$this->dateTV)); /* */ if (empty($tmp)) {return $this->error('no_result');} else { foreach ($tmp as $v) { $d = strftime('%Y-%m', strtotime($v[0]['value'])); if ($d == $year.'-'.$month) {$ids[] = $v[1]['value'];} $dates_arr[$v[1]['value']] = $v[0]['value']; } } /* $ids, , , . */ $arr = $modx->getDocuments($ids, 1, 0, "id,pagetitle,introtext", "", 'pub_date ASC, id', 'ASC'); /* - , */ if (empty($arr)) {return json_encode(array());} /* - , */ /* */ $tpl = $modx->getChunk($this->tplEvent); $i = 1; foreach ($arr as $v) { /* */ $did = $v['id']; $url = $modx->makeUrl($did); $date = strftime($this->dateFormat, strtotime($dates_arr[$did])); $date2 = strftime('%Y-%m-%d', strtotime($dates_arr[$did])); $desc = $v['introtext']; $title = $v['pagetitle']; /* , */ if (isset($date3) && $date3 != $date2) {$i = 1;} $date3 = $date2; /* modx */ $placeholders = array('[+ec.date+]','[+ec.title+]','[+ec.url+]','[+ec.desc+]','[+ec.num+]'); $values = array($date, $title, $url, $desc, $i); $text = str_replace($placeholders, $values, $tpl); /* , cp1251. */ if ($this->conv != 0) {$dates[$date2] .= iconv('cp1251', 'utf-8', $text);} else {$dates[$date2] .= $text;} $i++; } /* .. jqueryui.datepicker '','css class',' ' - */ foreach($dates as $k => $v) { $dates2[] = array($k, '', $v); } /* json */ return json_encode($dates2); } /* , */ function output($tpl) { global $modx; $tpl = $modx->getChunk($tpl); echo $tpl; } } /* , , modx */ $Cal = new eventsCalendar; $Cal->id = $id; // ! /* - */ if (!empty($dateTV)) {$Cal->dateTV = $dateTV;} if (!empty($dateFormat)) {$Cal->dateFormat = $dateFormat;} if (!empty($tplEvent)) {$Cal->tplEvent = $tplEvent;} if (!empty($tplMain)) {$Cal->tplMain = $tplMain;} if (!empty($conv)) {$Cal->conv = $conv;} /* ajax - */ if ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') { $action = $_POST['action']; if (!empty($action)) { switch($action) { case 'getEvents': echo $Cal->getEvents($Cal->id, $_POST['month'], $_POST['year']); break; } } else { echo $Cal->error('no_action'); } die(); } /* - */ else { $Cal->output($Cal->tplMain); } ?>
次に、modx管理パネルに移動してスニペットを作成し、新しいスニペットを作成して、eventsCalendarという名前を付けて、上記にコピーします。
新しいスニペットを作成し、ページ上の任意の場所で次のように呼び出します。
[!eventsCalendar?
&id=`13`
&dateTV=`event_date`
&dateFormat=`%d %b %Y %H:%M`
&tplMain=`tplCalendar`
&tplEvent=`tplEvent`
!]
トピックの最後にあるパラメーターを参照してください。
彼が何も表示しない限り、私たちはパターンを書きませんでした。
チャンク。 クライアント側で作業します。
小さいものから始めましょう-tplEventイベントテンプレート。
<div class='event'> <span class='num'><b>[+ec.num+].</b></span> <span class='date'>[+ec.date+]</span> <span class='link'><a href='[+ec.url+]' target='_blank'>[+ec.title+]</a></span> <br /> <span class='notice'>[+ec.desc+]</span> </div> <br />
次に、大きなテンプレート。
落書きが多いため、デザイン全体をスキップします。ここでは主なもののみを示し、残りは添付ファイルです。
ライブラリを接続する必要があります(パスに注意してください)。
<script type='text/javascript' src='[(site_url)]inc/js/jquery-1.4.4.min.js'></script> <script type='text/javascript' src='[(site_url)]inc/js/jquery-ui-1.8.6.custom.min.js'></script> <script type='text/javascript' src='[(site_url)]inc/js/jquery.ui.datepicker-ru.js'></script> <!-- datepicker --> <script type='text/javascript' src='[(site_url)]inc/js/jquery.qtip.js'></script>
今、主な魔法。
<script type='text/javascript'> $(document).ready(function() { class_enabled = 'enabled'; // , class_disabled = 'disabled'; // element = '#Calendar'; // DOM url = '/[~[*id*]~]'; // ajax, - dates = getEvents(); // ajax Calendar(dates); // Qtip(); // qTip, }); // . function Calendar(dates) { $(element).datepicker({ language: 'ru', inline: true, dateFormat: 'dd.mm.yy', // - . , 1 qTip, // DOM . onChangeMonthYear: function(year, month) { dates = getEvents(year, month); window.setTimeout( function() { Qtip() }, 1000 ); }, // - , . // 3: /, , title td. beforeShowDay: function(d) { var date = $.datepicker.formatDate('yy-mm-dd', d); for (i = 0, c = dates.length; i < c; i++) { if (date == dates[i][0]) { return [true, class_enabled, dates[i][2]]; } } return [false, class_disabled]; }, // . - . onSelect: function() {return false;} }); } // ajax . // - , , , - . // , , . function getEvents(year, month) { $.ajaxSetup({async: false}); $.post(url, {action: 'getEvents', month: month, year: year}, function(data) { if (data == 'null') {data = '[]';} dates = jQuery.parseJSON(data); response = dates; } ) return response; } // qTip. // . title . function Qtip() { $(element + ' .' + class_enabled).qtip({ prerender: true, show: {when: {event: 'mouseover'}, effect: {length: 0}, solo: true}, hide: {when: {event: 'unfocus'}, effect: {length: 0}}, position: { corner: { target: 'center', tooltip: 'topLeft' } }, style: {height: 100,width: 300} }); } </script>
<div id='Calendar'></div> -- ,
私は今でも、月を変更するときにカレンダーを暗くして、ダウンロードインジケーターを表示するためにいくつかのものを使用しています。
複雑なことはありません。 ここで確認できます 。
どのように機能しますか?
最初にページを開くと、tplCalendarテンプレートが表示されます。 ロードした後、日付の配列の要求機能が開始されます。
配列が到着するとすぐにカレンダーが開始され、日付をレンダリングするときにツールチップのスタイルとテキストが割り当てられます。
次に、qTipが開始され、ツールチップが生成されます。
月を変更すると、日付の新しい配列が要求され、ポップアップが再起動されます(DOMが変更されたため)。
同時に、日付をクリックしてイベントをハングアップすることもできます(たとえば、その日付のニュースページに移動します)。 月を変更するには(私は持っています
ダウンロードインジケータが表示され、カレンダー自体が暗くなっています)。 ポップアップウィンドウの外観は、スタイルとコンテンツの両方で完全にカスタマイズ可能です。
今、欠点について。 それらのいくつかがあります。
- 各カレンダー操作の後にqTipを呼び出す必要。 (少なくとも私はどのように思い付かなかった)どのカレンダーを見つけることは不可能なので
準備ができて、1秒のタイムアウトでそれをしなければなりません。 サーバーが遅い場合、または非常に多くのイベントがある場合、2番目のイベントでは不十分な場合があります。 一方、
タイムアウトは変更でき、作成するイベントが非常に多いため、通常のサーバーでは1秒でそれらを処理する時間がありませんでした。 - ポップアップのテキストはtd要素のtitle属性に書き込まれるため、引用符とそのエスケープについて覚えておく必要があります。
この特定のタスクのphpでカレンダーを書くことで欠点を回避できますが、datepickerの利点はイベントを出力するための使用の欠点よりも重要であると判断しました。
アプリケーション。
スニペットとテンプレートを使用してアーカイブをダウンロードする
作業中のビュー(革命版)
EventsCalendarスニペットオプション:
&id
: ,
: [int]
: ID - .
&dateFormat
: '%d %b %Y %H:%M'
: strftime()
: .
&dateTV
: event_date
: tv
: TV modx .
&tplEvent
: tplEvent
: modx
: .
&tplMain
: tplCalendar
:
: .
&conv
: 0
: [int]
: cp1251 utf8.
EventCalendarスニペットプレースホルダー:
[+ ec.num +]
. , . ,
TV . , .
[+ ec.date +]
.
[+ ec.url +]
.
[+ ec.title +]
, pagetitle modx.
[+ ec.desc +]
, introtext modx.
必要なサイトへのリンク。
UPD。
バグレポートをbezumkin@yandex.ruに送信するか、このスレッドに残してください。
UPD.2
カレンダーの2番目のバージョンは、 datepickerなしで、関連する欠陥なしで準備完了です!