{"id":4495,"date":"2020-04-27T06:29:02","date_gmt":"2020-04-27T14:29:02","guid":{"rendered":"https:\/\/officedevblogs.wpengine.com\/?p=4495"},"modified":"2020-04-27T06:29:02","modified_gmt":"2020-04-27T14:29:02","slug":"a-lap-around-microsoft-graph-toolkit-day-5-customizing-components-using-templates","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/a-lap-around-microsoft-graph-toolkit-day-5-customizing-components-using-templates\/","title":{"rendered":"A Lap around Microsoft Graph Toolkit Day 5 \u2013 Customizing Components using Templates"},"content":{"rendered":"<p><strong>Author<\/strong>: Fabio Franzini, Microsoft Office Development MVP.<\/p>\n<p>Welcome to Day 5 of the <a href=\"http:\/\/aka.ms\/mgtlap\">Microsoft Graph Toolkit blog series<\/a>!<\/p>\n<p>As you saw in our previous blog posts, Microsoft Graph Toolkit is designed to provide a set of ready-to-use web components for interfacing with the Microsoft Graph API. You\u2019ve also seen how to customize the components using attributes, properties, or CSS to change their look and feel.<\/p>\n<p>In this post we will explore another extremely useful feature that allows us to customize the UI of individual toolkit components &#8211; templates.<\/p>\n<p>All Microsoft Graph Toolkit components support templates by simply adding a <strong>&lt;template&gt;<\/strong> element inside a component.<\/p>\n<p>Let&#8217;s take the <strong>mgt-agenda<\/strong> component as an example and use a template to change the appearance and functionality of this control.<\/p>\n<p>This is default rendering of the agenda control:<\/p>\n<p><img decoding=\"async\" class=\"alignleft wp-image-4496\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/04\/Image-1-2.png\" alt=\"mgt-agenda component default view\" width=\"450\" height=\"464\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/04\/Image-1-2.png 614w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/04\/Image-1-2-291x300.png 291w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/04\/Image-1-2-24x24.png 24w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/04\/Image-1-2-48x48.png 48w\" sizes=\"(max-width: 450px) 100vw, 450px\" \/><\/p>\n<p>And we want to change the template to show more details like:<\/p>\n<ul>\n<li>Display of event dates and time;<\/li>\n<li>Clickable title to directly access the calendar via web link;<\/li>\n<li>Show the participants;<\/li>\n<li>Show the description of the event.<\/li>\n<\/ul>\n<p>This is the result after using custom templates, custom CSS, and JavaScript:<\/p>\n<p><img decoding=\"async\" class=\"alignleft wp-image-4497\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/04\/Image-2-1.png\" alt=\"mgt-agenda modified to show based on requirements\" width=\"450\" height=\"479\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/04\/Image-2-1.png 598w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/04\/Image-2-1-282x300.png 282w\" sizes=\"(max-width: 450px) 100vw, 450px\" \/><\/p>\n<h3>Implementation<\/h3>\n<p>Each component can have multiple modifiable parts. You can use <strong>data-type<\/strong> to specify which of the many templates to modify.<\/p>\n<p>In this case, we customized 3 templates: <strong>event view<\/strong>, <strong>no-data view,<\/strong> and <strong>loading view<\/strong> and we will focus on modifying <strong>event <\/strong>template.<\/p>\n<pre class=\"lang: decode:true\">&lt;mgt-agenda&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;template data-type=\"event\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;!--\n\u00a0\u00a0\u00a0\u00a0&lt;\/template&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;template data-type=\"no-data\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;p class=\"noData\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0There are no events found!\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/p&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;\/template&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;template data-type=\"loading\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;p class=\"loading\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Loading...\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/p&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;\/template&gt;\n&lt;\/mgt-agenda&gt;<\/pre>\n<p>To show a customized date and time using the <strong>event<\/strong> template, you need additional functions that can be called directly from the template. To do this you can take advantage of the <strong>templateContext<\/strong> JavaScript property present in each Toolkit component, that allows you to extend the context of the template with your variables, functions, and events.<\/p>\n<pre class=\"lang: decode:true\">const months = [\"JAN\", \"FEB\", \"MAR\", \"APR\", \"MAY\", \"JUN\", \"JUL\", \"AUG\", \"SEP\", \"OCT\", \"NOV\", \"DEC\"];\ndocument.querySelector('mgt-agenda').templateContext = {\n\u00a0\u00a0\u00a0\u00a0openWebLink: (e, context, root) =&gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0window.open(context.event.webLink, '_blank');\n\u00a0\u00a0\u00a0\u00a0},\n\u00a0\u00a0\u00a0\u00a0getDate: (dateString) =&gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0let dateObject = new Date(dateString);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return dateObject.setHours(0, 0, 0, 0);\n\u00a0\u00a0\u00a0\u00a0},\n\u00a0\u00a0\u00a0\u00a0getTime: (dateString) =&gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0let dateObject = new Date(dateString);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return dateObject.getHours().toString().padEnd(2, '0')\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0+ ':' + dateObject.getMinutes().toString().padEnd(2, '0');\n\u00a0\u00a0\u00a0\u00a0},\n\u00a0\u00a0\u00a0\u00a0formatDate: (date) =&gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0let dateObject = new Date(date);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return dateObject.getDate()\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0+ \"\/\" + months[dateObject.getMonth()]\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0+ \"\/\" + dateObject.getFullYear();\n\u00a0\u00a0\u00a0\u00a0},\n\u00a0\u00a0\u00a0\u00a0getTextFromHTML(htmlString) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var doc = (new DOMParser()).parseFromString(htmlString, \"text\/html\");\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return doc.body.innerText;\n\u00a0\u00a0\u00a0\u00a0}\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>Now you have a series of functions that format dates (<strong>getDate<\/strong>, <strong>getTime<\/strong>, <strong>formatDate<\/strong>), a function to open the link to access the web calendar (<strong>openWebLink<\/strong>), and a function to extract the text from an HTML string (<strong>getTextFromHTML<\/strong>).<\/p>\n<p>To refer to the data to be displayed in the template, you can use a data-binding expression using <strong>double curly brackets <\/strong>like <strong>{{\u00a0event.subject\u00a0}}<\/strong> b. You can also use the <strong>data-props<\/strong> attribute. It allows you to add an event listener or set a property value directly in your templates. \u00a0You can add an event handler by using the \u201c<strong>@<\/strong>eventName\u201d syntax like <strong>@click:\u00a0openWebLink.<\/strong><\/p>\n<pre class=\"lang: decode:true\">&lt;template data-type=\"event\"&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;div class=\"event\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0...\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div class=\"event-title\" data-props=\"{{@click: openWebLink}}\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{{ event.subject }} @ {{event.location.displayName}}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0...\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;div class=\"event-description\" data-props=\"{{innerHTML: event.body.content}}\" \/&gt;\u00a0\u00a0\u00a0\u00a0 ...\n\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n&lt;\/template&gt;<\/pre>\n<p>In this example the first <strong>div<\/strong> will show two properties of the event: <strong>subject<\/strong> and <strong>displayName<\/strong> and a click event is hooked to our <strong>openWebLink<\/strong> function previously defined. The second div will show the body property of the event.<\/p>\n<p>You can also use <strong>data-if<\/strong> and <strong>data-else<\/strong> attributes to be able to pilot the rendering with conditional expressions:<\/p>\n<pre class=\"lang: decode:true\">&lt;template data-type=\"event\"&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;div class=\"event\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0...\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div data-if=\"getDate(event.start.dateTime) == getDate(event.end.dateTime)\"\n\u00a0\u00a0\u00a0\u00a0\u00a0 class=\"event-subTitle\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{{formatDate(event.start.dateTime)}}\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0from {{getTime(event.start.dateTime)}}\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0to {{getTime(event.end.dateTime)}}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div data-else class=\"event-subTitle\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{{formatDate(event.start.dateTime)}} ({{getTime(event.start.dateTime)}})\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{{formatDate(event.end.dateTime)}} ({{getTime(event.end.dateTime)}})\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0...\n\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n&lt;\/template&gt;<\/pre>\n<p>In this part of the template you can see how the <strong>data-if<\/strong> attribute is used with an expression that uses one of the functions defined in the <strong>templateContext<\/strong>: getDate. The expression checks to see if the start date is the same as the end date.\u00a0 If it is, it displays the content of the div.\u00a0 Otherwise it displays the div containing the <strong>data-else<\/strong> attribute. In both cases, other previously defined helpers are used to format the data to display.<\/p>\n<p>The last implemented part of the template is the one related to the visualization of the attendees:<\/p>\n<pre class=\"lang: decode:true\">&lt;template data-type=\"event\"&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;div class=\"event\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0...\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div class=\"event-attendees\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;mgt-person data-for=\"attendee in event.attendees\"\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0person-query=\"{{ attendee.emailAddress.name }}\"\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0person-card=\"hover\" \/&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0...\n\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n&lt;\/template&gt;<\/pre>\n<p>Here you can use one of the toolkit controls, mgt-person, to view the details of the users. The <strong>data-for<\/strong> attribute allows you to cycle through data collections, such as users, and then display lists of data in the UI. In the expression there is a definition of a variable, attendee, which represents the current object during the cycle. It is possible to use the <strong>$index<\/strong> variable in expressions to refer to the element index or the <strong>$parent<\/strong> variable to access the context of the parent data, even if in this example they are not used.<\/p>\n<h3>Final Component using Templates<\/h3>\n<p>When we put together the snippets described above using the Playground or your web project, the result is this:<\/p>\n<p><strong>HTML<\/strong><\/p>\n<pre class=\"lang: decode:true\">&lt;mgt-agenda&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;template data-type=\"event\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div class=\"event\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div class=\"event-subTitle\"\u00a0\n\u00a0\u00a0 data-if=\"getDate(event.start.dateTime) == getDate(event.end.dateTime)\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{{formatDate(event.start.dateTime)}} from {{getTime(event.start.dateTime)}} to\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{{getTime(event.end.dateTime)}}&lt;\/div&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div class=\"event-subTitle\" data-else&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{{formatDate(event.start.dateTime)}} ({{getTime(event.start.dateTime)}}) -\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{{formatDate(event.end.dateTime)}} ({{getTime(event.end.dateTime)}})\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div class=\"event-title\" data-props=\"{{@click: openWebLink}}\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{{ event.subject }} @ {{event.location.displayName}}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div class=\"event-attendees\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;mgt-person data-for=\"attendee in event.attendees\"\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0 person-query=\"{{ attendee.emailAddress.name }}\"\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0 person-card=\"hover\" \/&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div class=\"event-description\" data-props=\"{{innerHTML: event.body.content}}\" \/&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;\/template&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;template data-type=\"no-data\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;p class=\"noData\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0There are no events found!\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/p&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;\/template&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;template data-type=\"loading\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;p class=\"loading\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Loading...\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/p&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;\/template&gt;\n&lt;\/mgt-agenda&gt;\n<\/pre>\n<p><strong>JavaScript<\/strong><\/p>\n<pre class=\"lang: decode:true\">const months = [\"JAN\", \"FEB\", \"MAR\", \"APR\", \"MAY\", \"JUN\", \"JUL\", \"AUG\", \"SEP\", \"OCT\", \"NOV\", \"DEC\"];\ndocument.querySelector('mgt-agenda').templateContext = {\n\u00a0\u00a0\u00a0\u00a0openWebLink: (e, context, root) =&gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0window.open(context.event.webLink, '_blank');\n\u00a0\u00a0\u00a0\u00a0},\n\u00a0\u00a0\u00a0\u00a0getDate: (dateString) =&gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0let dateObject = new Date(dateString);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return dateObject.setHours(0, 0, 0, 0);\n\u00a0\u00a0\u00a0\u00a0},\n\u00a0\u00a0\u00a0\u00a0getTime: (dateString) =&gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0let dateObject = new Date(dateString);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return dateObject.getHours().toString().padEnd(2, '0')\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0+ ':' + dateObject.getMinutes().toString().padEnd(2, '0');\n\u00a0\u00a0\u00a0\u00a0},\n\u00a0\u00a0\u00a0\u00a0formatDate: (date) =&gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0let dateObject = new Date(date);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return dateObject.getDate()\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0+ \"\/\" + months[dateObject.getMonth()]\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0+ \"\/\" + dateObject.getFullYear();\n\u00a0\u00a0\u00a0\u00a0}}<\/pre>\n<p><strong>CSS<\/strong><\/p>\n<pre class=\"lang: decode:true \">.event {\n\u00a0\u00a0\u00a0\u00a0box-shadow: 0 3.2px 7.2px 0 rgba(0,0,0,.132), 0 0.6px 1.8px 0 rgba(0,0,0,.108);\n\u00a0\u00a0\u00a0\u00a0margin: 10px;\n}\n.event-title {\n\u00a0\u00a0\u00a0\u00a0cursor: pointer;\n\u00a0\u00a0\u00a0\u00a0font-size: var(--event-subject-font-size, 19px);\n}\n.event, .event-title, .event-subTitle, .event-attendees, .event-description, .noData, .loading {\n\u00a0\u00a0\u00a0\u00a0padding: 5px;\n}\u00a0\n.noData, .loading {\n\u00a0\u00a0\u00a0\u00a0font-family:\u00a0\u00a0\"Segoe UI\", \"Segoe UI Web (West European)\", \"Segoe UI\", -apple-system, BlinkMacSystemFont, Roboto, \"Helvetica Neue\", sans-serif;\n}\n<\/pre>\n<h3>Conclusion<\/h3>\n<p>We\u2019ve introduced you to the power of customizable templates.\u00a0 We\u2019ve shown you how to mix HTML elements with other Toolkit controls or with external web components, and how easy it is to adapt them to your needs.\u00a0 Now you can explore the infinite customization possibilities of toolkit components without having to re-implement the controls.<\/p>\n<p>Stay tuned with the <a href=\"https:\/\/aka.ms\/mgtlap\">series<\/a> and share our articles using #MSGraphToolkitLap. Next up: <a href=\"https:\/\/developer.microsoft.com\/en-us\/graph\/blogs\/a-lap-around-microsoft-graph-toolkit-day-6-the-power-of-mgt-get\/\">The power of mgt-get<\/a>!<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Day 5 of A Lap around Microsoft Graph Toolkit, we will explore an extremely useful feature, templates, that allows us to customize the UI of individual toolkit components.<\/p>\n","protected":false},"author":69077,"featured_media":25159,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3],"tags":[137,34],"class_list":["post-4495","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft-graph","tag-javascript","tag-microsoft-graph-toolkit"],"acf":[],"blog_post_summary":"<p>Day 5 of A Lap around Microsoft Graph Toolkit, we will explore an extremely useful feature, templates, that allows us to customize the UI of individual toolkit components.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/4495","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/users\/69077"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/comments?post=4495"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/4495\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media\/25159"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media?parent=4495"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/categories?post=4495"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/tags?post=4495"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}