How using RavenDB in a html5/javascript application


In this example will be used RavenDB as database; it will be showed how create a mvc ajax knockout.js / mvvm grid with filter, paging and sort functions. The database is the database example Albums/Genres included in the RavenDB package. Using a linq provider that implement IQueryable, you can change the underlying database in a trasparent mode. (in the other examples was used sqlserver instead of ravendb).

@using JQueryLinq
@model MvcApplication1.Album

@{
    ViewBag.Title = "Page2";
}

<h2>Page2</h2>

@section header{
    <script src="@Url.Content("~/Scripts/zPageGrid1.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/zPageGrid2.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/zPage02.js")" type="text/javascript"></script>
}

<div>
   <input id="gbutton1" type="button" value="Search" />&nbsp;
   <input id="gbutton2" type="button" value="MoveF"  />&nbsp;
   <input id="gbutton3" type="button" value="MoveP"  />&nbsp;
   <input id="gbutton4" type="button" value="MoveN"  />&nbsp;
   <input id="gbutton5" type="button" value="MoveL"  />&nbsp;
</div>

<br /><br />

<div id="gpane1" style="display:none">
  <div>
    <table class="viewmodel">    
    <tr>
      <td>Artist: </td>
      <td><input id="text1" data-bind="value: campo1" /></td>
    </tr>  
    <tr>
      <td>Genre: </td>
      <td><input id="text2" data-bind="value: campo2" /></td>
    </tr> 
    </table>
    <br /><br />
    <input id="gbutton6" type="button" value="Find" />
  </div>
</div>

<div id="gpane2" style="display:none">
  <a href="#" data-jcreateaction>Create new customer</a>
  <br /><br />
  <div>
    <table id="jtable">
    <thead>
    <tr>
      <td colspan="2"> &nbsp; </td>
      <td data-sort="Id"> Id </td>
      <td data-sort="Title"> Title </td>
      <td data-sort="AlbumArtUrl"> AlbumArtUrl </td>
      <td data-sort="Artist"> Artist </td>
      <td data-sort="Genre"> Genre </td>
      <td data-sort="Price"> Price </td>
    </tr>
    </thead>
    <tbody id="jlist" data-bind="template: {name: 'temp1', foreach: $data}"></tbody>
    </table>
  </div>
</div>

<div id="gdialog2" style="display:none;height:100px">
  <div id="jlist2" data-bind="template:'jcreateTemplate'"></div> 
  <div>
    <a href="#" data-jinsertaction>Insert</a>&nbsp;
    <a href="#" data-jcancelaction>Cancel</a>&nbsp;
  </div>
</div>

<div id="gdialog3" style="display:none;height:100px">
  <div id="jlist3" data-bind="template:'jmodifyTemplate'"></div> 
  <div>
    <a href="#" data-jupdateaction>Update</a>&nbsp;
    <a href="#" data-jcancelaction>Cancel</a>&nbsp;
  </div>
</div>

<br /><br />

<script id="temp1" type="text/html">
<tr>
  <td><a href="#" data-jdeleteaction>Delete</a></td>
  <td><a href="#" data-jmodifyaction>Modify</a></td>
  <td><span data-bind="text: Id" /></td>
  <td><span data-bind="text: Title" /></td>
  <td><span data-bind="text: AlbumArtUrl" /></td>
  <td><span data-bind="text: Artist.Name" /></td>
  <td><span data-bind="text: Genre.Name"  /></td>
  <td><span data-bind="text: Price" /></td>
</tr>
</script>

