This topic is locked

Meeting calendar, javascript of Daypilot

1/7/2020 2:55:07 PM
PHPRunner Tips and Tricks
fhumanes author

[size="4"]Use Calendars to show project meetings[/size]
This is another of the required functionalities of the projects. In this case, the example is to inform of the proposed solution of representation of "calendars" using one of theDaypilot libraries.
As I always indicated, this is not a meeting planning solution, but an example of using these libraries integrated in PHPRunner for you to adapt it to your requirements.
Also, indicate that the use of this interface and its interactions with PHPRunner can be enhanced much more, but to leave a not very complex example it has been left quite simple, however, commented code is left to evolve and, you can always ask me, if You don't see something.

Definition of the requirements of the example
I started from a Database scheme that had already worked on the Project and Kanban examples, where we had Projects that in turn were related to Companies and Departments of these Companies.
Meetings have made them depend on the projects and they are assigned Resources (Users) and Files (to share before the meeting).
The application must provide:

  • Show the meetings of a selected Project, or of a Company or a Department.
  • Show a user's meetings.
  • Show the occupation of related users in a Meeting, to see if the proposed date (date of the meeting) is available or not for all users.


Below I show some of the screens in the example and explain some notable characteristics of them.


This is the menu screen and it is nothing special (with respect to the other examples I have provided).


Have:

  • A background image.
  • An application icon.


These 5 tables look the same as this one, that is, a button has been added to show the Calendar of meetings filtered by the Entity and register where the button is pressed.


The calendar only has a representation for all the buttons of all the entities, also, it adjusts to the availability of the space available on the screen, but it is not adapted for the mobile.
Projects and users have an assigned color and is used in the presentation.
From this same screen, you can register new meetings and by clicking on one of the meetings, you can go to the consultation and from there, you can go on to edit the meeting. Always, when registering and modifying meetings there is a reload of the screen and all its data.


The registration, consultation and editing screens are the PHPRunner screens in its "popup" version.
Daypilot has very, very powerful javascript libraries and all of them are used in the same way as this example, so if you need to show and manage your data associated with dates, surely you have a solution with these libraries.
To try the example, connect to https://fhumanes.com/meetings/. Use the user "admin" and password "admin". Please do not destroy the data. If they are deleted by mistake, I beg you to tell me (email) to restore them.
I show you the presentation code, which is separated in the file “ICM/calendar.php”.





<?php

global $conn;

/* Session variable

$_SESSION['project_id']

$_SESSION['project_name']

$_SESSION['option_calendar'] valor: project | user | company | departament | meeting

$_SESSION['language']

$_SESSION['user_id']

$_SESSION['login']

$_SESSION['email']

$_SESSION['username']

$_SESSION['company_id']

$_SESSION['dept_id']

* ----------Currently unused ------------------

$_SESSION['nav_start'];

$_SESSION['nav_end']

* ----------------------------------------------

*/

$site = $_SESSION['config'][array_search('URL', array_column($_SESSION['config'], 'name'))][value].'/';

// $ajax_mes = $_SESSION['config'][array_search('MEETINGS_AJAX', array_column($_SESSION['config'], 'name'))][value].'?';

/* ----------Currently unused ------------------

$start_date = date("Y-m-d",strtotime("-1 month",strtotime(date("Y-m-01",strtotime("now")))));

$end_date = date("Y-m-d",strtotime("+1 month",strtotime(date("Y-m-01",strtotime("now")))));

$day = date("Y-m-d",strtotime(date("Y-m-01",strtotime("now"))));

$start_date.='T12:00:00';

$end_date.='T12:00:00';

$day.='T12:00:00';

*/

if ($_SESSION['language'] == 'Spanish') {

$language = 'es-es'; // Spanish

} else {

$language = 'en-us'; // English

}

