Gregory's Blog

Kendo scrollview

I have been using the scroll view on my home site at gregoryalexander.com quite a bit, and wanted to pass along a few tips.

If you want to change the button size on the scroll view, use the following css. The default font-size is around 2em, to make the right and left arrows bigger, use anywhere from 6-8em, and 1em to make the arrows a bit smaller.

view plain about
1#nameOfScrollViewDiv .k-scrollview-next span, .k-scrollview-prev span {
2    font-size: 8em;
3}

To use the scrollview to display a lot of text, I used the following approach.

First, we need to use data-role='page' and create a 'white-space:normal' style for every element in order to allow for the text to wrap properly instead of going off of the scrollview page:

view plain about
1<div id="developmentScrollView" class="blueGradient">
2    <!-- This is used for every page -->
3    <div class="getConnected" data-role="page" style="white-space:normal;">
4</div>

To constrain the text and allow the arrows to be seen visibility on the right and left, I created a css class for the div that contains the actual scrollview, and wrapper classes that constrain the text information in the proper spot.

The class for the scrollview div (the outer class in this case):

view plain about
1/* Scroll view outer containers within the content blocks. */
2#developmentScrollView {
3    /* Text color */
4    color: rgba(255, 255, 255, 0.9);
5    height: var(--scrollViewHeight);
6    width: var(--scrollViewWidth); /* Don't use dynamic css vars set when the page loads. It screws stuff up. */
7    margin: auto;    
8    z-index: 2; /* This needs to be higher than the nav blocks */
9}

And the three wrapper classes: the first class (firstScrollviewWrapper) is used on the first slide, and the second class (scrollviewWrapper) controls all of the slides after the first and last slide, and the last class (lastScrollviewWrapper) is used for the very last slide. These are used to keep the text separated from the arrows in order to make the arrows more visible.

view plain about
1.firstScrollviewWrapper {
2    position: relative;
3    display: table;
4    left: 0%; /* The 2nd and x slides there after start to the right of the left arrow. */
5    right: 10%;
6    margin: auto;
7    width: 80%; /* the width of the scroll view container. */
8    text-align: left;
9    font-family: var(--scrollViewFont);
10    font-size: var(--scrollViewFontSize);
11}
12
13.scrollviewWrapper {
14    position: relative;
15    display: table;
16    left: 0%; /* The 2nd and x slides there after start to the right of the left arrow. */
17    right: 10%;
18    margin: auto;
19    width: 80%; /* the width of the scroll view container. */
20    text-align: left;
21    font-family: var(--scrollViewFont);
22    font-size: var(--scrollViewFontSize);
23}
24
25.lastScrollviewWrapper {
26    position: relative;
27    display: table;
28    left: 0%; /* The 2nd and x slides there after start to the right of the left arrow. */
29    right: 0%; /* The last slide does not have a right arrow that we need to leave room for. */
30    margin: auto;
31    width: 80%; /* the width of the scroll view container. */
32    text-align: left;
33    font-family: var(--scrollViewFont);
34    font-size: var(--scrollViewFontSize);
35}

A demonstration of my approach can be seen on my www.gregoryalexander.com/index.cfm home page.

Note: I am using css variables for the font family and font size.

This entry was posted on April 16, 2019 at 7:57 PM and has received 71 views.

There are currently 0 comments.

How to add additional descriptive elements to an element with 'data-'

While coding logic for a Kendo tooltip, I had to send both the anchor's title and other information that the Kendo tooltip would display. I wanted to display the location where the image was taken, and a description of the image like this:

"Grand Prismatic Spring, Yellowstone National Park.

The vibrant colors of this spring is best captured from over-head. Wouldn't it be cool to fly a drone over this and take a few pictures?"

I wanted both elements to be separated with a horizontal rule, and I needed to isolate the location and the description. However, the anchor tag only has a 'title' and an alt tag to store this information.

If you want to store additional information in an element does not support, you can easily use the 'data-' + name prefix like so:

view plain about
1<span title="Grand Prismatic Spring, Yellowstone National Park." data-desc="The vibrant colors of this spring is best captured from over-head. Wouldn't it be cool to fly a drone over this and take a few pictures?">

