Part 4 : How I show photo in w2ui grid

Hi,

recently my client ask me to create a photo gallery.

This was easy, using Blueimp Gallery, I manage to develop it in no time.

But then I face a problem how to delete and edit the photo as we cannot do it directly from  Blueimp Gallery . This is when I try to use w2ui grid and to my surprise its work like charm.

So here I want to share what I have done so far.

The Model

public class Photo 
{
   public int Id { get; set; }
   public DateTime CreatedDate { get; set; }
   public String Description { get; set; }
   public String ImagePath { get; set; }
   public String ThumbPath { get; set; }
}


My View (Index.cshtml)

@model IEnumerable<MyProject.Models.Photo>

@Styles.Render("~/w2ui/css")
<div id="indexGallery" style="width: 100%; height: 400px; overflow: hidden;"></div>

@section Scripts 
{
@Scripts.Render("~/w2ui/js")

<script>
  $(document).ready(function () {
    $('#indexGallery').w2grid({
      name: 'indexGallery',
      header: 'Gallery',
      recordHeight: 70,
      url: {
        get: '@Url.Action("LoadRecords")',
        remove: '@Url.Action("DeleteRecords")',
        save: '@Url.Action("InlineEdit")'
      },
      recid: 'Id',
      fixedBody: true,
      show: {
         lineNumbers: true,
         toolbar: true,
         header: true,
         footer: true,
         toolbarAdd: false,
         toolbarDelete: true,
         toolbarEdit: false,
         toolbarSave: true,
      },
      columns: [
        { field: 'ThumbPath', caption: 'Photo', sortable: false, size: '5%',
            render: function (record) {
              var html; 
              html = '<a href="' + record.ImagePath + '" target="_blank">' +
                     '<img src="' + record.ThumbPath + '" alt="' + record.ThumbPath + '" class="img-rounded" style="margin:2px;" /></a>';
              return html;
              }
        },
        { field: 'Description', caption: 'Tajuk', sortable: true, size: '5%', editable: { type: 'text' }, info: true },
        { field: 'CreatedDate', caption: 'Tarikh Upload', sortable: true, size: '5%',
            render: 'date:dd-mm-yyyy', editable: { type: 'date', format: 'dd-mm-yyyy' },
        },
        { field: 'NoFail', caption: 'No. Fail', sortable: true, size: '5%', editable: { type: 'text' } },
      ],
      searches: [
        { field: 'Description', caption: 'Tajuk', type: 'text' },
        { field: 'NoFail', caption: 'No. Fail', type: 'text' },
      ],
      onDelete: function (event) {
        if (event.status == "error") {
          console.log("Error Delete Record : " + event.message);
        }
      },
      onSave: function (event) {
        if (event.status == "error") {
           w2alert(event.message, "Error During Save");
        } else {
           w2ui['indexGallery'].mergeChanges();
        }
      },
   });
  });
</script>
}

The Result

Notes

  • In the above example, I load image thumbnail into w2ui grid.
  • User are able to delete selected photo(s) or edit the description (inline edit)
  • If user click on a thumbnail, the bigger size of the photo will be loaded into a new tab.

Steps

  • In order to do this, there are two main properties we need to configure
  1. change w2ui grid row height to 70px  to properly show photo thumbnail.
    • recordHeight : 70
  2. using render in column-field setting to show the thumbnail .
{ field: 'ThumbPath', caption: 'Photo', sortable: false, size: '5%', 
     render: function (record) { 
       var html; 
       html = '<a href="' + record.ImagePath + 
              '" target="_blank">' + 
              '<img src="' + record.ThumbPath + '" alt="' + record.ThumbPath + 
              '" class="img-rounded" style="margin:2px;" /></a>'; 
       return html; } 
     },
  • That’s it. This the only steps you have to do.

 

The controller

  • Before I end my post, a little bit about the controller.
  • There is nothing special in my controller. I have created related functions to support calls from w2ui grid.
    1. LoadRecords
      • Please look in my previous post which I discuss about this.
      • I used the same function, just change the model name accordingly
    2. DeleteRecords
      • I use this function to delete selected records from the grid
    3. InlineEdit
      • I use this function to save changes done from inline editing
      • I will discuss this two functions in my next post.