switch ($_SESSION['option_calendar']) {

case 'project':

$sql = "SELECT idmeetings id , m.name, username resource, m.start_date, m.end_date, p.color_identifier color

FROM meetings m

join users on ( owner = user_id )

join projects p on (projects_project_id = project_id)

where projects_project_id =" . $_SESSION['project_id'];

break;

case 'user':

$sql = "SELECT distinct idmeetings id , m.name, username resource, m.start_date, m.end_date, p.color_identifier color

FROM meetings m

join projects p on (m.projects_project_id = p.project_id)

join users_meetings um on (um.meetings_idmeetings = m.idmeetings)

join users u on ( um.users_user_id = u.user_id )

where u.user_id =" . $_SESSION['user_id'];

break;

case 'company':

$sql = "SELECT idmeetings id , m.name, username resource, m.start_date, m.end_date, p.color_identifier color

FROM meetings m

join users u on ( owner = user_id )

join projects p on (m.projects_project_id = p.project_id)

join companies c on (p.companies_company_id = c.company_id)

where c.company_id =" . $_SESSION['company_id'];

break;

case 'departament':

$sql = "SELECT idmeetings id , m.name, username resource, m.start_date, m.end_date, p.color_identifier color

FROM meetings m

join users u on ( owner = user_id )

join projects p on (m.projects_project_id = p.project_id)

join departments d on (p.departments_dept_id = d.dept_id)

where d.dept_id =" . $_SESSION['departament_id'];

break;

case 'meeting':

$sql = "SELECT idmeetings id , m.name, u.username resource, m.start_date, m.end_date, u.color_identifier color

FROM meetings m

join users_meetings um on (um.meetings_idmeetings = m.idmeetings)

join users u on ( um.users_user_id = u.user_id )

where idmeetings <>" . $_SESSION['meeting_id'];

break;

}

$resql = db_query($sql,$conn);