To get the information that the data element contains, in this case, a Kendo template, use the data- prefix. You can name the prefix anything you want, and within the javascript template, don't need to specify the actual data tag- just leave it blank but name the variable after the 'data-' element (see '#=target.data('desc')#: below).

view plain about
1<!--- Kendo tooltip template--->
2<InvalidTag id="aboutTemplate" type="text/x-kendo-template">
3    <div class="template-wrapper">
4        <h3> #=target.data('title')# </h3>
5        <p>#=target.data('desc')#</p>
6    </div>
7</script>

This is a neat way to store additional data into HTML elements, such as a span tag, or any other element as well.

This entry was posted on March 29, 2019 at 2:16 PM and has received 76 views.

There are currently 0 comments.

Kendo Server Side Validation

This post describes how to use Kendo's validator for server side validation. There are very few posts showing how to use Kendo's validator with server side validation (none of them are really clear), it took me a bit of time to figure it out, and want to share my approach and will provide extensive comments.

One of the reasons that there are very few posts concerning server side validation with the Kendo validator is that it is not really built to do this. Unlike the majority of the other Kendo widgets which allow for customization, the validator was meant for simple validation. The built in validation is quite useful for simple client side validation, but it is not an extensive validation library and anytime that you need to extend it you will find yourself wanting more. I felt like I was trying to hammer a square peg into a circle while coding this. However, since one of the main goals of this blog is to share how ColdFusion can use the Kendo UI, I felt the need to dig into the kendo validator.

I have a captcha form on this blog that is used to verify that the user is an actual user, and it encrypts a token and passes it off to the server side for validation. You can see this in action by making a comment on this post below.

The meat and potatoes of this function, like most of the other Kendo widgets, lies in the Javascript. This script is heavily commented. Click the more button below to inspect the script.

This entry was posted on March 1, 2019 at 5:34 PM and has received 120 views.

There are currently 0 comments.

Responsive Web Design

I am spending quite a bit of time making the new blog responsive. My goal is to make the mobile site fully functional and to make it look as nice as the application on the web. I ran into some major hurdles.

For example, the original code formatter, developed by Jason Delmore, expanded beyond the mobile device size. I re-wrote quite a bit of the logic in the formatter, but I did not want to re-write the core logic that provides the formatted code and lines. I had wanted to re-write every inner div and span that used position: absolute underneath the constraining parent div that had position, relative, but gave up as there were so many div's and spans. There is so much logic in the formatter that I gave up thinking about making the code responsive and instead I constrained the content like so:

CSS:

view plain about
1/* The constrainer table will constrain one or many different div's and spans to a certain size. It is handy to use when you are trying to contain the size of elements created by an older libary that does not use responsive design. */
2#constrainerTable {
3    /* The parent element (this table) should be positioned relatively. */
4    position: relative;
5    /* Use the root width var */
6    width: var(--contentWidth);
7    /* Now that the parent element has a width setting, make sure that the width does not ever exceed this */
8    max-width: 100%;
9}    
10        
11/* Helper function to the constrainerTable to break the text when it exceeds the table dimensions */
12#constrainerTable .constrainContent {
13    max-width: 100%
14}
15th {
16    max-width: var(--contentWidth);
17}
18td {
19    word-break: break-word;
20    min-width: 50px;
21}

And the HTML:

view plain about
1<!-- Post content -->
2<!--- Note: Delmore's code formatter is not mobile friendly and it does not use responsive design. This table will constrain the content to a certain variable size. --->
3<table id="constrainerTable" class="constrainContent">
4    <tr>
5        <td>
6            <!--- Blog post. --->
7            #application.blog.renderEntry(body,false,enclosure)#                
8        </td>
9    </tr>
10</table>

Fixed background image settings for mobile devices: To use a fixed background, the main arguments here are display: block, position: fixed, z-index:-10

