Use LinkedIn Hopscotch with hidden elements
My previous posting shows how to use Hopscotch on asp.net Masterpages. While creating a new tour I’ve faced one thing: Sometimes the referenced element is currently hidden on the page, e.g. when using the collapse-option in Twitters Bootstrap Framework. Using Hopscotch it’s simple to show the element and then reference the tooltip to it. So current tip is regardless of the programming language (asp.net, PHP, HTML, etc.) and it’s a very simple one.
Use LinkedIn HopScotch on ASPX Masterpages
I fully agree with this quote from StartupVitamins: A user interface is like a joke. If you have to explain it, it’s not that good!
But it might happen that you need to have some kind of complexity which might be overwhelming for some users. So it’s of course a good idea to give as many helpful information as possible. But who reads manuals? …. Exactly. So nowadays it is (with good reason) expected by the users to have some kind of interactive guidelines. Of course there are several solutions, free and paid.
Hopscotch is a children’s game that can be played with several players or alone, but in currently article I’ll share some information about the Hopscotch framework created by the developers of business network LinkedIn. This Hopscotch helps you creating product tours on your website. So let’s see how to add a multipage tour to your asp.net website using asp.net Masterpages. Note: All helpful scripts are added at the end of this article. Continue reading…
Create HTML5 Charts using Chartist JS and asp.net
After RGraph has changed their license type and I also saw an article about Chartist JS in Smashing Magazine I checked what needs to be done to move. Chartist is hosted on Github so it’s open source and also free according to their current license.
I’ve already written a blog post how to Create HTML5 Charts using ASP.net and RGraph so I used this code and transferred it to Chartist JS. And well, it’s just 2 minutes work.
Of course you have to reference the library, so add the script and the css to your page:
<link rel="stylesheet" href="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.css"> <script src="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.js"></script>
Then add the script for your chart and the div for the chart itself:
<script type="text/javascript"> function setChart() { var data = { labels: <%=chartLabels %>, series: <%=chartData%> }; new Chartist.Line('.ct-chart', data); }; window.onload = setChart; </script> <div class="ct-chart ct-perfect-fourth"> </div>
In the backend compute the values you want to show. Probably you would like to read them from SQL DB or else, but I just code them for easier understanding in this example. Take care: chartDate needs 2 square brackets!
Public Class WebForm3 Inherits System.Web.UI.Page Private m_chartData As String Public Property chartData() As String Get Return m_chartData End Get Set(value As String) m_chartData = value End Set End Property Private m_chartLabels As String Public Property chartLabels() As String Get Return m_chartLabels End Get Set(value As String) m_chartLabels = value End Set End Property Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not Page.IsPostBack Then SetValues() End If End Sub Private Sub SetValues() chartData = "[]280, 45, 133, 166, 84, 259, 266, 960, 219, 311, 67, 89[]" chartLabels = "['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']" End Sub End Class
And that’s all.
Of course you could do much more with Chartist, like Animations, tooltips etc., but current post should only give you a first overview how to start with asp.net and Chartist JS. Now have a look at their examples and create your own charts.
RGraph changed license type so always download your tools
This is not a how-to article to describe some development techniques. It’s just a reminder to always download the full package of any external tools you use!
Reason for this blog post is the changed license of RGraph.net: Previously it was free for everyone to use, both personal and commercial. That’s why I used it and also wrote a blog post how to Create HTML5 Charts using ASP.net and RGraph. But now the license has changed! It’s still free for personal projects, but if you want to use it in commercial projects your have to pay 99 £ (currently around 130 € or 150 US-$). I was surprised to discover this because I did not find any announcement about the license change. I would expect some information somewhere. Maybe on the start screen so everyone is informed. At least on the license page or on the previous donation page (which does not exist anymore). Maybe also on their facebook page. Or on Twitter? They have 419 followers so they might be interested in a license change. But nothing found.
So I checked the internet archive. According to their archives, the change has been made between 02. August 2014 (saying “Truly Open Source and Free to use”) and 28. August 2014 (where it’s “Open and free for non-commercial”). I also checked their facebook and twitter accounts for this time range, but no information found 🙁
I’m a bit sad that the license change is not published anywhere. Of course RGraph is a great tool, and for sure they deserve the money. It seems that donations were not successful, so the switch to another license type is of course completely ok. I fully support this. But I regret that there is no information to the current users. Why do they want to hide the change? Why not be more open and explain the change? I guess most users would understand that switch.
So now I’ve discovered the license change by coincidence. So what about my current license? I’m using a version which was free. Am I still allowed to use it for free? I think so, because you could change the license for new versions, but not for published ones (as far as I know). Additionally I have in mind that the RGraph project is not developed anymore? I thought I’ve visited the site maybe 2 months
Several other projects show much better how to switch a license type: Explain to the user, clarify what is allowed with old versions, maybe still offer the old free code to download, explain why the license is switched and what advantages users would have from the new version.
So what I’ve learned from this: Always download the tools you are using! Content-Delivery Networks (CDN) are great and easy to use, but if the license type changes unexpected you might have problems to use the previously free version. Having a local copy would always help, also in legal cases.
Update from 02. July 2015:
I just received an email from Richard that the license of RGraph has been changed again. Now it has 2 license types: GPL or purchase. Please have a look at RGrpahs License page for all the details
Download Enterprise library log file which is currently in use by asp.net
I use Microsofts Enterprise Library in many web projects. The modules are very easy to use, so e.g. you have a log for your website up and running in minutes. The problem I faced: I write the log into textfiles, and of course they are always in use. I could download them via FTP and read offline, but what if I want to read it online? Of course I don’t have the files in the public webdirectory as it contains confidential information. So I need to provide a download mechanism, but there is one trap because the logfile is more or less always in use. So here is how to do it, and we also create a general procedure out of it so that the filename is retrieved from web.config instead of hardcoded. Continue reading…
How to create tooltips in asp:Repeater using Bootgrid
In my previous posts Use jQuery Bootgrid with asp.net Gridview and Use jQuery Bootgrid with asp.net Repeater I have already shown details about using jQuery-Bootgrid in asp.net Gridview and Repeater. I’ve also shown how to format datetime or numeric values, style columns, add links and some more. So here are some more things which you might want to add in your jQuery Bootgrid implementation. These tips are not related to asp.net anymore, so these are also helpful if you are on PHP, HTML or whatever. Continue reading…
Use jQuery Bootgrid with asp.net Repeater
In last post “Use jQuery Bootgrid with asp.net Gridview” I’ve setup jQuery-Bootgrid to work with an asp.net Gridview control. Now I do the same for asp:Repeater control. Additionally I’ve changed the style of a column and also the output of the datetime column so that it’s now working fine if the datatable contains the value as datetime instead of string. Continue reading…
Use jQuery Bootgrid with asp.net Gridview
I’ve used Twitters Bootstrap template in several asp.net projects. I’m surprised that I had no large gridviews in these projects, but just when I needed one t3n has published an article containing information about jQuery Bootgrid.This plugin makes a grid much more convenient, so I set it up in my project and it works brillant.
Here are the steps to be done to implement jQuery-Bootgrid into your existing asp:Gridview, so you should already have setup your gridview and data retrieval on your own. Once this is done, the following steps are necessary to use jQuery-Bootgrid. You will find the whole source code of WebForm1.aspx and Webform1.aspx.vb at the bottom of the article
- Add jQuery, Bootstrap and jquery-Bootgrid to your project. This contains several JavaScript-Files and Stylesheets.
<!-- jQuery, http://jquery.com/ --> <script src="//code.jquery.com/jquery-1.11.0.min.js" type="text/javascript"></script> <script src="//code.jquery.com/jquery-migrate-1.2.1.min.js" type="text/javascript"></script> <!-- Bootstrap, http://getbootstrap.com/ --> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css"> <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js" type="text/javascript"></script> <!-- Bootgrid, http://jquery-bootgrid.com/ or https://github.com/rstaib/jquery-bootgrid --> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-bootgrid/1.1.4/jquery.bootgrid.min.js" type="text/javascript"></script> <link rel="Stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jquery-bootgrid/1.1.4/jquery.bootgrid.min.css" />
- Inform Bootgrid about the grid to be prepared. 2 Steps are necessary:
1. Add data-toggle=”bootgrid” to your grid, and
2. Activate Bootgrid on your gridview. Additionally I personally don’t like case-sensitivity so I turned it off, of course that’s up to you.<script type="text/javascript" language="javascript"> $(function () { $('#<%= MyGridview.ClientID %>').bootgrid({ caseSensitive: false }); }); </script>
- Add data-grid-id for all columns. You could not add it right into your aspx because you would get an error message “Type ‘System.Web.UI.WebControls.BoundField’ does not have a public property named ‘data-column-id’.” Therefore you have to do this in the backend. Create a Handler for your Gridview.RowCreated and add the attributes to your header.
Private Sub MyGridview_RowCreated(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles MyGridview.RowCreated If Not e Is Nothing Then If e.Row.RowType = DataControlRowType.Header Then e.Row.Cells(0).Attributes.Add("data-column-id", "companyname") e.Row.Cells(1).Attributes.Add("data-column-id", "customernumber") e.Row.Cells(2).Attributes.Add("data-column-id", "creationdate") e.Row.Cells(3).Attributes.Add("data-column-id", "search") End If End If End Sub
- Set up gridview to build also theader. By default, gridview creates a HTML-Table with only tbody. For Bootgrid it’s important to have also theader. To do this set the following attribute:
Griview.HeaderRow.TableSection = TableRowSection.TableHeader
Now you should be able to compile your application and it should work fine!
Here are some more information which you might find useful once your grid works fine:
How to sort numeric columns
As you see, ‘CustomerNumber’ is a numeric column, but Bootgrid sorts it using string sorting, means e.g. ‘100’ is listed before ’70’. To change this behavior, you could simply set the data-converter to numeric in the backend: e.Row.Cells(1).Attributes.Add(“data-converter”, “numeric”)
How to sort date columns
Sorting date columns is a bit tricky, because you need to transfer the provided date into javascript date format for sorting and later on back to string for displaying. Of course Bootgrid does this for you, but you have to take care about the format.If you have a look at the example code below, column ‘CreationDate’ is provided as string, not as date column: row(“CreationDate”) = Today.AddMonths(-1).ToString(“yyyy-MM-dd”). This helps to ensure that the date is formatted in a way which javascript understands so it’s easier to write the converters. Of course you could use your own format and take care to update the converter accordingly. In my example I’ve created a new converter called ‘datetime’ with a very basic structure (For a better output you could of course use special libraries like moment.js). In the backend you need to set the datetime-converter for the correct column and make sure that the datevalues in the column are in a format which is understandable for your converter. Easiest way is of course to supply the values as string instead of date so you control the format in both backend and frontend accordingly.
converters: { datetime: { from: function (value) { return new Date(value); }, to: function (value) { var d = value.getDate(); var m = value.getMonth(); m += 1; // JavaScript months are 0-11 var y = value.getFullYear(); return (d + "." + m + "." + y); } } }
Add a hyperlink column
Sometimes you also need to have some hyperlink columns in your grid. As Bootgrid takes over the control of your grid, Hyperlinks defined in your gridview would not work anymore. But Bootgrid has a feature for it: Formatters. You could define formatters on your own. In my example code I have a column ‘Search’ (which is not sortable) linking to Bing to search for the companyname. In your formatter you could reference all values from the current row, e.g. see row.search: The data-column-id ‘search’ is defined in backend and then used in the formatter.
formatters: { "link": function (column, row) { return "<a href=\"http://www.bing.com/search?q=" + row.search + "\">" + column.id + ": " + row.companyname + "</a>"; } }
The complete source code
Here is WebForm1.aspx and WebForm1.aspx.vb. It’s all set up to have a master page ‘Site1.Master’ which is the default created by Visual Studio, no changes there.
Webform1.aspx
<%@ Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/Site1.Master" CodeBehind="WebForm1.aspx.vb" Inherits="WebApplication1.WebForm1" %> <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server"> <!-- jQuery, http://jquery.com/ --> <script src="//code.jquery.com/jquery-1.11.0.min.js" type="text/javascript"></script> <script src="//code.jquery.com/jquery-migrate-1.2.1.min.js" type="text/javascript"></script> <!-- Bootstrap, http://getbootstrap.com/ --> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css"> <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js" type="text/javascript"></script> <!-- Bootgrid, http://jquery-bootgrid.com/ or https://github.com/rstaib/jquery-bootgrid --> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-bootgrid/1.1.4/jquery.bootgrid.min.js" type="text/javascript"></script> <link rel="Stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jquery-bootgrid/1.1.4/jquery.bootgrid.min.css" /> <script type="text/javascript" language="javascript"> $(function () { $('#<%= MyGridview.ClientID %>').bootgrid({ caseSensitive: false, formatters: { "link": function (column, row) { return "<a href=\"http://www.bing.com/search?q=" + row.search + "\">" + column.id + ": " + row.companyname + "</a>"; } }, converters: { datetime: { from: function (value) { return new Date(value); }, to: function (value) { var d = value.getDate(); var m = value.getMonth(); m += 1; // JavaScript months are 0-11 var y = value.getFullYear(); return (d + "." + m + "." + y); } } } }); }); </script> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server"> <asp:GridView ID="MyGridview" runat="server" AutoGenerateColumns="false" CssClass="table table-bordered" data-toggle="bootgrid"> <Columns> <asp:BoundField HeaderText="Company" DataField="CompanyName" /> <asp:BoundField HeaderText="Customer Number" DataField="CustomerNumber" /> <asp:BoundField HeaderText="Creation Date" DataField="CreationDate" /> <asp:BoundField HeaderText="Search Bing" DataField="Search" /> </Columns> </asp:GridView> </asp:Content>
Webform1.aspx.vb
Public Class WebForm1 Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not Page.IsPostBack Then With MyGridview .DataSource = GetDatatable() .DataBind() .HeaderRow.TableSection = TableRowSection.TableHeader End With End If End Sub Private Function GetDatatable() As DataTable Dim dt As New DataTable dt.Columns.Add("CompanyName") dt.Columns.Add("CustomerNumber") dt.Columns.Add("CreationDate") dt.Columns.Add("Search") Dim row As DataRow row = dt.NewRow row("CompanyName") = "Company abc" row("CustomerNumber") = 100 row("CreationDate") = Today.AddMonths(-1).ToString("yyyy-MM-dd") row("Search") = "abc" dt.Rows.Add(row) row = dt.NewRow row("CompanyName") = "Company def" row("CustomerNumber") = 1001 row("CreationDate") = Today.AddDays(-15).ToString("yyyy-MM-dd") row("Search") = "def" dt.Rows.Add(row) row = dt.NewRow row("CompanyName") = "company ghi" row("CustomerNumber") = 70 row("CreationDate") = Today.AddDays(-25).ToString("yyyy-MM-dd") row("Search") = "ghi" dt.Rows.Add(row) row = dt.NewRow row("CompanyName") = "cOmPaNy jkl" row("CustomerNumber") = 345 row("CreationDate") = Today.AddDays(-5).ToString("yyyy-MM-dd") row("Search") = "jkl" dt.Rows.Add(row) Return dt End Function Private Sub MyGridview_RowCreated(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles MyGridview.RowCreated If Not e Is Nothing Then If e.Row.RowType = DataControlRowType.Header Then e.Row.Cells(0).Attributes.Add("data-column-id", "companyname") e.Row.Cells(1).Attributes.Add("data-column-id", "customernumber") e.Row.Cells(1).Attributes.Add("data-converter", "numeric") e.Row.Cells(1).Attributes.Add("data-align", "right") e.Row.Cells(2).Attributes.Add("data-column-id", "creationdate") e.Row.Cells(2).Attributes.Add("data-converter", "datetime") e.Row.Cells(3).Attributes.Add("data-column-id", "search") e.Row.Cells(3).Attributes.Add("data-sortable", "false") e.Row.Cells(3).Attributes.Add("data-formatter", "link") End If End If End Sub End Class
Site1.Master
<%@ Master Language="VB" AutoEventWireup="false" CodeBehind="Site1.master.vb" Inherits="WebApplication1.Site1" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <asp:ContentPlaceHolder ID="head" runat="server"> </asp:ContentPlaceHolder> </head> <body> <form id="form1" runat="server"> <div> <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server"> </asp:ContentPlaceHolder> </div> </form> </body> </html>