jaydata indexedDb joined database - jaydata

I have created a sample database and test scripts with it.
The database structure is:
I have created a JSFiddle for it: fiddle
Click all the buttons except stress test on the top, then click the tests.
The problem is, it perfectly works with provider webSql, but it fails on the provider indexedDb. I downloaded the pro packages and it makes test 3 work partially but it still fails on test 2 completely.
The problem i found is when i query the database with join relation(ex: employees in with department.ID is 1) indexedDb cannot process this request.
How can circumvent this situation?
Whole code is:
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="jaydataPro/jaydata.min.js"></script>
<script src="jaydataPro/jaydataproviders/IndexedDbProProvider.min.js"></script>
<script src="jaydataPro/jaydataproviders/SqLiteProProvider.min.js"></script>
<script src="jaydataPro/jaydataproviders/WebApiProvider.min.js"></script>
<script src="jaydataPro/jaydataproviders/YQLProvider.min.js"></script>
<script src="sampledatabase.js"></script>
<script src="test.js"></script>
<title>Jaydata Test</title>
</head>
<body>
<div>
<h3>Database Generation</h3>
<div>
<button onclick="TestAddDepartments(5);">Add Departments</button>
</div>
<div>
<button onclick="AddEmployeeList(TestEmployeeList(1,100),1);"> Employees 1</button>
<button onclick="AddEmployeeList(TestEmployeeList(101,100),2);">Employees 2</button>
<button onclick="AddEmployeeList(TestEmployeeList(201,100),3);">Employees 3</button>
<button onclick="AddEmployeeList(TestEmployeeList(301,100),4);">Employees 4</button>
<button onclick="AddEmployeeList(TestEmployeeList(401,100),5);">Employees 5</button>
</div>
<div>
<button onclick="AddStockList(TestStockList(1,400),1);">
Stocks 1</button>
<button onclick="AddStockList(TestStockList(401,400),2);">
Stocks 2</button>
<button onclick="AddStockList(TestStockList(801,400),3);">
Stocks 3</button>
<button onclick="AddStockList(TestStockList(1201,400),4);">
Stocks 4</button>
<button onclick="AddStockList(TestStockList(1601,400),5);">
Stocks 5</button>
</div>
<div>
<button onclick="AddStockList(TestStockList(2001,5000),2);">
Stress Test for Test 3</button>
</div>
</div>
<div>
<h3>Queries</h3>
<button onclick="TestSearchEmployeeName1()">Test 1</button>
<button onclick="TestSearchEmployeeName2()">Test 2</button>
<button onclick="TestSearchEmployeeName3()">Test 3</button>
</div>
<div>
<h3>Results</h3>
<p id='Result'>Result</p>
</div>
</body>
</html>
sampledatabase.js:
/*
x is a database
Database name is Company
Company has 3 tables:
=Departments
-ID(key,computed)
-DepartmentName(string,required)
=Employees
-ID(key,computed)
-Name(string,required)
=Stocks
-ID(key,computed)
-Description(string)
-NumItems(int,required)
Employee is connected to Department
Stock is connected to Department
Department has a list of Stocks and Employees
To do:
-insert websql and indexeddb translations to the document
*/
$data.Entity.extend("Org.Employee",{
ID: {key: true, type: "integer", computed: true},
Name: {type: "string", required: true},
Department: {type: "Org.Department", inverseProperty: "Employees"}
});
$data.Entity.extend("Org.Stock",{
ID: {key: true, type: "integer", computed: true},
Description: {type: "string"},
NumItems: {type: "integer", required: true},
Department: {type: "Org.Department", inverseProperty: "Stocks"}
});
$data.Entity.extend("Org.Department",{
ID: {key: true, type: "integer", computed: true},
DepartmentName: {type: "string", required: true},
Employees:{type: Array, elementType: "Org.Employee", inverseProperty:"Department"},
Stocks:{type: Array, elementType: "Org.Stock", inverseProperty:"Department"}
});
$data.EntityContext.extend("Company",{
Employees: {type: $data.EntitySet, elementType: Org.Employee},
Departments: {type: $data.EntitySet, elementType: Org.Department},
Stocks: {type: $data.EntitySet, elementType: Org.Stock}
});
var x= new Company({
provider: "indexedDb",
databaseName: "DB",
version: 1,
dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables
});
function AddEmployee(emp,department)
{
x.Departments.first(
function(it){
return it.ID==department.valueOf()
},
{emp:emp,department:department},
function(dep){
x.Departments.attach(dep);
emp.Department=dep;
x.Employees.add(emp);
x.Employees.saveChanges();
}
);
}
function RemoveEmployee(emp_id)
{
x.Employees.first(
function(res){
return res.ID==emp_id.valueOf();
},
{emp_id:emp_id},
function(emp)
{
x.Employees.remove(emp);
x.Employees.saveChanges();
}
);
}
function ChangeEmployeeName(emp_id,new_name)
{
x.Employees.first(
function(res){
return res.ID==emp_id.valueOf();
},
{emp_id:emp_id,new_name:new_name},
function(emp)
{
x.Employees.attach(emp);
emp.Name=new_name;
x.Employees.saveChanges();
}
);
}
function RemoveDepartment(dep_id)
{
x.Employees.filter(
function(res){
return res.Department.ID==dep_id
},
{dep_id:dep_id}
).forEach(
function(it){
x.Employees.remove(it)
});
x.Employees.saveChanges();
x.Departments.first(
function(it)
{
return it.ID==dep_id;
},
{dep_id:dep_id},
function(dep)
{
x.Departments.remove(dep);
x.Departments.saveChanges();
}
);
}
function AddStock(stock,department)
{
x.Departments.first(
function(it){
return it.ID==department.valueOf()},
{emp:emp,department:department},
function(dep){
x.Departments.attach(dep);
stock.Department=dep;
x.Stocks.add(stock);
x.Stocks.saveChanges();
});
}
function AddEmployeeList(list,department)
{
x.Departments.first(
function(it){return it.ID==department.valueOf()},
{department:department,list:list},
function(dep){
for (var i = 0; i < list.length; i++) {
list[i].Department=dep;
};
x.Departments.attach(dep);
x.Employees.addMany(list);
x.Employees.saveChanges();
});
}
function AddStockList(list,department)
{
x.Departments.first(
function(it){return it.ID==department.valueOf()},
{department:department,list:list},
function(dep){
for (var i = 0; i < list.length; i++) {
list[i].Department=dep;
};
x.Departments.attach(dep);
x.Stocks.addMany(list);
x.Stocks.saveChanges();
});
}
test.js:
//testing script
function TestAddDepartments(number) //number of departments
{
var dep='Department';
for (var i = 1; i <= number.valueOf(); i++)
{
var temp=dep+i.toString();
x.Departments.add({DepartmentName:temp});
};
x.Departments.saveChanges();
}
function TestEmployeeList(start,number)
{
emp_list=new Array();
var emp='Employee';
for (var i = start.valueOf(); i < start.valueOf()+number.valueOf(); i++)
{
var temp=emp+i.toString();
emp_list.push({Name:temp});
};
return emp_list;
}
function TestStockList(start,number)
{
stock_list=new Array();
var stock='Stock';
for (var i = start.valueOf(); i < start.valueOf()+number.valueOf(); i++)
{
var temp=stock+i.toString();
var num=Math.floor((Math.random()*1000)+1);
stock_list.push({Description:temp,NumItems:num});
};
return stock_list;
}
/*function TestSearchEmployeeName(number,limit)
{
var start= new Date().getTime();
var emp='Employee';
for (var i = 1; i <= number.valueOf(); i++)
{
num=Math.floor((Math.random()*limit.valueOf())+1);
search=emp+num.toString();
x.Employees.filter(
function(res)
{
return res.Name==search;
}).
forEach(
function(it)
{
console.log(it.Name);
});
};
var elapsed=new Date().getTime()-start;
console.log("Searching the database with "+number.toString()+
" entries took "+elapsed.toString()+" milliseconds");
}
*/
//Static tests
function TestSearchEmployeeName1()
{
var start= new Date().getTime();
x.Employees.filter(
function(res)
{
return res.Name=='Employee43';
},{start:start}).
toArray(function(it){
var elapsed=new Date().getTime()-start;
var res="Query with "+it.length.toString()+" result took "+
elapsed.toString()+" milliseconds";
document.getElementById('Result').innerHTML = res;
},{start:start}
);
}
function TestSearchEmployeeName2()
{
var start= new Date().getTime();
x.Employees.filter(
function(res)
{
return res.Department.ID==1;
},{start:start}).
toArray(function(it){
var elapsed=new Date().getTime()-start;
var res="Query with "+it.length.toString()+" results took "+
elapsed.toString()+" milliseconds";
document.getElementById('Result').innerHTML = res;
},{start:start}
);
}
function TestSearchEmployeeName3()
{
var start= new Date().getTime();
x.Stocks.filter(
function(res)
{
return res.NumItems>258 || res.Department.ID<3;
},{start:start}).
toArray(function(it){
var elapsed=new Date().getTime()-start;
var res="Query with "+it.length.toString()+" results took "+
elapsed.toString()+" milliseconds";
document.getElementById('Result').innerHTML = res;
},{start:start}
);
}