view plain about
1body:before {
2    content: "";
3    display: block;
4    position: fixed;
5    left: 0;
6    top: 0;
7    width: 100%;
8    height: 100%;
9    z-index: -10;
10    background: url(<cfoutput>#blogBackgroundImage#</cfoutput>) no-repeat center center;
11    -webkit-background-size: cover;
12    -moz-background-size: cover;
13    -o-background-size: cover;
14    background-size: cover;
15}

Opacity settings for mobile devices: The web application has a nice opacity effect where the theme's background image bleeds through into the interface. To accomplish the same effect for iOs devices, I used: opacity: .92 and visibility: true.

view plain about
1/* Opacity for iOs */
2opacity: 0.<cfoutput>#siteOpacity#</cfoutput>;
3visibility: visible;

This entry was posted on February 12, 2019 at 4:01 PM and has received 92 views.

There are currently 0 comments.

Kendo Responsive Panel

While working on the mobile site, I had a few challenges with the Kendo responsive panel that I solved with the blog today, and wanted to make a post about it as I could not find any other solution on the web. I ran into someone posting the same scrolling question as I was looking to solve on stack overflow, but could not find anything else on the web.

The responsive panel is used to provide a slide-out menu on mobile devices when you click on what is commonly known as a 'hamburger. The panel is used in responsive web design and is triggered when the device reaches a certain minimum screen width. Here is the code that I developed for this blog:

view plain about
1<nav id="sidebarPanel" class="k-content">
2    <!---Suppply the sideBarType argument before loading the side bar--->
3    <cfset sideBarType = "panel">
4    <cfinclude template="includes/layers/sidebar.cfm">
5</nav><!---<nav id="sidebar">--->
6            
7<!--- This script must be placed underneath the layer that is being used in order to effectively work as a flyout menu.--->
8Javascript
9    $("#sidebarPanel").kendoResponsivePanel({
10        breakpoint: 1280,
11        orientation: "left",
12        autoClose: true
13        })
14        .on("click", "a", function(e) {
15            $("#sidebarPanel").kendoResponsivePanel("close");
16    });

There were several challenges that I ran into when developing this.

First, I tried to use the same div element that I use on the right side of the page to hold the various widgets, such as the calendar, subscribe, recent posts, etc. However, I noticed that if I tried to use the same div for the responsive menu, I could no longer apply certain css properties to the panel, and it was stuck at the top of the page.

To solve this, I used a different div at the end of the application to serve as the responsive panel, duplicated the logic from the right column, and put it into the new panel at the end of the page. I also created a script to show the new responsive panel when the screen size hit the breakpoint setting (1280 pixels), and hid the original div that is on the right column. Here is the relevant portions of the code:

view plain about
1// Handle the sidebar and the sideBarPanels
2    if (windowWidth <= 1280){
3        // Hide the sidepanel (the responsive panel will takeover here).
4        $( "#sidebar" ).hide();
5        // Show the responsive panel
6        $( "#sidebarPanel" ).show();
7    } else {
8        // Show the sidebar, and hide the responsive panel
9        $( "#sidebar" ).show();
10        $( "#sidebarPanel" ).hide();
11    }

Second, the hamburger showed up, but it closed as soon as I tried to open it. I found the following solution while searching the web:

view plain about
1// Important note: this is a workaround with a google chrome bug and mobile devices.
2// This prevents the following error: "Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive."
3// See https://github.com/telerik/kendo-ui-core/issues/3556
4$(".k-rpanel-toggle").on("touchend", function(e) {
5     e.preventDefault();
6});

Third, I ran into problems where to put the resonsivePanel initiation script. I found out that it must be at underneath the actual element that it will be placed into.

It now works, however, there is a big problem. I could not scroll down the responsive panel when it was triggered. It just stayed in a fixed position and only showed the top part of the page. I looked everywhere in the Kendo site, and then on the internet, looking for some arcane argument that I could use, such as scrollable: true, but couldn't find any. I then looked at the similar jQuery UI menu, and inspected Telerik's production page which has a responsive panel and found that they both used the css declaration: position: absolute;

view plain about
1position: absolute;

Fourth. Ok, that fixed that problem, but now the div layer disappeared at the bottom of the page. I tried setting height to 100%, but that failed too. So I looked at both jQuery and Kendo's panels again, and noticed that they also used: height: auto;

view plain about
1height: auto;
Also, use the autoclose argument to be false on the responsive panel widget, otherwise you won't be able to able to keep the layer open when scrolling past the bottom of the first page. That worked! The panel can be scrolled now.

The final working code is pasted below:

CSS:

view plain about
1/* The side bar panel is essentially a duplicate of the sidebar div, however, it is a responsive panel used when the screen size gets small. */
2#sidebarPanel {
3/* We are going to eliminate this sidebar for larger devices, and activate it when the screen size gets to a certain size. */
4display: none;
5/* Note: the panel will not scroll with the blog content unless there is a css position: absolute. */
6position: absolute;
7margin: 0;
8/* Apply more padding to the right to keep things uniform. */
9padding: 20px 40px 20px 20px;
10width: 45%;
11/* Note: if you don't set 'height: auto', the panel will not be displayed below the bottom of the page. */
12height: auto;
13vertical-align: top;
14overflow: visible;
15border-right: thin;
16        
17/* Put a drop shadow on the panel when it is expanded. */
18#sidebarPanel.k-rpanel-expanded {
19 box-shadow: 0 0 10px rgba(0,0,0,.3);
20 }
CFML:
view plain about
1<!---This is the sidebar responsive navigation panel that is triggered when the screen gets to a certain size. It is a duplicated of the sidebar div above, however, I can't properly style the sidebar the way that I want to within the blog content, so it is duplicated without the styles here.--->
2                        
3<!--- Side bar is to the right of the main panel container. It is also used as a responsive panel below when the screen size is small. --->
4<nav id="sidebarPanel" class="k-content">
5<!---Suppply the sideBarType argument before loading the side bar--->
6<cfset sideBarType = "panel">
7<cfinclude template="includes/layers/sidebar.cfm">
8</nav><!---<nav id="sidebar">--->
Javascript:
view plain about
1<!--- This script must be placed underneath the layer that is being used in order to effectively work as a flyout menu.--->
2    $("#sidebarPanel").kendoResponsivePanel({
3        breakpoint: 1280,
4        orientation: "left",
5        autoClose: false // set this to false if you want the layer to stay up when you want to sroll down.
6        })
7        .on("click", "a", function(e) {
8            $("#sidebarPanel").kendoResponsivePanel("close");
9    });
10
11// Important note: this is a workaround with a google chrome bug and mobile devices.
12// This prevents the following error: "Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive."
13// See https://github.com/telerik/kendo-ui-core/issues/3556
14    $(".k-rpanel-toggle").on("touchend", function(e) {
15        e.preventDefault();
16    });