<script id="jcreateTemplate" type="text/x-jquery-tmpl">
@using (Html.BeginForm()) {
<div>
  <p>Create</p> 
  <p>
    <b>Id: </b>@Html.KoTextBoxStrFor(model => model.Id)<br>
    @Html.ValidationMessageFor(model => model.Id)
  </p>
  <p>
    <b>Title: </b>@Html.KoTextBoxStrFor(model => model.Title)<br>
    @Html.ValidationMessageFor(model => model.Title)
  </p> 
  <p>
    <b>AlbumArtUrl: </b>@Html.KoTextBoxStrFor(model => model.AlbumArtUrl)<br>
    @Html.ValidationMessageFor(model => model.AlbumArtUrl)
  </p> 
  <p>
    <b>Artist.Id: </b>@Html.KoTextBoxStrFor(model => model.Artist.Id)
    @Html.ValidationMessageFor(model => model.Artist.Id)
  </p>
  <p>
    <b>Artist.Name: </b>@Html.KoTextBoxStrFor(model => model.Artist.Name)
    @Html.ValidationMessageFor(model => model.Artist.Name)
  </p>
  <p>
    <b>Genre.Id:  </b>@Html.KoTextBoxStrFor(model => model.Genre.Id )
    @Html.ValidationMessageFor(model => model.Genre.Id )
  </p>
  <p>
    <b>Genre.Name: </b>@Html.KoTextBoxStrFor(model => model.Genre.Name)
    @Html.ValidationMessageFor(model => model.Genre.Name)
  </p>
  <p>
    <b>Price: </b>@Html.KoTextBoxStrFor(model => model.Price)
    @Html.ValidationMessageFor(model => model.Price)
  </p>
</div>
}
</script>

<script id="jmodifyTemplate" type="text/x-jquery-tmpl">
@using (Html.BeginForm()) {
<div> 
  <p>Modify</p>
 <p>
    <b>Id: </b>@Html.KoTextBoxStrFor(model => model.Id)<br>
    @Html.ValidationMessageFor(model => model.Id)
  </p>
  <p>
    <b>Title: </b>@Html.KoTextBoxStrFor(model => model.Title)<br>
    @Html.ValidationMessageFor(model => model.Title)
  </p> 
  <p>
    <b>AlbumArtUrl: </b>@Html.KoTextBoxStrFor(model => model.AlbumArtUrl)<br>
    @Html.ValidationMessageFor(model => model.AlbumArtUrl)
  </p> 
  <p>
    <b>Artist.Id: </b>@Html.KoTextBoxStrFor(model => model.Artist.Id)
    @Html.ValidationMessageFor(model => model.Artist.Id)
  </p>
  <p>
    <b>Artist.Name: </b>@Html.KoTextBoxStrFor(model => model.Artist.Name)
    @Html.ValidationMessageFor(model => model.Artist.Name)
  </p>
  <p>
    <b>Genre.Id:  </b>@Html.KoTextBoxStrFor(model => model.Genre.Id )
    @Html.ValidationMessageFor(model => model.Genre.Id )
  </p>
  <p>
    <b>Genre.Name: </b>@Html.KoTextBoxStrFor(model => model.Genre.Name)
    @Html.ValidationMessageFor(model => model.Genre.Name)
  </p>
  <p>
    <b>Price: </b>@Html.KoTextBoxStrFor(model => model.Price)
    @Html.ValidationMessageFor(model => model.Price)
  </p>
</div>
}
</script>

The page structure is the same as CRUD knockoutjs grid and MVVM pattern

$(document).ready(function () {
    var settings = {
      tpane1: 'gpane1',
      tpane2: 'gpane2',
      ttemplate: "jtableTemplate",
      tcontainer: "jlist",
      tformViewModel: function () {
          return {
            campo1: ko.observable(""),
            campo2: ko.observable("")
          };
      },
      tcreateViewModel: function () {
          return new createDataItem();
      },
      tcustomCallBack: function (obj) {
          customfrm(obj);
      },
      tdeleteCallBack: function (obj) {
          deletefrm(obj);
      },
      tinsertCallBack: function (obj) {
          insertfrm(obj);
      },
      tupdateCallBack: function (obj) {
          updatefrm(obj);
      },
      tcreatePanel: "gdialog2",
      tcreateContainer: "jlist2",
      tmodifyPanel: "gdialog3",
      tmodifyContainer: "jlist3",
      tknockoutValidation: true,
      tlinqEnabled: false,
      ttype: "2"
    };
    $("#gpane2").gridTemplate(settings, searchfrm).
         bind('databound', function (event) {
             //alert("databound");
         }
    );
});

function searchfrm(context) {
    context.clearSearch();

    var swhere = context.koWhereString();

    context.from("/Home/GetDataJson").pagingWithSize(10).where(swhere).
                    orderBy("Artist.Name").applyTempKo();
};

function createDataItem() {
    var that = this;
    this.Id = ko.observable("");
    this.Title = ko.observable("");
    this.AlbumArtUrl = ko.observable("");
    this.Artist = { Id: ko.observable(""), Name: ko.observable("") };
    this.Genre = { Id: ko.observable(""), Name: ko.observable("") };
    this.CountSold = ko.observable(0);
    this.Price = ko.observable(0);
};