If (mysqli_num_rows($resql) == 0) { // No records

echo 'There is no information to show';

} else {

$str1 = <<<EOD

<!-- helper libraries

<script src="daypilot/js/jquery-1.12.2.min.js" type="text/javascript"></script>

-->

<!-- daypilot libraries -->

<script src="daypilot/js/daypilot-all.min.js?v=2019.4.4160" type="text/javascript"></script>

<!-- daypilot themes -->

<link type="text/css" rel="stylesheet" href="daypilot/themes/areas.css?v=2019.4.4160" />

<link type="text/css" rel="stylesheet" href="daypilot/themes/month_white.css?v=2019.4.4160" />

<!--

<link type="text/css" rel="stylesheet" href="../demo/themes/month_green.css?v=2019.4.4160" />

<link type="text/css" rel="stylesheet" href="../demo/themes/month_transparent.css?v=2019.4.4160" />

<link type="text/css" rel="stylesheet" href="../demo/themes/month_traditional.css?v=2019.4.4160" />

-->

<link type="text/css" rel="stylesheet" href="daypilot/themes/navigator_8.css?v=2019.4.4160" />

<link type="text/css" rel="stylesheet" href="daypilot/themes/navigator_white.css?v=2019.4.4160" />

<link type="text/css" rel="stylesheet" href="daypilot/themes/calendar_white.css?v=2019.4.4160" />

<!--

<link type="text/css" rel="stylesheet" href="../demo/themes/calendar_transparent.css?v=2019.4.4160" />

<link type="text/css" rel="stylesheet" href="../demo/themes/calendar_green.css?v=2019.4.4160" />

<link type="text/css" rel="stylesheet" href="../demo/themes/calendar_traditional.css?v=2019.4.4160" />

-->



</head>

<body>

<div style="float:left">

<div id="nav"></div>

</div>

<div style="margin-left: 243px;">

<div id="dp"></div>

</div>

<div id="print"></div>

<script type="text/javascript">

// AJAX function to communicate actions to the Server



var HttpClient = function() {

this.get = function(aUrl, aCallback) {

var anHttpRequest = new XMLHttpRequest();

anHttpRequest.onreadystatechange = function() {

if (anHttpRequest.readyState == 4 && anHttpRequest.status == 200)

aCallback(anHttpRequest.responseText);

}

anHttpRequest.open( "GET", aUrl, true );

anHttpRequest.send( null );

}

}

EOD;

$str2 = "

// -------------------------------Currently unused ------------------------------------------------------

// var site='$site' // Host URL

// var url ='$ajax_mes'; // To report the month change

// -----------------------------------------------------------------------------------------------------

";

$str3 = <<<EOD

var nav = new DayPilot.Navigator("nav");

nav.showMonths = 2;

nav.skipMonths = 1;

nav.selectMode = "week";

nav.freeHandSelectionEnabled = true;

nav.showWeekNumbers = true;

nav.visibleRangeChangedHandling = "Disabled"; // It only works in ASP.NET

nav.selectionDay = DayPilot.Date.today();



// nav.select(date_start); // Set the submission date

// nav.selectionDay = date_day;



nav.onTimeRangeSelected = function(args) {

console.log(args);

var start = args.start;

var end = args.end;



dp.startDate = args.start;

dp.update();

};



nav.onBeforeCellRender = function(args) {

if (args.cell.isCurrentMonth) {

args.cell.cssClass = "current-month";

}

};



nav.onVisibleRangeChange = function(args) { // When the months change



var start = args.start;

var end = args.end;

var day = nav.selectionDay;

console.log('Start: '+start+ ' End: '+ end+ ' Day: '+day);

if (start <= nav.selectionDay && nav.selectionDay < end) {

return;

}



// Update request for date change and data reload ----Currently unused -------

// var client = new HttpClient();

// client.get(site+url+'start='+start+'&end='+end, function(response) {

// console.log('Respuesta: '+response);

// location.reload();

// });



var day = nav.selectionDay.getDay();

var target = start.firstDayOfMonth().addDays(day);

nav.select(target);

};



var dp = new DayPilot.Calendar("dp");

EOD;

$str4 = "

nav.locale = '$language'; // Language

dp.locale = '$language'; // Language

";

$str5 = <<<EOD



// view

dp.startDate = nav.selectionDay;

dp.viewType = "Week";

// event creating



/*

dp.onTimeRangeSelected = function (args) {

var name = prompt("New event name:", "Event");

if (!name) return;

var e = new DayPilot.Event({

start: args.start,

end: args.end,

id: DayPilot.guid(),

resource: args.resource,

text: "Event"

});

dp.events.add(e);

dp.clearSelection();

dp.message("Created");

};

*/



dp.eventDeleteHandling = "Disabled";

/*

dp.onEventDelete = function(args) {

alert("deleting: " + args.e.text());

};

*/

// bubble, with async loading

dp.bubble = new DayPilot.Bubble({

onLoad: function(args) {

var ev = args.source;

//alert("event: " + ev);

args.async = true; // notify manually using .loaded()

// simulating slow server-side load

setTimeout(function() {

args.html = "Id: " + ev.id() + "<BR>Resource: " + ev.resource();

args.loaded();

}, 500);

}

});

/*

dp.contextMenu = new DayPilot.Menu({

items: [

{text:"Show event ID", onclick: function() {alert("Event value: " + this.source.value());} },

{text:"Show event text", onclick: function() {alert("Event text: " + this.source.text());} },

{text:"Show event start", onclick: function() {alert("Event start: " + this.source.start().toStringSortable());} },

{text:"Delete", onclick: function() { dp.events.remove(this.source); } }

]});

*/

// event moving

dp.eventMoveHandling = "Diabled";

/*

dp.onEventMoved = function (args) {

dp.message("Moved: " + args.e.text());

};

*/

// event resizing

dp.eventResizeHandling = "Disabled";

/*

dp.onEventResized = function (args) {

dp.message("Resized: " + args.e.text());

};

*/

// event creating

/*

dp.onTimeRangeSelected = function (args) {

var name = prompt("New event name:", "Event");

dp.clearSelection();

if (!name) return;

var e = new DayPilot.Event({

start: args.start,

end: args.end,

id: DayPilot.guid(),

resource: args.resource,

text: name

});

dp.events.add(e);

dp.message("Created");

};

*/



/*

// Right button in range

dp.onTimeRangeRightClick = function(args) {

window.console && console.log(args);

};

*/

/*

dp.onTimeRangeDoubleClicked = function(args) {

alert("DoubleClick: start: " + args.start + " end: " + args.end + " resource: " + args.resource);

};

*/

dp.onEventClick = function(args) { // Run in VIEW popup of the meeting

var meeting = args.e.id();

var url = "calendar_view.php?editid1="+meeting;

var header = '<h2 data-itemtype="view_header" data-itemid="view_header" data-pageid="10">'+'Meeting: '+ meeting+'</h2>' ;

window.popup = Runner.displayPopup({

url: url,

width: 800,

height: 550,

header: header

});

};

dp.eventDoubleClickHandling = "Disabled";

/*

dp.onEventDoubleClick = function(args) {

alert("double click");

};

*/

// dp.showEventStartEnd = true;

dp.scrollLabelsVisible = true;



/*

// Right button in range

dp.contextMenuSelection = new DayPilot.Menu({

items: [

{

'text': 'Create new event (JavaScript)', 'onclick': function () {

dp.events.add(new DayPilot.Event({

start: this.source.start,

end: this.source.end,

text: "New event",

resource: this.source.resource

}));

}

},

{'text': '-'},

{

'text': 'Show selection details', 'onclick': function () {

alert('Start: ' + this.source.start + '\nEnd: ' + this.source.end + '\nResource id: ' + this.source.resource);

}

},

{

'text': 'Clean selection', 'onclick': function () {

dp.clearSelection();

}

}]

});

*/

// dp.timeRangeSelectingStartEndEnabled = true;

EOD;

$str6 = '';

while ($row = db_fetch_array($resql)) { // Loop of records processing

$str6.=

'

var e = new DayPilot.Event({

start: new DayPilot.Date("'.substr($row[start_date],0,10).'T'.substr($row[start_date],-8).'"),

end: new DayPilot.Date("'.substr($row[end_date],0,10).'T'.substr($row[end_date],-8).'"),

id: "'.$row[id].'",

text: "'.addslashes($row[name]).'",

resource: "'.addslashes($row[resource]).'",

barColor: "'.$row[color].'"

});

dp.events.add(e);

' ;

};

$str6 .= <<<EOD



nav.init();

dp.init();

</script>

EOD;

echo $str1.$str2.$str3.$str4.$str5.$str6;

}; // end of record control

?>


For questions or whatever problems arise, please indicate this through my email fernandohumanes@gmail.com.
In my blog you can download the example files

fhumanes author 1/9/2020

Hi:
I have corrected the example so that in our meeting the proposed date and time of start and end, have a time of difference.
The logic of the example is not very worked because my goal was to see how easy it is to include Daypilot libraries in PHPRunner.
Regards,
fernando

fhumanes author 1/13/2020

Hi:
As I have indicated, the example aims to show how Daypilot libraries are integrated.
I have not coded the validation dates and therefore there are no logical controls of the data that is being interfered. This is done as standard with PHPRunner solutions.
I insist, if you destroy the test data, please indicate me to restore them.
I also insist that I have used a very simple way of representing and displaying meetings and that the product has many more forms that you can see on the Daypilot website.
Greetings,
fernando

fhumanes author 5/5/2020

Hello:
I have updated this project by changing the Daypilot javascript library to the FullCalendar library, which is open source, and there is no need to license anything.
The integration is very good (I recommend it).
The image of the new calendar is this:


As in all the examples that I publish, in my portal are the sources of the example so that you can install and customize it on your computers.
Cheers,
Fernando