OK. I’m done here. See you in my next post.

Reference

Part 3 : Implementing w2ui in ASP.Net – Remote Data Source

In my last post, I already share how I do it with local data source, here I like to share on how I implement w2ui grid with remote data source.

1. CONTROLLER

Using remote data source, w2ui grid need to load data from the controller when user choose to

  • sort
  • search
  • scroll up and down (when needed)

For this purpose, I have created related functions in the controller.

LoadRecords 

  • This is my main function to load records from database
  • I will show later how I call this function from w2ui grid.
public string LoadRecords()
{
  string filter = RequestQueryString();
 
  IEnumerable<Task> records = db.Task
      .SqlQuery("SELECT * FROM Tasks " + filter);

  var jsonData = JsonConvert.SerializeObject(records);
  return jsonData;
}

RequestQueryString

  • this function generate query string base on user request
protected string RequestQueryString(string query = "", string defaultorder = "Id")
{
  string filter = query;
  var req = Request.Form["request"];
  if (req == null) { return filter; }

  JObject r = JObject.Parse(req);
  int limit = (int)r["limit"];
  int offset = (int)r["offset"];

  JArray search = (JArray)r["search"]; // field + type + operator + value
  if (search != null)
  {
    string SearchLogic = (string)r["searchLogic"];
    foreach (JObject o in search.Children<JObject>())
    {
      if (filter == query)
         filter += (query == "" ? "WHERE (" : " AND (") + " (" + SearchFilter(o) + ") ";
      else
         filter += SearchLogic + " (" + SearchFilter(o) + ") ";
      }
      filter += ")";
    }

    JArray sort = (JArray)r["sort"];
    filter += SortFilter(sort, defaultorder);

    return filter + " OFFSET " + offset + 
      " ROWS FETCH NEXT " + limit + " ROWS ONLY";
}

SearchFilter

protected string SearchFilter(JObject o)
{
  string field = (string)o["field"];
  string opt = (string)o["operator"]; //'is', 'between', 'begins with', 'contains', 'ends with'

  string val = (opt != "between" ? (string)o["value"] : "");

  switch (opt)
  {
    case "is":
      val = FormatDate(val);
      return (field + " = '" + val + "'");
    case "begins":
      return (field + " LIKE '" + val + "%'");
    case "contains":
      return (field + " LIKE '%" + val + "%'");
    case "ends":
      return (field + " LIKE '%" + val + "'");
    case "before":
    case "less":
      return (field + " < '" + FormatDate(val) + "'");
    case "after":
    case "more":
      return (field + " > '" + FormatDate(val) + "'");
    case "between":
      string d1 = FormatDate((string)o["value"][0]);
      string d2 = FormatDate((string)o["value"][1]);
      return (field + " BETWEEN '" + d1 + "' AND '" + d2 + "'");
    default: return "";
  }
}

SortFilter

protected string SortFilter(JArray sort, string defaultorder)
{
  if (sort == null)
    return " ORDER BY " + defaultorder;

  string ssql = "";
  foreach (JObject o in sort.Children<JObject>())
  {
    string field = (string)o["field"];
    string order = (string)o["direction"];
    ssql += (ssql == "" ? " ORDER BY " : ", ");
    ssql += field + (order == "asc" ? " ASC" : " DESC");
  }
  return ssql;
}

FormatDate

private string FormatDate(string input)
{
  DateTime d;
  if (DateTime.TryParseExact(input, "dd-MM-yyyy", 
        CultureInfo.InvariantCulture, 
        DateTimeStyles.None, out d))
  {
    return d.ToString("yyyy-MM-dd");
  }
  return input;
}

Notes :

  • I use these functions almost in each of my controller.
  • The only thing I have to change is the model and table name inside LoadRecords function.

 

2. VIEW 

Example for Index Page

@Styles.Render("~/w2ui/css")

<div id="indexGrid" style="width: 100%; height: 400px; overflow: hidden;"></div>

