• OData first steps

    Get first-hand experience with the OData standard using JayData, create an online-offline Northwind product manager app with WebSQL/IndexedDB synchronization.

    Learn more
  • Are You a Pro?

    Then use JayData Pro for your professional needs! Now with new providers like IndexedDB Pro and SQlite Pro. You're going to love extra features likes transactions, online/offline sync and indexis.

    Learn more
  • Go
    serverside!

    Use your JayData skills to work with data in the cloud. Explore JayStorm, your cloudbased enviroment to build REST data services with JavaScript.

    Get your free app now* * No credit card required
  • Watch Webinars online!

    If you want to get familiar with JayData and JayStorm in the fastest and easiest way it's your thing to check out. Subscribe for the upcoming webinars!

    Watch free webinars

Latest release


JayData 1.3.6

Our new release is available at CodePlex and includes the following features:

  • Easy online-offline data sync for locally changed entities
  • Configurable foreign keys
Release notes

Get Support

Working on a project with JayData?
Need some advice? Need to meet some crazy deadlines and you need some help? Contact the JayData team and get some expert support here!

Learn more

JayData
Northwind Product Editor

JayData oData provider in action. See how easy to create a simple HTML5 based CRUD application from the Northwind database.

More videos

Understand JayData in 7 simple steps

Step 1 - Initialize resources

Initialize your resource like stylesheets, scripts and so on.

<script src="http://include.jaydata.org/jaydata.js"></script>
<script src="http://include.jaydata.org/datajs-1.0.3.js"></script>
<script src="http://include.jaydata.org/jaydata.js"></script>
<script src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://include.jaydata.org/jaydata.js"></script>
<script src="http://include.jaydata.org/knockout-2.1.0.js"></script>
<script src="http://include.jaydata.org/jaydata.js"></script>
<script src="http://include.jaydata.org/jaydatamodules/knockout.js"></script>
<script src="http://cdn.kendostatic.com/2012.2.710/js/kendo.all.min.js"></script>
<script src="http://include.jaydata.org/jaydata.js"></script<>
<script src="http://include.jaydata.org/jaydatamodules/kendo.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.rc.1/handlebars.js"></script>
<script src="http://include.jaydata.org/jaydata.js"></script<>
<script src="http://include.jaydata.org/jaydatamodules/handlebars.js"></script>

Step 2 - Define data model

Simple model that works online and offline as well.
Define your data model:

$data.Entity.extend("Todo", {
    Id: { type: "int", key: true, computed: true },
    Task: { type: String, required: true, maxLength: 200 },
    DueDate: { type: Date },
    Completed: { type: Boolean }
});

$data.EntityContext.extend("TodoDatabase", {
    Todos: { type: $data.EntitySet, elementType: Todo }
});

The local item store provides an automatic client storage facitlity for every entity type.
Just define your model type and the rest is handled by the library:

$data.Entity.extend("Todo", {
    Id: { type: "int", key: true, computed: true },
    Task: { type: String, required: true, maxLength: 200 },
    DueDate: { type: Date },
    Completed: { type: Boolean }
});

Model types an have relationships to enforce referencial integrity

$data.Entity.extend("Todo", {
    Id: { type: "int", key: true, computed: true },
    Task: { type: String, required: true, maxLength: 200 },
    DueDate: { type: Date },
    Completed: { type: Boolean },
    Person: { type: "Person", required: true, inverseProperty: "Todos"}
});

$data.Entity.extend("Person", {
    Id: { type: "int", key: true, computed: true },
    Name: { type: String, required: true, maxLength: 200 },
    Todos: { type: Array, elementType: Todo, inverseProperty: "Person" }
});

$data.EntityContext.extend("TodoDatabase", {
    Todos: { type: $data.EntitySet, elementType: Todo },
    People: { type: $data.EntitySet, elementType: Person }
});

Model entities can have complex properties that are entities themselves

$data.Entity.extend("Location", {
    City: { type: String },
    Country: { type: String }
});
$data.Entity.extend("Todo", {
    Id: { type: "int", key: true, computed: true },
    Task: { type: String, required: true, maxLength: 200 },
    DueDate: { type: Date },
    Completed: { type: Boolean },
    Location: { type: Location }
});

$data.EntityContext.extend("TodoDatabase", {
    Todos: { type: $data.EntitySet, elementType: Todo }
});

Step 3 - Initialize the data storage

var todoDB = new TodoDatabase("MyTodoDatase");

todoDB.onReady(function() {
    //Work with todoDB now
});
var todoDB = new TodoDatabase({ 
    provider: 'webSql', databaseName: 'MyTodoDatabase'
});

todoDB.onReady(function() {
    //Work with todoDB now
});
var todoDB = new TodoDatabase({ 
    provider: 'indexedDb', databaseName: 'MyTodoDatabase'
});

todoDB.onReady(function() {
    //Work with todoDB now
});
var todoDB = new TodoDatabase('http://mysite/myapi');