This entry was posted on February 9, 2019 at 10:38 PM and has received 109 views.

There are currently 0 comments.

Done with the draft version of Gregory's blog

It is the first day of the New Year, and I am happy to say that I am done incorporating the features that I wanted into the new desk-top oriented blog. After working with Raymond's back-end code, I am quite impressed with the logic that it contains and how he anticipated functional logic, even though the logic was not used within the original BlogCfc UI. For example, the getEntries method allows passing in a string of categories when you are using the search interface, even though the original blogCfc only allowed one category to be selected at a time. With the new interface that I have programmed, I designed the search to use one or more categories with a Kendo multi-select drop down box. I had thought that I would need to revise Raymond's original getEntries method to allow one or more categories, but found out that I can pass more than one category value as a list. This is just how I would have designed this if I had the time, but Raymond already designed his function to be used for multiple arguments, even though the UI did not use that logic in the original interface. I also looked for various functions that I had thought to write, and I found them in Raymond's code-base, often with the same name that I would have used as if I had wrote them myself. I found Raymond's back-end logic both powerful and intuitive. It was a pleasure to use Raymond's back-end logic, and I am glad that I made the choice to use BlogCfc as the back-end when re-writing this application.

I intend to work on getting my own personal site up, developing the responsive mobile blog, and then go through more testing before launching this new blog software. This is a part-time weekend project. I have a lot of other stuff vying for my attention, as well as being married, having kids, and a working a full time job; this may take several months.

Gregory

This entry was posted on January 1, 2019 at 11:04 PM and has received 96 views.