function deletefrm(obj) {
    $.ajax({ url: "/Home/DeleteViewModel/", type: 'post',
        data: ko.toJSON(obj.dataitemJs),
        contentType: 'application/json',
        error: function (request, state, error) {
            alert("Ajax error:" + error);
        },
        success: function (result) {
            obj.context.refresh();
            alert("ok");
        }
    });
};

function insertfrm(obj) {
    $.ajax({ url: "/Home/InsertViewModel/", type: 'post',
        data: ko.toJSON(obj.dataitemJs),
        contentType: 'application/json',
        error: function (request, state, error) {
            obj.context.closeCreateDialogFeilure();
            alert("Ajax error:" + error);
        },
        success: function (result) {
            //obj.context.refresh();
            obj.context.closeCreateDialogSuccess();
            alert("ok");
        }
    });
};

function updatefrm(obj) {
    $.ajax({ url: "/Home/UpdateViewModel/", type: 'post',
        data: ko.toJSON(obj.dataitemJs),
        contentType: 'application/json',
        error: function (request, state, error) {
            obj.context.closeModifyDialogFeilure();
            alert("Ajax error:" + error);
        },
        success: function (result) {
            //obj.context.refresh();
            obj.context.closeModifyDialogSuccess();
            alert("ok");
        }
    });
};


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Raven.Client.Document;
using Raven.Client.Linq;
using JQueryLinq;

namespace MvcApplication1.Controllers
{
    public class HomeController : Controller
    {
        public HomeController() 
        {
      
        }
        
        public ActionResult Page()
        {
            List<Album> list = null;
            ViewBag.Message = "Page";
            return View(list);
        }

        [HttpPost]
        [OutputCache(Duration = 0, VaryByParam = "*")]
        public JsonResult InsertViewModel(Album doc)
        {
            var message = "";
            var documStore = HttpContext.Application["DocumentStore"] as DocumentStore;
            if (ModelState.IsValid == true)
            {
                try
                {
                    using (var session = documStore.OpenSession())
                    {
                        session.Store(doc);
                        session.SaveChanges();
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            return Json(message);
        }

        [HttpPost]
        [OutputCache(Duration = 0, VaryByParam = "*")]
        public JsonResult UpdateViewModel(Album doc)
        {
            var message = "";
            var documStore = HttpContext.Application["DocumentStore"] as DocumentStore;
            if (ModelState.IsValid == true)
            {
                try
                {
                    using (var session = documStore.OpenSession())
                    {
                        session.Store(doc);
                        session.SaveChanges();
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            return Json(message);
        }

        [HttpPost]
        [OutputCache(Duration = 0, VaryByParam = "*")]
        public JsonResult DeleteViewModel(Album doc)
        {
            var message = "";
            var documStore = HttpContext.Application["DocumentStore"] as DocumentStore;
            try
            {
                using (var session = documStore.OpenSession())
                {
                    var entity = session.Load<Album>(doc.Id);
                    session.Delete(entity);
                    session.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }         
            return Json(message);
        }
      
        [OutputCache(Duration = 0, VaryByParam = "*")]
        public ActionResult GetDataJson(RequestRest rest)
        {
            object result = null;
            rest.Operator = WhereOperator.And;
            rest.AddWhereMapping("Artist.Name", "=", "campo1");
            rest.AddWhereMapping("Genre.Name" , "=", "campo2");
            var documStore = HttpContext.Application["DocumentStore"] as DocumentStore;
            using (var session = documStore.OpenSession())
            {
                var query = session.Query<Album>();
                result = this.TryApplyView(rest, query.JQuery(rest));
            }
            return Json(result, JsonRequestBehavior.AllowGet);
        }  
    }
}


In this way you can create a MVC jquery knockoutjs grid with paging, filter and sort functions.

Classic page with knockout MVVM
jQuery mobile page with knockout MVVM
CRUD knockoutjs grid and MVVM pattern
jQuery mobile dynamic content with a knockoutjs template and MVC
Create a PhoneGap application using html5/javascript
How using RavenDB in a html5/javascript application
Knockoutjs and LINQ for JavaScript



Last edited Mar 17, 2012 at 7:53 PM by mastefano64, version 16

Comments

No comments yet.