According to the provider feature matrix, the include() and complex type mapping features aren't implemented yet for IndexedDB, this means you cannot have navigation properties in IndexedDB, only in SQLite/WebSQL.
You can propose this feature at the user voice page.

Related

Table sorted date not correct

Expected:
I'll get a datetime string from an API returned. This value "2019-08-15T15:58:14.597Z" should be displayed in a table as `DD-MM-YYYY HH:MM.
Vuetify comes with a data table component, that can sort the data ascending and descending. I also want to use this functionality for the date, to make it sort ascending and descending.
Short question: The date from the API should be saved and displayed in another "style" in the table, but the sort-functionality uses the real date object.
My current code:
<template>
<v-content class="mt-12 ml-12">
<h1 class="font-weight-black display-3">Servers</h1>
<v-data-table
class="elevation-1"
:headers="headers"
:items="columns"
:items-per-page="15"
>
</v-data-table>
<ul id="example-1">
<li v-for="(data, index) in columns.data" :key="index">
{{ data.attributes }}
</li>
</ul>
</v-content>
</template>
<script>
import instances from '../services/instances';
export default {
data() {
return {
columns: [],
headers: [
{ text: 'Server Name', value: 'attributes.name' },
{ text: 'Spieler', value: 'attributes.playerCount' },
{ text: 'Avg. FPS', value: 'attributes.details.rust_fps_avg' },
{ text: 'Wiped', value: 'attributes.details.rust_last_wipe' },
],
};
},
async created() {
const { data } = await instances.createInstance();
this.columns = data.data;
this.columns.forEach((entry) => {
const { players, maxPlayers } = entry.attributes;
entry.attributes.playerCount = `${players} / ${maxPlayers}`;
const { rust_last_wipe } = entry.attributes.details;
const mmmm = new Date(entry.attributes.details.rust_last_wipe);
entry.attributes.details.rust_last_wipe = `${mmmm.getDate()}.${mmmm.getMonth() + 1}.${mmmm.getFullYear()}`;
});
console.log(this.columns);
},
};
</script>
In this documentation there is a way to customize the columns content
Based on it we can do:
<template>
<v-content class="mt-12 ml-12">
<h1 class="font-weight-black display-3">Servers</h1>
<v-data-table
class="elevation-1"
:headers="headers"
:items="columns"
:items-per-page="15"
>
<template v-slot:item.attributes.details.rust_last_wipe="{ item }">
<span>{{ item.attributes.details.rust_last_wipe_formatted }}</span>
</template>
</v-data-table>
<ul id="example-1">
<li v-for="(data, index) in columns.data" :key="index">
{{ data.attributes }}
</li>
</ul>
</v-content>
</template>
<script>
import instances from '../services/instances'
export default {
data() {
return {
columns: [],
headers: [
{ text: 'Server Name', value: 'attributes.name' },
{ text: 'Spieler', value: 'attributes.playerCount' },
{ text: 'Avg. FPS', value: 'attributes.details.rust_fps_avg' },
{ text: 'Wiped', value: 'attributes.details.rust_last_wipe' }
]
}
},
async created() {
const { data } = await instances.createInstance()
this.columns = data.data
this.columns.forEach(entry => {
const { players, maxPlayers } = entry.attributes
entry.attributes.playerCount = `${players} / ${maxPlayers}`
const { rust_last_wipe } = entry.attributes.details
const mmmm = new Date(entry.attributes.details.rust_last_wipe)
entry.attributes.details.rust_last_wipe_formatted = `${mmmm.getDate()}.${mmmm.getMonth() + 1}.${mmmm.getFullYear()}`
})
console.log(this.columns)
}
}
</script>