@section Scripts {
   @Scripts.Render("~/w2ui/js")

   <script>
      $(document).ready(function () { 
         $('#indexGrid').w2grid({
            name: 'indexGrid',
            url: {
               get: '@Url.Action("LoadRecords")',
            },
            columns: [ 
               { field: 'lname', caption: 'Last Name', size: '30%', sortable: true },
               { field: 'fname', caption: 'First Name', size: '30%', sortable: true },
               { field: 'email', caption: 'Email', size: '40%', sortable: true },
               { field: 'sdate', caption: 'Start Date', size: '120px', sortable: true }
            ],
            searches: [
               { field: 'fname', caption: 'First Name', type: 'text' },
               { field: 'email', caption: 'Email', type: 'text' },
            ],
          });           
       });
   </script>
}
  • define link to w2ui css and javascript
@Styles.Render("~/w2ui/css")
@Scripts.Render("~/w2ui/js")
  • define url property to LoadRecords 
url: { 
    get: '@Url.Action("LoadRecords")', 
},
  • define sortable: true to enable sorting for selected field
columns: [ 
  { field: 'lname', ... , sortable: true }, 
  ....
],
  • define the search fields
searches: [ 
   { field: 'fname', caption: 'First Name', type: 'text' }, 
   { field: 'email', caption: 'Email', type: 'text' }, 
],

That’s it, we are good to go. I have upload a video to show how I really do it in my project. Try view this video if you having problem to understand the given example .

On next posting, I plan to share on how I do inline editing in w2ui grid.

See you then.

 

Part 1 : Implementing w2ui in ASP.Net MVC – Basic configuration

Hi there,

if you dont know what is w2ui you should visit w2ui homepage. For me this is a wonderful javascript UI library with a very small footprint.

Sadly to say, there are very few tutorial on w2ui available except whats provided in their own page. As part time programmer, I found it very tricky when I want to implement it in my application.

So here I would like to share on how I implement it in my ASP.Net MVC application. More important this will become my own reference point in the future as I tend to forget it after a while. This may be not the best solutions but this how I got it to work.

OK. Let’s get started,

Step 1 : Download w2ui

  • Go to their web site ,
  • Download latest version of w2ui (currently 1.5.rc1)
  • Extract the zip file to your local folder.
  • You should get 4 files (assuming you have downloaded the 1.5.rc1 version)
    • w2ui-1.5.rc1.css
    • w2ui-1.5.rc1.min.css
    • w2ui-1.5.rc1.js
    • w2ui-1.5.rc1.min.js

Step 2 : Add w2ui in  your program

  • Open your ASP.Net project,
  • Create w2ui folder under Content folder
    • add w2ui-1.5.rc1.css and w2ui-1.5.rc1.min.css to this folder
  • Create w2ui folder under Scripts folder
    • add w2ui-1.5.rc1.js and w2ui-1.5.rc1.min.js to this folder

notes : you should add this files using Add-Existing Items.. option.

Step 3 : Add w2ui reference in BundleConfig

  • add these line to your BundleConfig
public static void RegisterBundles(BundleCollection bundles)
{
   ... 
   RegisterW2ui(bundles);
}

private static void RegisterW2ui(bundleCollection bundles)
{
   bundles.Add(new ScriptBundle("~/w2ui/js").Include(
         "~/Scripts/w2ui/w2ui-1.5.rc1.min.js"));
   bundles.Add(new StyleBundle("~/w2ui/css").Include(
         "~/Content/w2ui/w2ui-1.5.rc1.min.css"));
}
  • Now we are good to go .

If you get confuse, try watch this youtube video.

In my next post I will show you how I implement w2ui grid in my project.

 

 

Part 2 : Implementing w2ui in ASP.Net MVC – w2ui grid

Hi again.

In my first post, I have shown how to configure w2ui in your ASP.Net project. If you familiar with ASP.Net MVC project, the View commonly come with Index, Create, Edit and Details pages.

Index page is where I regularly use w2ui grid replacing the standard html table. With w2ui grid you don’t have to worry about search, sort and pagination anymore. Thanks to the writer, Vitamila who has put a lot of his effort to make this library so easy to use.

In this posting I will show you how I implement w2ui grid in my ASP.Net project.

Note – I will not explain in depth of w2ui as you can get it more details from w2ui official page.

W2UI grid