todoDB.onReady(function() {
    //Work with todoDB now
});
$data.service('http://yourserviceurl.com', function(factory, contextType){
    var service = factory();
    service.onReady(function() {
        //work with your JayStorm PaaS data and services - http://jaystack.com
    });
});
var todoDB = new TodoDatabase({ 
    provider: 'mongoDB' , databaseName: 'MyTodoDatabase' 
});

todoDB.onReady(function() {
    //Work with todoDB now
});
var todoDB = new TodoDatabase({
    provider: 'sqLite' , databaseName: 'MyTodoDatabase'
});

todoDB.onReady(function() {
    //Work with todoDB now
});

Step 4 - Create data

//Create
var tasks = todoDB.Todos.addMany([
    { Task: 'Step0: Get this this list', Completed: true },
    { Task: 'Step1: Define your data model'},
    { Task: 'Step2: Initialize data storage'}
]);
todoDB.saveChanges(function() {
    tasks.forEach( function(todo) { alert(todo.Id) });
});
//Create with types
var todo = new Todo();
todo.Task = "Step4: create entity";
todo.DueDate = new Date();
todoDB.add(todo);
todoDB.saveChanges().then(function() { alert("done!"); });
//Create using ItemStore API

$data('Todo').save({ Task: 'Step3: advanced'})
.then(function(newItem){
    alert(newItem.Id);
});
//Create related data
todoDB.Todos.add({ 
    Task: "Your task", 
    Person: new Person({Name: 'Peter'});
});
todoDB.saveChanges();
//Retrieve the existing item by Id and attach to the context to track changes
var todo = todoDB.Todos.attachOrGet({ Id:1}); 
todo.Completed = true;
todoDB.saveChanges();

Step 5 - Query data

//Filter #1
todoDB.Todos
        .filter( function(todo) {
            return todo.Completed == true ||
                    todo.Task.startsWith("Step2")
        })
        .forEach( function(todo) {
            yourTemplate.render(todo); 
        });
//Filter #2
todoDB.Todos
        .filter("it.Completed || it.Task.startsWith('Step2')")
        .forEach( function(todo) {
            yourTemplate.render(todo); 
        });
//Use TypeScript
todoDB.Todos
        .filter(todo => todo.Completed == true)
        .map(todo => todo.Task )
        .forEach(taskName => $('#list')
        .append('Task: ' + taskName + ' completed'));
//Filter on relations
todoDB.Todos
        .filter("it.Person.Name == 'Peter'")
        .toArray( function(todos) { });
//Ordering and shaping
todoDB.Todos
        .orderBy("it.DueDate")
        .map(function(todo) { return todo.Task })
        .toArray(function(taskNameArray) { });

Step 6 - Remove

//Simple remove
todoDB.Todos.remove(todo);
todoDB.saveChanges();
//Remove in batch
todoDB.Todos
        .removeAll();
//Remove with query
todoDB.Todos
        .filter("it.Completed == true")
        .removeAll(function() {
            alert("items removed");
        });

Step 7 - Generate some UI

//UI with jQuery
todoDB.Todos
        .include("Person")
        .forEach(function(todo) {
            $('#todos')
                .append('<li>' + todo.Task + ',' + todo.Person.Name + '</li>');
        });
//UI with Knockout
function viewModel() {
    var self = this;
    self.todos = ko.observableArray();
    todoDB.Todos
            .include("Person")
            .toArray(self.todos);
}
ko.applyBindings(new viewModel());
//UI with Kendo UI

$("#chart").kendoChart({
    dataSource: todoDB.Todos
        .orderByDescending('it.DueDate')
        .take(10)
        .asKendoDataSource()
});
//UI with Handlebars.js
$data("Todo")
        .query('it.Id > 3')
    .then($data.renderItemsTo("#todoList","<li>{{Task}}</li>"));

Key features

Extended support for Visual Studio JavaScript Intellisense

Designed to make full use of Visual Studio JavaScript IntelliSense to provide the best developer experience

JavaScript Language Query (JSLQ)

JSLQ brings the philosophy of Entity Framework and LINQ from the .NET platform to the world of JavaScript

Cross-device & cross-layer paradigm

Experience the true power of JavaScript, run your code on mobile devices, in web browsers or on a NodeJS serverside

Built on HTML5 standards

Build full-featured applications powered by HTML5, capitalize on your expertise as a web developer!

What is JayData?

JayData is a standards-based, cross-platform Javascript library and a set of practices to access and manipulate data from various online and offline sources.

How it works

You can use the out-of-box JayData provider to access Windows Azure store, LocalStore, IndexedDb or Facebook data from JavaScript. 

JayStorm

The world's first platform as a service for JavaScript Business Apps! JayStack provides a set of products and services that can help you thrive in the cross-platform, cross-device era.

UI Libraries

Javascript Language Query

dbcontext
            .Products
            .filter(function (p) {
                return p.Category.ID == 42
            }).skip(10).take(5)
            .toArray();

Simple CRUD

var product = new Northwind.Product({
            ProductName: 'Lady Gray Tea',
            Cateogory : new Northwind.Category('Teas')
        });
        Northwind.Products.add(product);
        Northwind.saveChanges();