Important Note
The default language for the CustomGrid is English. You don't need a .json file for English unless you want to overwrite the default values.
Thank you for purchasing Arthaus Custom Grid. If you have any questions that have not been answered below, or you didn't find the answer in our demo project, feel free to contact us via our CodeCanyon account.
Thanks again!
To be able to use CustomGrid control you need to have the following software components:
The image below shows an example for adding a reference to the Arthaus CustomGrid component in your project.
Below is HTML example of required JavaScript and CSS file references for this grid to run properly:
<link href="Content/CustomGrid.css" rel="stylesheet" type="text/css" />
<link href="Content/jquery-ui-1.8.12.css" rel="stylesheet" type="text/css" />
<script src="Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
<script src="Scripts/jquery-ui-1.8.12.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.contextMenu.js" type="text/javascript"></script>
Create a folder with name "CustomGrid". The folder needs to have write permissions so that CustomGrid.js is generated. Once it is generated you can remove the write permissions.
The CustomGrid allows you to easily support any number of languages. Language strings are stored in .json files within the CustomGrid/Language directory.
You should save one .json file for each supported language. The files should be named according to the predefined CultureInfo names and identifiers accepted and used by CultureInfo Class in the System.Globalization namespace.
You can see a sample .json file here.
You can see the table of language Culture Names here.
The default language for the CustomGrid is English. You don't need a .json file for English unless you want to overwrite the default values.
The CustomGrid class has static method for Drawing the Grid, methods for creating grid columns and 2 static methods for generating the grid paging. In continuation are given the definitions of the CustomGrid methods.
DrawGrid is a static method that returns back the full grid html. It can be used in any view of the MVC project.
public static HtmlString DrawGrid(
string gridID,
IEnumerable<dynamic> model,
CustomGridColumn[] columns,
NameValueCollection queryStringParams,
string action,
bool groupBy = false,
bool searchBy = true,
string tableCssClass = "datatable",
string dateFormat = "mm/dd/yy")
This method has the following parameters:
The "column" method has 6 overloads and is used for generating the grid columns with specific settings.
public static CustomGridColumn column(string headerTitle, string fieldName, bool sort = false, string align = "left", string filterType = "none", bool nowrap = false)
Parameters:
The code for a basic example of grid with two simple (text) columns will look like this:
@CustomGrid.CustomGrid.DrawGrid("cl", Model,
CustomGrid.CustomGrid.columns(
CustomGrid.CustomGrid.column("First Name", "FirstName", true, "left", "text"),
CustomGrid.CustomGrid.column("Last Name", "LastName", true, "left", "text")
), Request.QueryString)
The above code in the browser looks like the image below.
You will notice that by clicking the icon next to the search filter, a context menu with available search options will be displayed for that field. By default the text filter is "contains", which means that results must contain the searched text. Please see the example below.
If we need to change the filterType to "number", a context menu with available search options for number filtering will appear. By default, the number filter is "Equals".
In the example above if we want to add additional column with "date" filtering, we need to add the following code:
CustomGrid.CustomGrid.column("Date Created", "DateCreated", true, "left", "date")
The source code for the grid will be:
@CustomGrid.CustomGrid.DrawGrid("cl", Model,
CustomGrid.CustomGrid.columns(
CustomGrid.CustomGrid.column("First Name", "FirstName", true, "left", "text"),
CustomGrid.CustomGrid.column("Last Name", "LastName", true, "left", "text"),
CustomGrid.CustomGrid.column("Date Created", "DateCreated", true, "left", "date")
), Request.QueryString)
The source code from above will output the following grid:
We can notice in the above example that when we add a "date" filter, two input fields appear, the first for "From date" and the second for "To Date". In other words we have the ability to filter the results between specific dates for the given column.
Have in mind that grid is not implementing client side filtering, but is only sending this info to the server side, where it is your responsibility to filter the data. Also the filter submit form is triggered by pressing "Enter" in any of the filter input fields or by changing the value in filter drop down menu.
The code below is the method used for a simple column with drop down filter.
public static CustomGridColumn column(string headerTitle, string fieldName, IEnumerable<dynamic> filterDropDownList, bool sort = false, string align = "left")
Parameters:
The code below is used to create a simple column with "drop down" filter.
CustomGrid.CustomGrid.column("User Type", "UserType", new CustomGrid.DropDownList[] { new CustomGrid.DropDownList() { optionID = "Admin", optionValue = "Admin" }, new CustomGrid.DropDownList() { optionID = "Member", optionValue = "Member" } }, true, "center")
If we add this column to the previous grid we will have the following code:
@CustomGrid.CustomGrid.DrawGrid("cl", Model,
CustomGrid.CustomGrid.columns(
CustomGrid.CustomGrid.column("First Name", "FirstName", true, "left", "text"),
CustomGrid.CustomGrid.column("Last Name", "LastName", true, "left", "text"),
CustomGrid.CustomGrid.column("Date Created", "DateCreated", true, "left", "date"),
CustomGrid.CustomGrid.column("User Type", "UserType", new CustomGrid.DropDownList[] { new CustomGrid.DropDownList() { optionID = "Admin", optionValue = "Admin" }, new CustomGrid.DropDownList() { optionID = "Member", optionValue = "Member" } }, true, "center")
), Request.QueryString)
Visually the above code will look like the following:
From the image above, we can see that the a dropdown filter appears with available options for filtering.
The code below is the method used for a column with more values.
public static CustomGridColumn column(string headerTitle, string html, string[] fieldNames, bool sort = false, string align = "left", string filterType = "none", bool nowrap = false, bool HTMLEncode = false)
Parameters:
As example this kind of column can help us if we need to make some the column text as a link. Lets modify the "First Name" column as a link which uses the ID of the record.
CustomGrid.CustomGrid.column("First Name", "<a href='/Users/Details/?id={1}'>{0}</a>", new string[] { "FirstName", "ID" }, true, "left", "text")
The modified grid source code will be:
@CustomGrid.CustomGrid.DrawGrid("cl", Model,
CustomGrid.CustomGrid.columns(
CustomGrid.CustomGrid.column("First Name", "<a href='/Users/Details/?id={1}'>{0}</a>", new string[] { "FirstName", "ID" }, true, "left", "text"),
CustomGrid.CustomGrid.column("Last Name", "LastName", true, "left", "text"),
CustomGrid.CustomGrid.column("Date Created", "DateCreated", true, "left", "date"),
CustomGrid.CustomGrid.column("User Type", "UserType", new CustomGrid.DropDownList[] { new CustomGrid.DropDownList() { optionID = "Admin", optionValue = "Admin" }, new CustomGrid.DropDownList() { optionID = "Member", optionValue = "Member" } }, true, "center")
), Request.QueryString, false)
We can add as much fields in the array as needed. Below is a visual example of the source code from above.
The code below is the method used to create a column with more values and a "dropdown" filter for that column.
public static CustomGridColumn column(string headerTitle, string html, string[] fieldNames, IEnumerable<dynamic> filterDropDownList, bool sort = false, string align = "left")
Parameters:
As example we can make the column "User Type" as a link. The modified grid source code will look as the example below.
@CustomGrid.CustomGrid.DrawGrid("cl", Model,
CustomGrid.CustomGrid.columns(
CustomGrid.CustomGrid.column("First Name", "<a href='/Users/Details/?id={1}'>{0}</a>", new string[] { "FirstName", "ID" }, true, "left", "text"),
CustomGrid.CustomGrid.column("Last Name", "LastName", true, "left", "text"),
CustomGrid.CustomGrid.column("Date Created", "DateCreated", true, "left", "date"),
CustomGrid.CustomGrid.column("User Type", "<a href='/Users/Details/?id={1}'>{0}</a>", new string[] { "UserType", "ID" }, new CustomGrid.DropDownList[] { new CustomGrid.DropDownList() { optionID = "Admin", optionValue = "Admin" }, new CustomGrid.DropDownList() { optionID = "Member", optionValue = "Member" } }, true, "center")
), Request.QueryString)
The source code for the method used for a column with conditions is displayed below.
public static CustomGridColumn column(string headerTitle, Conditions[] conditions, string[] fieldNames, bool sort = false, string align = "left", string filterType = "none")
Parameters:
Here is simple example of using conditions when displaying data:
CustomGrid.CustomGrid.columns(
CustomGrid.CustomGrid.column("I am...",
new CustomGrid.Conditions[] {
new CustomGrid.Conditions("UserType", "==", "Member", "I am a member: {0} {1}"),
new CustomGrid.Conditions("UserType", "==", "Admin", "I am an admin: {0} {1}")
}, new string[] { "FirstName", "LastName" }, false, "left")
This grid is supporting only simple conditions, like:
Only the html from the first correct condition will be displayed.
When comparing strings, numbers or booleans using "==" operator but the value is NULL then the result will be false! Similarly, when comparing strings, numbers or booleans using "!=" operator but the value is NULL then the result will be true!
If the filter is enabled for this type of column, the data will be filtered by the first element in fieldNames array (in this case "FirstName").
The code below is the method used for a column with conditions and a dropdown filter.
public static CustomGridColumn column(string headerTitle, Conditions[] conditions, string[] fieldNames, IEnumerable<dynamic> filterDropDownList, bool sort = false, string align = "left")
The data displayed in grid cells can be formatted very simply. The cell formatting is using .NET String.Format static method, which means everything specified in columns html parameter can be formatted by using the values from fieldNames array.
Below is an example of source code for formatting the "ID" column with a leading zeros, date formatting, double value formatting and currency formatting.
@CustomGrid.CustomGrid.DrawGrid("cl", Model,
CustomGrid.CustomGrid.columns(
CustomGrid.CustomGrid.column("ID", "{0:000000}, {1:n}", new string[]{"ID", "DoubleValue"}, true, "right"),
CustomGrid.CustomGrid.column("Date Created", "{0:yyyy-MM-dd}", new string[] { "DateCreated" }, true, "left", "date"),
CustomGrid.CustomGrid.column("Double Value", "<span style='color:green'>{0:n}</span> or {0:c}", new string[] { "DoubleValue" }, true, "right", "number")
), Request.QueryString)
Currently there are 2 types of paging available, "classic" paging and "scroll" paging.
If we want to add a classic paging to the grid, we can use the following code:
@CustomGrid.CustomGrid.PagingNumbers("cl", Request.QueryString, ViewBag.totalRecords, "20")
In the above example, the first parameter is "gridID" and it needs to be the same as gridID used in DrawGrid method, the second parameter is the NameValueCollection of the Query string, the third parameter is total number of records, and the last parameter is the number of records per page.
Now the complete source of the grid and the paging will be:
@CustomGrid.CustomGrid.DrawGrid("cl", Model,
CustomGrid.CustomGrid.columns(
CustomGrid.CustomGrid.column("First Name", "<a href='/Users/Details/?id={1}'>{0}</a>", new string[] { "FirstName", "ID" }, true, "left", "text"),
CustomGrid.CustomGrid.column("Last Name", "LastName", true, "left", "text"),
CustomGrid.CustomGrid.column("Date Created", "{0:yyyy-MM-dd}", new string[] { "DateCreated" }, true, "left", "date"),
CustomGrid.CustomGrid.column("User Type", "<a href='/Users/Details/?id={1}'>{0}</a>", new string[] { "UserType", "ID" }, new CustomGrid.DropDownList[] { new CustomGrid.DropDownList() { optionID = "Admin", optionValue = "Admin" }, new CustomGrid.DropDownList() { optionID = "Member", optionValue = "Member" } }, true, "center"),
CustomGrid.CustomGrid.column("Decimal Value", "<span style='color:green'>{0:c}</span>", new string[] { "DoubleValue" }, true, "right", "number")
), Request.QueryString)
@CustomGrid.CustomGrid.PagingNumbers("cl", Request.QueryString, ViewBag.totalRecords, "20")
The output with the "classic" paging is shown below:
The advanced paging has option for selecting a number of records per page. The paging is done via "jquery" scroller which produces great visual effects to the users.
The usage of the advanced paging is "almost" the same as the classic paging, the only difference is the name of the method. Instead of "PagingNumbers" which is the classic paging, the method for advanced paging is "PagingScroll".
If we change the above source code to the following:
@CustomGrid.CustomGrid.DrawGrid("cl", Model,
CustomGrid.CustomGrid.columns(
CustomGrid.CustomGrid.column("First Name", "<a href='/Users/Details/?id={1}'>{0}</a>", new string[] { "FirstName", "ID" }, true, "left", "text"),
CustomGrid.CustomGrid.column("Last Name", "LastName", true, "left", "text"),
CustomGrid.CustomGrid.column("Date Created", "{0:yyyy-MM-dd}", new string[] { "DateCreated" }, true, "left", "date"),
CustomGrid.CustomGrid.column("User Type", "<a href='/Users/Details/?id={1}'>{0}</a>", new string[] { "UserType", "ID" }, new CustomGrid.DropDownList[] { new CustomGrid.DropDownList() { optionID = "Admin", optionValue = "Admin" }, new CustomGrid.DropDownList() { optionID = "Member", optionValue = "Member" } }, true, "center"),
CustomGrid.CustomGrid.column("Decimal Value", "<span style='color:green'>{0:c}</span>", new string[] { "DoubleValue" }, true, "right", "number")
), Request.QueryString)
@CustomGrid.CustomGrid.PagingScroll("cl", Request.QueryString, ViewBag.totalRecords, "20")
In the browser it will look like the image below:
CustomGrid.css file contains the grid css classes. They are grouped in 5 categories:
Each grid action is sending an ajax GET request to the server. Below is list of the all possible form elements, their names and possible values they can have.
The grid is using two type of forms:
<-- Filter form: -->
<form method="get" id="frm_GRIDID">
...
</form>
<-- Paging form: -->
<form method="get" id="frmP_GRIDID">
...
</form>
Filter form ID always starts with "frm_" and then is concatenated with GRIDID which is the grid ID added to each form and form field. This way you can have multiple different grids on same page. Paging form ID always starts with "frmP_" and then concatenated with GRIDID.
No matter which form is submitted, both have the same form fields, with same name syntax:
<-- text and number filter fields -->
<input id="GRIDID_FIELDNAME" name="GRIDID_FIELDNAME" type="text" />
<input id="GRIDID_o_FIELDNAME" name="GRIDID_o_FIELDNAME" type="hidden" />
<-- drop down filter fields -->
<select id="GRIDID_FIELDNAME" name="GRIDID_FIELDNAME">
<-- date filter fields -->
<input id="GRIDID_from_FIELDNAME" name="GRIDID_from_FIELDNAME" type="text" />
<input id="GRIDID_to_FIELDNAME" name="GRIDID_to_FIELDNAME" type="text" />
<-- paging fields for page size and page number: -->
<select name="GRIDID_pages">
<input id="GRIDID_page" name="GRIDID_page" type="hidden" />
Selected filter options from Context menu are kept in the hidden fields for each text and number filter (name="GRIDID_o_FIELDNAME"). Here is a list of all possible values and their meaning:
// Text filters:
"sf_1": Contains
"sf_2": Not contains
"sf_3": Starts with
"sf_4": Ends with
"sf_5": Equals to
"sf_6": Not equals to
// Number Filters:
"sf_7": Equals to
"sf_8": Not equals to
"sf_9": Is less then
"sf_10": Is less then or equal to
"sf_11": Is greater then
"sf_12": Is greater then or equal to
"sf_13": Between
"sf_14": Not between
// Both Filters:
"sf_15": Is null
"sf_16": Is not null
For example if your "query string" on server side has the following code: MyGrid_FisrtName=Test&MyGrid_o_FisrtName=sf_4 it means that you need to search all first names in your data collection that end with "Test".
The server side processing is completely left in your hands. This grid is only displaying data that you will provide, and is sending back to the server user's actions on the grid. The way you will retrieve, filter, sort and paginate your data is your code responsibility.
In order to make this product more user friendly, we are delivering it with sample demo MVC3 project that has different types of grid examples. We are also suggesting two server side dynamic query generation techniques for easy filtering, sorting and paging.
To make the process of getting filter values easier, we have developed a helper class "QueryParams". This class is already included in CustomGrid component, but the code is also available as helper class within this demo project, so you can easily change the code and adapt it to your needs.
Controller:
public ActionResult SampleGrid6()
{
//database connection object defined in User model
SampleSQLDB db = new SampleSQLDB();
//get paging values from the query string
int pageNum = CustomGrid.QueryParams.getPageNumber("cl" Request.QueryString);
int pageSize = CustomGrid.QueryParams.getPageSize("cl", Request.QueryString);
//get sorting values from query string
string sort = CustomGrid.QueryParams.getSortField("cl", Request.QueryString, new User(), "ID");
string stype = CustomGrid.QueryParams.getSortType("cl", Request.QueryString);
//get filter where conditions and values from the query string
List<object> whereValues = new List<object>();
string whereConditions = "";
whereConditions += CustomGrid.QueryParams.getLINQQueryParam("cl", "FirstName", Request.QueryString, whereValues);
whereConditions += CustomGrid.QueryParams.getLINQQueryParam("cl", "LastName", Request.QueryString, whereValues);
whereConditions += CustomGrid.QueryParams.getLINQQueryParam("cl", "DateCreated", Request.QueryString, whereValues);
whereConditions += CustomGrid.QueryParams.getLINQQueryParam("cl", "UserType", Request.QueryString, whereValues);
whereConditions += CustomGrid.QueryParams.getLINQQueryParam("cl", "DoubleValue", Request.QueryString, whereValues);
//get data from database
var sampleUser = db.Users.Select(i => i);
sampleUser = sampleUser.AsQueryable().Where("1=1 " + whereConditions, whereValues.ToArray()).OrderBy(sort + " " + stype);
//count the total number of records
ViewBag.totalRecords = sampleUser.Count();
//get only required page data by skiping the other records
sampleUser = sampleUser.Skip(pageSize * (pageNum-1)).Take(pageSize);
return View(sampleUser.ToList());
}
View:
@CustomGrid.CustomGrid.DrawGrid("cl", Model,
CustomGrid.CustomGrid.columns(
CustomGrid.CustomGrid.column("First Name", "FirstName", true, "left", "text"),
CustomGrid.CustomGrid.column("Last Name", "LastName", true, "left", "text"),
CustomGrid.CustomGrid.column("Date Created", "DateCreated", true, "left", "date"),
CustomGrid.CustomGrid.column("User Type", "UserType", new CustomGrid.DropDownList[] { new CustomGrid.DropDownList() { optionID = "Admin", optionValue = "Admin" }, new CustomGrid.DropDownList() { optionID = "Member", optionValue = "Member" } }, true, "center"),
CustomGrid.CustomGrid.column("Email", "Email", true, "left", "text")
), Request.QueryString)
@CustomGrid.CustomGrid.PagingScroll("cl", Request.QueryString, ViewBag.totalRecords, "20")
Most of the code is same as in previous example, except that in this approach we are generating sql query with all included conditions for filtering, sorting and paging.
Part of the controller's code:
//get filter where conditions from query string
string whereConditions = "";
whereConditions += CustomGrid.QueryParams.getQueryParam("cl", "FirstName", Request.QueryString);
whereConditions += CustomGrid.QueryParams.getQueryParam("cl", "LastName", Request.QueryString);
whereConditions += CustomGrid.QueryParams.getQueryParam("cl", "DateCreated", Request.QueryString);
whereConditions += CustomGrid.QueryParams.getQueryParam("cl", "UserType", Request.QueryString);
whereConditions += CustomGrid.QueryParams.getQueryParam("cl", "DoubleValue", Request.QueryString);
//get data from database
int totalRecords = 0;
var sampleUser = db.getUsers(pageStart, pageEnd, sort, stype, whereConditions, out totalRecords).ToList();
ViewBag.totalRecords = totalRecords;
User Model:
public IEnumerable<User> getUsers(int startRow, int endRow, string sort, string sorttype, string conditions, out int totalRecords)
{
//count all records
var maxRowNumber = this.ExecuteQuery<int>(@"
SELECT COUNT(ID) as cnt FROM Users WHERE 1=1 " + conditions
);
//get the total number of records
totalRecords = maxRowNumber.SingleOrDefault();
//select users with paging and sorting
return this.ExecuteQuery<User>(@"
SELECT subquery.* FROM (
SELECT *, ROW_NUMBER() OVER(ORDER BY " + sort + " " + sorttype + @") AS rowNumber
FROM Users
WHERE 1=1 " + conditions + @"
) AS subquery
WHERE rowNumber BETWEEN {0} AND {1}", startRow, endRow);
}
Because it is not using prepare statement for query variables, this approach has potential query injection problem which is fixed by using the QueryParams.getQueryParam method for getting the values from the query string.
The demo project has couple of examples of how this grid can be used within a MVC project. Below is short explanation of each project folder/file and its purpose.