There are currently 0 comments.

New HTML 5 Media Player

Instead of the original flash plug-in, I have incorporated a new Kendo HTML 5 media player.

This entry was posted on January 1, 2019 at 12:50 AM and has received 87 views.

There are currently 0 comments. Download attachment.

Picture test

This is a picture test... test.

This entry was posted on December 31, 2018 at 1:55 PM and has received 82 views.

There are currently 0 comments. Download attachment.

Coldfish Formatter Test

I probably will rewrite the code formatting to use another library, such as prism.js, as suggested by Ray Camden. For now however, I have re-purposed the original Coldfish library that was used in the original blogCfc.

view plain about
1<!--- There are two types of routing titles. The original design used an routing title that was used to populate a contract and this title was not the official title, but something more generic that was easily identifiable on a written contract. The other title is the official title that is coming from the workday database We will use the original routing title if the user was assigned a routing title that is found in the routing database, otherwise, we will use the official workday title. --->
2<cffunction name="getTitleByEmail" access="remote" returntype="struct" hint="Determines the approver title. This will be either the routing title that was used in previous contracts, or the official title found in workday. We need to return multiple values, so this returns a one dimension array instead of a string.">
3<cfargument name="email" type="string" required="yes" hint="Supply the email.">
4
5<cfparam name="title" default="">
6
7<!---Format the email--->
8<cfinvoke component="#WorkdayUsersObj#" method="formatUwEmail" returnvariable="uwEmail">
9 <cfinvokeargument name="email" value="#arguments.email#">
10 </cfinvoke>
11
12<!--- Query the Approval database to see if the title exists. --->
13<cfquery name="approvalTitle" datasource="Contracts">
14 SELECT TOP (1)
15 ApproverTitle
16 FROM dbo.Approval
17 WHERE (Email = <cfqueryparam value="#uwEmail#" cfsqltype="cf_sql_varchar">)
18</cfquery>
19<!---Set the ApproverTitle--->
20<cfset ApproverTitle = approvalTitle.ApproverTitle>
21 <!---Get the workday job title. --->
22 <cfinvoke component="#WorkdayUsersObj#" method="getEmployeeJobTitle" returnvariable="workdayTitle">
23 <cfinvokeargument name="email" value="#email#">
24 </cfinvoke>
25
26<!---Build the shorthand struct --->
27<cfset titleStruct = {workdayTitle = #workdayTitle#, ApproverTitle = #ApproverTitle#}>
28
29<cfreturn titleStruct>
30
31</cffunction>

This entry was posted on December 15, 2018 at 7:09 PM and has received 99 views.

There are currently 0 comments.

Removed style tags

I'm removing most of the style tags that were coded in the original blogCfc interface. there are hundreds of custom styles applied to UI elements that are conflicting with the Kendo .css themes. I also need to complete a complete re-write of Jason Delmore's logic to format the text within the &l;tcode> blocks. Additionally, I need to apply the 'k-content' class to all links.

This entry was posted on December 15, 2018 at 1:32 AM and has received 96 views.

There are currently 0 comments.




Your input and contributions are welcomed!

If you have an idea, BlogCfc based code, or a theme that you have built using this site that you want to share, please contribute by making a post here or share it by contacting us! This community can only thrive if we continue to work together.

Images and Photography:

Gregory Alexander either owns the copyright, or has the rights to use, all images and photographs on the site. If an image is not part of the "Gregory's Blog" open sourced distribution package, and instead is part of a personal blog post or a comment, please contact us and the author of the post or comment to obtain permission if you would like to use a personal image or photograph found on this site.

Credits:

Portions of Gregory's Blog are powered on the server side by BlogCfc, an open source blog developed by Raymond Camden. Revitalizing BlogCfc was a part of my orginal inspiration that prompted me to design this site. Some of the major open source contributers to BlogCfc include:

  1. Peter Farrell: the author of 'Lyla Captcha' that is used on this blog.
  2. Pete Freitag: the author of the 'ColdFish' code formatter that is also used on this blog.

Version:

Gregory's Blog Version 1.15 July 25th, 2019.