populate select with datajson using React js

I'm trying to populate a select using React js, I'm using the example given on the react js docs(https://facebook.github.io/react/tips/initial-ajax.html) , which uses jquery to manage the ajax calling, I'm not able to make it work, so far i have this:
here the codepen : http://codepen.io/parlop/pen/jrXOWB
//json file called from source : [{"companycase_id":"CTSPROD","name":"CTS-Production"},{"companyc ase_id":"CTSTESTING","name":"CTS-Testing"}]
//using jquery to make a ajax call
var App = React.createClass({
getInitialState: function() {
return {
opts:[]
};
},
componentDidMount: function() {
var source="https://api.myjson.com/bins/3dbn8";
this.serverRequest = $.get(source, function (result) {
var arrTen = result[''];
for (var k = 0; k < ten.length; k++) {
arrTen.push(<option key={opts[k]} value={ten[k].companycase_id}> {ten[k].name} </option>);
}
}.bind(this));
},
componentWillUnmount: function() {
this.serverRequest.abort();
},
render: function() {
return (
<div>
<select id='select1'>
{this.state.opts}
</select>
</div>
);
}
});
ReactDOM.render(
<App />,
document.getElementById('root')
);
html
<div id="root"></div>
any idea how to make it works, thanks.
You need to call setState to actually update your view. Here's a workable version.
//json file called from source : [{"companycase_id":"CTSPROD","name":"CTS-Production"},{"companyc ase_id":"CTSTESTING","name":"CTS-Testing"}]
//using jquery to make a ajax call
var App = React.createClass({
getInitialState: function() {
return {
opts:[]
};
},
componentDidMount: function() {
var source="https://api.myjson.com/bins/3dbn8";
this.serverRequest = $.get(source, function (result) {
var arrTen = [];
for (var k = 0; k < result.length; k++) {
arrTen.push(<option key={result[k].companycase_id} value={result[k].companycase_id}> {result[k].name} </option>);
}
this.setState({
opts: arrTen
});
}.bind(this));
},
componentWillUnmount: function() {
this.serverRequest.abort();
},
render: function() {
return (
<div>
<select id='select1'>
{this.state.opts}
</select>
</div>
);
}
});
ReactDOM.render(
<App />,
document.getElementById('root')
);

Update vuejs model value using jquery-chosen plugin

Trying to use jquery-chosen with vue, the problem is that this plugin hides the actual select that I applied v-model, so when I select a value vue doesn't recognize it as a select change event and model value is not updated.
The value of the select is being changed actually when I select something, I've inspected this with console.log to see the selected value.
http://jsfiddle.net/qfy6s9Lj/3/
I could do vm.$data.city = $('.cs-select').val(), that seems to work,
But is there another option? If the value of the select was changed why vue doesn't see this?
#swift's answer got pretty close, but as #bertrand pointed out, it doesn't work for multiselects. I've worked something out that works with both cases: http://jsfiddle.net/seanwash/sz8s99xx/
I would have just commented but I don't have enough rep to do so.
Vue.directive('chosen', {
twoWay: true, // note the two-way binding
bind: function () {
$(this.el)
.chosen({
inherit_select_classes: true,
width: '30%',
disable_search_threshold: 999
})
.change(function(ev) {
// two-way set
// Construct array of selected options
var i, len, option, ref;
var values = [];
ref = this.el.selectedOptions;
for (i = 0, len = ref.length; i < len; i++) {
option = ref[i];
values.push(option.value)
}
this.set(values);
}.bind(this));
},
update: function(nv, ov) {
// note that we have to notify chosen about update
$(this.el).trigger("chosen:updated");
}
});
var vm = new Vue({
data: {
city: 'Toronto',
cities: [{text: 'Toronto', value: 'Toronto'},
{text: 'Orleans', value: 'Orleans'}]
}
}).$mount("#search-results");
I am opened for other suggestions, but for the time-being I did it this way:
html
<div id='search-results'>
{{city}}
<select class="cs-select" v-model='city'>
<option value="Toronto">Toronto</option>
<option value="Orleans">Orleans</option>
</select>
</div>
js
window.vm = new Vue({
el: '#search-results',
data: {
city: 'Toronto',
}
})
$('.cs-select').chosen({
inherit_select_classes: true,
width: '30%'
}).change( function() {
vm.$data.city = $('.cs-select').val()
})
Update: Be advised this doesn't work from within a v-for loop. A related question that deals with that is available here.
Going off of #kaktuspalme's solution, and with help from my friend Joe Fleming, I came up with a solution that works with Vue 2 and allows single and multiple selections:
Vue.directive('chosen', {
inserted: function(el, binding, vnode) {
jQuery(el).chosen().change(function(event, change) {
if (Array.isArray(binding.value)) {
var selected = binding.value;
if (change.hasOwnProperty('selected')) {
selected.push(change.selected);
} else {
selected.splice(selected.indexOf(change.deselected), 1);
}
} else {
var keys = binding.expression.split('.');
var pointer = vnode.context;
while (keys.length > 1)
pointer = pointer[keys.shift()];
pointer[keys[0]] = change.selected;
}
});
},
componentUpdated: function(el, binding) {
jQuery(el).trigger("chosen:updated");
}
});
Use it like this:
<select v-model="mymodel" v-chosen="mymodel">...</select>
It works with multiple="multiple" and even with nested state, e.g.:
<select v-model="nested.mymodel" v-chosen="nested.mymodel">...</select>
See the fiddle here: https://jsfiddle.net/tylercollier/bvvvgyp0/5/
Answer:
http://jsfiddle.net/qfy6s9Lj/5/
<div id='search-results'>
Vue model value <br>
{{city}}
<hr>
Select value:
<select class="cs-select" v-chosen>
<option value="Toronto">Toronto</option>
<option value="Orleans">Orleans</option>
</select>
</div>
Vue.directive('chosen', {
bind: function () {
var vm = this.vm;
this.el.options = vm.cities;
this.el.value = vm.city;
$(this.el).chosen({
inherit_select_classes: true,
width: '30%',
disable_search_threshold: 999})
.change( function() {
vm.city = this.el.value;
}.bind(this)
);
}
});
var vm = new Vue({
data: {
city: 'Toronto',
cities: ['Toronto', 'Orleans']
}
}).$mount("#search-results");
UPDATE: an even better solution (thanks to simplesmiler):
http://jsfiddle.net/simplesmiler/qfy6s9Lj/8/
I made an update for vue2.
Vue.directive('chosen', {
selected: null,
inserted: function (el, binding) {
selected = binding.value;
$(el).chosen().change(function(event, change) {
if(change.hasOwnProperty('selected')) {
selected.push(change.selected);
} else {
selected.splice(selected.indexOf(change.deselected), 1);
}
});
},
componentUpdated: function(el, binding) {
selected = binding.value;
$(el).trigger("chosen:updated");
}
});
var vm = new Vue({
el: '#app',
data: {
selected: [],
cities: [{id: 1, value: "Toronto"}, {id: 2, value: "Orleans"}, {id: 3, value: "Bern"}]
}
});
See: https://jsfiddle.net/kaktuspalme/zenksm2b/
Code taken from #kaktuspalme answer. It works with non-multiple elements now and only for non-multiple.
Vue.directive('chosensingle', {
inserted: function (el, binding) {
var selected = binding.value;
$(el).chosen().change(function(event, change) {
if(change.hasOwnProperty('selected')) {
selected.value = change.selected;
} else {
selected.value ='';
}
});
},
componentUpdated: function(el, binding) {
$(el).trigger("chosen:updated");
}
});
Comments from #Tyler Collier are taken into account
But be carefully,property you use in v-model should be defined as array , e.g. applicantId: [] otherwise it doesn't work

bootstrap typeahead url/redirect

$(function(){
var orthoObjs = {};
var orthoNames = [];
var throttledRequest = _.debounce(function(query, process){
$.ajax({
url: 'json/ortho4.json'
,cache: false
,success: function(data){
orthoObjs = {};
orthoNames = [];
_.each( data, function(item, ix, list){
orthoNames.push( item.searchPhr );
orthoObjs[ item.searchPhr ] = item;
});
process( orthoNames );
}
});
}, 300);
$(".typeahead").typeahead({
source: function ( query, process ) {
throttledRequest( query, process );
}
,updater: function (item) {
var url = "orthoObjs[item.searchUrl]";
window.location = url;
Whats the best way to get the redirect to work? I have seen similar questions, but can't get this to work. Documentation on typeahead isn't great. I am using underscore.js for the each function. Just want a simple search query that redirects when the user selects.
I actually got this to work. I got a little help... but here it is. There is the JSON file..
[
{ "id":1, "searchUrl":"invisalign.html", "name":"invisalign" }
,{ "id":2, "searchUrl":"invisalign.html", "name":"invisalign teen" }
,{ "id":3, "searchUrl":"clearbraces.html", "name":"clear braces" }
]
And the HTML code....
Lots of good stuff here.. http://fusiongrokker.com/post/heavily-customizing-a-bootstrap-typeahead
And the search code..
<form method="post" id="myForm" class="navbar-search pull-left">
<input
type="text"
class="search-query typeahead"
placeholder="Search Our Website"
autocomplete="off"
data-provide="typeahead"
/>
<i class="fa-icon-search icon-black"></i>
</form> </li>
$(function(){
var bondObjs = {};
var bondNames = [];
$(".typeahead").typeahead({
source: function ( query, process ) {
//get the data to populate the typeahead (plus an id value)
$.ajax({
url: '/json/bonds.json'
,cache: false
,success: function(data){
bondObjs = {};
bondNames = [];
_.each( data, function(item, ix, list){
bondNames.push( item.name );
bondObjs[ item.name ] = item.searchUrl;
});
process( bondNames );
}
});
}
, updater: function ( selectedName ) {
window.location.href =bondObjs[ selectedName ];
}
});
});
</script>

kendo mvvm not updating after ajax call

I have a page (relevant code below) which carries out the following :
User enters a value into an auto-complete text box
2, Upon selecting an auto complete option, an ajax call is made in order to fill 2 dropdownlists
User is required to select a value from each dropdownlist
Once a value has been selected on both, they click on the add button and my bound table is updated
User can remove rows added to the table
The rows added in step 4 are contained in an array in the observable object.
The first time the page loads points 1 to 5 work as expected.....
However, if the user enters a new search into the auto-complete box and fires the select event, the second time the ajax call is made, the relationship between my viewmodel and UI objects are broken.
The code which is executing is identical so please could someone shed some light on why the second time around this breaks.
<input type="text" id="txtBox" style="width:300px;" />
<div id="fixturesBindable" style="padding:0 !Important;">
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
</tr>
</thead>
<tbody data-template="row-template" data-bind="source: Fixtures"></tbody>
</table>
<select id="a_teamsdropdown" data-role="dropdownlist" data-text-field="TeamFullName" data-value-field="Id" data-bind="source: Teams" style="width:200px;"></select>
<select id="a_oppteamsdropdown" data-role="dropdownlist" data-text-field="TeamFullName" data-value-field="Id" data-bind="source:
OpponentTeams" style="width:200px;"></select>
<button type="button" data-bind="click: addFixture">Add Fixture</button>
<script id="row-template" type="text/x-kendo-template">
<tr>
<td><input type="hidden" id="team" data-bind="attr: { name: TeamModelName, value: TeamId }" /></td>
<td><input type="hidden" id="oppteam" data-bind="attr: { name: OppModelName, value: OppTeamId }" /></td>
</tr>
</script>
</div>
<script>
$(document).ready(function () {
var viewModel = kendo.observable({
Teams: <%= Model.Teams %>,
OpponentTeams: [],
Fixtures: [],
addFixture: function (e) {
var Fixtures = this.get("Fixtures");
var teamId = $("#a_teamsdropdown").val();
var teamName = $("#a_teamsdropdown>option:selected").text();
var oppteamId = $("#a_oppteamsdropdown").val();
var oppteamName = $("#a_oppteamsdropdown>option:selected").text();
this.get("Fixtures").push({
TeamFullName: teamName,
TeamId: teamId,
OppTeamFullName: oppteamName,
OppTeamId: oppteamId,
OrderIndex: this.get("Fixtures").length,
TeamModelName: 'Fixtures[' + this.get("Fixtures").length + '].TeamId',
OppModelName: 'Fixtures[' + this.get("Fixtures").length + '].OpponentTeamId'
});
},
resetFixture: function(){
var Fixtures = this.get("Fixtures");
$.each(Fixtures, function (key, fixture) {
Fixtures.splice(0, 1);
});
}
});
opponents = $("#txtBox").kendoAutoComplete({
minLength: 3,
dataTextField: "Name",
filter: "contains",
dataSource: new kendo.data.DataSource({
transport: {
read: {
url: "/url/Ajax",
type: "POST",
data: function () { return { searchText: $("#txtBox").val()}
},
complete: function (data) {
opponents.list.width(400);
}
}
},
pageSize: 10,
serverPaging: true,
serverSorting: true,
schema: {
total: "count",
data: "data",
model: {
id: "Id",
fields: {
Id: { editable: false }
}
}
}
}),
change: function () {
this.dataSource.read();
},
select: function (e) {
$.each(opponents.dataSource.data(), function (index, value) {
if (e.item.text() == value.Name) {
selectedOpponent = value;
$('#Fixture_OpponentTeam_Id').val(selectedOpponent.Id);
$('#OpponentName').val(selectedOpponent.Name);
$.ajax({
url: 'GetOpponentTeams',
data: { schoolId: selectedOpponent.Id, seasonId: seasonId, sportId: sportsId },
type: 'GET',
success: function (data) {
viewModel.OpponentTeams = data;
kendo.bind($("#fixturesBindable"), viewModel);
},
error: function (xhr, ajaxOptions, thrownError) {
//alert('Error during process: \n' + xhr.responseText);
alert(thrownError);
}
});
return;
}
});
}
}).data("kendoAutoComplete");
</script>
Not sure if this will fix your issue or not, but in general I would advise against re-binding everything in your ajax success callback. If you just .set("OpponentTeams") instead of assigning the value directly, does that help?
success: function (data) {
viewModel.set("OpponentTeams", data);
},
The call to .set() should trigger a refresh of the #a_oppteamsdropdown element.