If your refer to the documentation, it give us two examples on how to load data to w2ui grid, i.e. local and remote data source.

Example 1 – Local Data Source

In my earlier attempt using w2ui, I have implement it follow local data source example. This how I did it.

Step 1 – Add the model and reference to w2ui css in Index Page

@model IEnumerable<w2uiproject.Models.TaskReport>

@Styles.Render("~/w2ui/css")

Notes : please refer to earlier post to see how I add w2ui to my project

Step 2 – Add div tag where you want to put the w2ui grid

<div id="indexGrid" style="width: 100%; height: 400px; overflow: hidden;"></div>
  • Here we declare the div to have 400px height with full width of the container
  • Overflow : hidden – show scroll bar if the grid height goes beyond 400px

Step 3 – Add reference to w2ui javascript and create the javascript 

Example  (use your keyboard arrow keys to scroll the code)

@section Scripts {
@Scripts.Render("~/w2ui/js")   // this is required
<script>
$(document).ready(function () {

  $('#indexGrid').w2grid({     
    name: 'indexGrid',
    header: 'List of order',
    show: {      // config grid toolbar, header and footer
      toolbar: true,
      header: true,
      footer: true,
      toolbarAdd: false,
      toolbarDelete: false,
      toolbarEdit: false
    },
    columns: [   // define grid columns
      { field: 'rec1', caption: 'Task', sortable: true, size: '20%' },
      { field: 'rec2', caption: 'Task Date', sortable: true, size: '15%', render: 'date' },
      { field: 'rec3', caption: 'Start Time', sortable: true, size: '10%' },
      { field: 'rec4', caption: 'End Time', sortable: true, size: '10%' },
      { field: 'rec5', caption: 'Duration', size: '10%' },
      {
        field: 'rec6', caption: 'Status', sortable: true, size: '12%',
        render: function (record) { 
           var html;
           if (record.status == 1) {
             html = '<p style="background: blue; color: white;" >Completed<\p>';
           }
           else if (record.status == 2) {
             html = '<p style="background: red; color: white;" >Error<\p>';
           }
           else if (record.status == 3) {
             html = '<p style="background: yellow; color: white;" >Warning<\p>';
           }
           else if (record.status == 4) {
             html = '<p style="background: gray; color: white;" >Cancel<\p>';
           }
           else {
             html = '<p>In Progress<\p>';
           }

           return html;
         }
      },
    ],

    searches: [   // define search options
      { field: 'rec1', caption: 'Task', type: 'int' },
      { field: 'rec2', caption: 'Task Date', type: 'date' },
      { field: 'rec6', caption: 'Status', type: 'list', options: { items: ['Complete', 'Error', 'Warning', 'Cancel', 'In Progress'] } },
    ],

    records: [    // define record items - from model send from controller
      @foreach (var item in Model)
      {
         DateTime dStart = Convert.ToDateTime(@item.StartTime);
         DateTime dEnd = Convert.ToDateTime(@item.EndTime);
         int d1 = 0;

         if (@item.Status == 1)
         {
            d1 = dEnd.Subtract(dStart).Seconds;
         }

         @: { recid: '@item.Id', rec1: '@item.TaskName', rec2: '@dStart', rec3: '@dStart.ToString("HH:mm")', rec4: '@dEnd.ToString("HH:mm")', rec5: '@d1 sec', status: '@item.Status' }, 
      }
    ], // records

  }); // #indexGrid
}); // doc ready

</script>
}

Notes about the example :

  • The w2ui grid is using local data source as we send all records once when loading the page.
  • w2ui did not have to fetch any data from the server during sorting or searching.
  • In the above example, I also shows how to
    • render Date (rec2) and Time (rec3, rec4)
    • show calculated data in rec5
    • show different cell color base on status at rec6
  • Please refer to w2ui page for details on how to configure and display records
  • At minimum you should understand about these properties or method
    • Shows
    • Columns
    • Searches
    • Records
  • You should familiar your self with demo and documentation provided in w2ui page
  • If you still confuse, try view this youtube video where I show how I do it in my ASP.Net project.

Example 2 – Remote Data Source

– for example on remote data source, I will continue in my next posting.