Kendo multiselect populate previously selected items using odata with paging. (AngularJS) - angularjs

I'm using the kendo MultiSelect with odata paging and using the angularJS integration. Populating the data from scratch works great. When I want to re-populate the data from initial data then I seem to have a problem.
Cause of the problem:
The data only gets populate from the initial or previous dataset. So, if I the paging size is 10 then only products that exist in the first page will be displayed as normal. All product that don't fall within the first page will just not be displayed.
Possible workarounds:
Increase the page size. I have used this on other pages where the results are quite small. However this is not a realistic work around as we are expecting much bigger datasets in the future ( hence using odata in the first place)
Was thinking we could possibly do some sort of initial sorting. However this could also be slow and could still be a problem if there were more items selected than exist in the first page.
Ideal solution
Is there a way to tell kendo component to load all data based on current value? This will then build the required odata call and populate the component.
Example of the current issue:
http://dojo.telerik.com/ODaLe/2

I worked 2-4 hours to find a solution for this. Dunno if yall would like it, but it might help somebody, so I'd type it here. Following are the steps:
Step 1: Create the data source
First, setup the dataSource object which you would be using for reading remote data (for offline data, improvise by reading the API).
var dataSource = new kendo.data.DataSource({
dataType: "jsonp",
transport: {
read: {
url: options.source,
type: 'POST'
},
},
serverFiltering: true
});
Step 2: Load the selected items
This can be tricky as you need to have the selected item IDs on the client side. For me, I did it by adding a data-options-selected="1;3;9" attribute to my select element. Later, in my JavaScript, I split this attribute by ";" and retrieve an array of selected IDs. Lets say these values are in var valuesArray;
Once we have an array of selected IDs, we need to read them from the data-source. In my case, it was remote, so I ran a dataSource.read() with filters as under:
dataSource.read({
filter: {
logic: 'and',
filters: [
{
field: options.dataValueField,
operator: 'equals',
value: options.value
}
]
}
});
On the server side, this should return an array containing the items having the given identifiers. Thus, we now have those items on the client-side as well.
Step 3: Set values for the widget
Now that the value related data is loaded, we can set the values for the widget using the values() method. Here, $el is the jQuery object representing the select element which I was using for multiSelect.
var oWidget = $el.data('kendoMultiSelect');
oWidget.value(valuesArray);
That's it! One multiselect widget pre-loaded with values, ready to rock and roll. Served my purpose. Dunno if any short-cuts exist.

When using Kendo with Angular, you want to use the k-rebind attribute to refresh the pulldown options + update the picker with the values in your $scope.countries object when it changes.
If you want like the picker to update when $scope.products changes as well, you can initialize the picker using a k-options attr pointed to an object in your controller, and set the k-rebind to that object.
This kendo tutorial provides a useful example, also using odata paging.
http://docs.telerik.com/kendo-ui/web/multiselect/how-to/AngularJS/pre-select-items

Related

ExtJs remote (list) filter reset

I have an issue with Extjs remote filter that I excpect you could help to clarify.
I've created a grid with a remote filter that works great, but if I update the grid info, the filter keeps the previous loaded data.
I've tried everything: store.doDestroy, store.removeAll, even assign a new store to the var with Ex.create, but I didn't succeed.
I've created a Fiddle to try to reproduce my issue:
First load default info (Simpsons)
Then open the 'Hobbie' filter (Simulates a select distinct). You get Jazz, Skate, Beer and Knit.
After that, update the grid data (Switch to Van Houtens)
Finally, try to get Van Houtens hobbies (Videogames, Margaritas and None), but you get Simpsons Hobbies (Jazz, Skate..), cause the filter was previously loaded. (Notice how there was not a loading mask).
Now restart the test skipping step 2 (and 5 to avoid infinite loop XD) and notice how the right hobbies are shown.
I need to 'reset' that previous store load.
Notes:
If I just do a store.load, the request is triggered, but the returned values are not bound to the filter list.
If try to bind the store with this bind:{store:'{filterStore}'}, noting happens
You just need to "rebind" the filters for each column like this:
var grid = this.up('grid');
//Clear the current filters before changing
grid.getPlugins()[0].clearFilters();
var store = grid.getStore();
setStoreFilter(store, 'Van Houten');
//Setting the store filters is not enough
setStoreFilter(filterStore, 'Van Houten');
setStoreFilter(hobbiesStore, 'Van Houten');
//You need to "rebind" the store, it needs a little delay to work properly
setTimeout(function(){ grid.getColumns()[3].filter.bindMenuStore(hobbiesStore); }, 1000);
Here is the updated FIDDLE

Query unrendered components

What is the best way to query unrendered components? I tried to query them as always using .query( '[group=abc]' ).
However this time, the components, having each group: abc, are not yet rendered, since they are used in an editable grid (first click it).
What I am trying to do is:
get data via Ajax for comboboxes
create an unknown number of comboboxes
put that Ajax data into each combobox
Problem: I want that boxes to be filled with the data on Ajax success
loading the data on Ajax success answer fails since I am missing a method to get my comboboxes via the property group=abc
loading the data on combobox creation fails too, since the Ajax success answer is not yet back
You will not be able to use ComponentQuery for unrendered components. You best bet is probably your last list item: Load the data into the combo stores when the combos are created. The key will be to mask the action that creates the combos (is this a grid row editor or something like that?) until the Ajax call is complete.
myComponent.setLoading(true);
Ext.Ajax.request({
//your request info here
success: function() {
//now unmask your component, allowing your combos to be created:
myComponent.setLoading(false);
//do other stuff here
}
});

How to find Table and append a new record to its Store?

I need to update a Store based on some information that I have.
I have a table in the document, that uses some Store to keep data,
and in separate part of page I have a button that needs to add some information to the Store (and table). I got a bit confused, so, I just ask here all I need to know:
Which property in table configuration needs to be specified to locate table later?
Which call I need to make to find the table and locate its store?
How I can generate and append data to the table's existing store?
The "table" you are referring to is Grid in ExtJS terminology.
1. To get the grid for later use, you need a reference to that object. There are many ways in ExtJS to get hold of this reference.
Using Javascript Variables: Most simple way is to have a javascript variable that will hold the reference. This is usually done when the grid is created. For example:
var myGrid = Ext.create('Ext.grid.Panel', {
// All the configs...
});
You can use the myGrid variable to get access to the grid.
Using ComponentManager: When an ExtJS component is created, it gets registered with the component manager. You can always get hold of an ExtJS component from this register. The manager tracks each component with a unique id. To use this method, you will have to define a unique id for your grid component and later use the famous Ext.getCmp() method. Here is an example:
var myGrid = Ext.create('Ext.grid.Panel', {
id: 'myGrid', // Unique id for the grid
// All other configs...
});
Using this method is NOT the best practice.
Using itemId and Component Query: A better method than the above two; you can use the itemId config and ComponentQuery. ComponentQuery class provides a selector-based searching for Sencha Components analogous to DOM querying. Example:
var myGrid = Ext.create('Ext.grid.Panel', {
itemId: 'myGrid',
// All other configs...
});
And to get a reference, you may call the query() method from a container or use Ext.ComponentManager (this is global).
Accessing in MVC controller: If you are developing your application using MVC, you can make use of this method. A controller have reference array namely: refs. (Internally, the method makes use of ComponentQuery and selectors to access the component). Refer MVC guides and examples to see how this works..
2. Once you obtain the grid with any the above techniques, you can get the store simply by calling the method: getStore(). This returns the store object (Ext.data.Store). Example:
myStore = myGrid.getStore();
3. Refer the Ext.data.Store documentation. you can manipulate your grid's store using methods like add(),load(),remove() etc...
FYI.
It is not
Ext.Cmp()
it is
Ext.getCmp('myGrid')

Issue with Extjs 3.2 grid paging not working

I have multiple store on my page to load data in extjs grid. I am using a js function to load these store. Based on the search button click event I attach the respective store to the grid. Its working fine. In the load function I have lots of params that I need to send to the backend to fetch the results and show in the grid. Now with pagination in place. Is there anyway that I can add that js function call inside the paging so I can pass those params. Because right now if I click next button in paging nothing is getting returned. since the required parameters are missing to fetch the results. I tried all the given sample on internet but nothing is working.
It would be great if somebody can actually post an example on paging passing parameters or calling js function on next button event.
Any help will be really appreciated. Thank you.
below is the load store function that I want to call on my next event on pagination.
function loadStore(prodId, productsName, doctype, criteria, filename, titlename) {
store.removeAll();
store.load({
params: {
// specify params for the first page load if using paging
start: 0,
limit: g_perPage,
ajax: "true",
productId: prodId,
ProductsNameArr: productsName,
assetsname: doctype,
criterianame: criteria,
newfilename: filename,
newtitlename: titlename
}
});
}
http://docs.sencha.com/ext-js/3-4/#!/api/Ext.data.Store-property-baseParams
As Nigel said above the beforeload event is what you are after, see below for an example:
store.on('beforeload',function(store,opts) {
store.baseParams = { param1: 'foo', param2: 'bar', ... }
});
baseParams does not seem particularly useful because it sends static values, not the latest search criteria. Getting the dynamic search criteria is tricky too because the grid (i.e. the form fields) may not exist yet.
The Ext JS devs seem to have consistently mistaken docstring fragments for real documentation making for quite a hellish learning curve with their product. A few real examples here would go a long way.

AJAX Autocomplete Query from a MYSQL Table

I wanted to implement an ajax based autocomplete feature for my searchbox, and i came across, implementing autocomplete in my website.
Now what i wanted to know was that i attach a datasource to the control, but so far i have seen that the datasource requires a textbase schema, can't i like it to a query, where it control calls the query and it returns the records on which the filter of the control must apply.
Hope my question is clear
How do you think you can link it to a query on client-side??
You can link it to an AJAX call to the server, which returns the option-list.
The control's filter will do the rest filtering on that option-list.
The best practice would be, to fire an AJAX on page load, to a server function, which will query to the database (MySQL in your case) and fetch the options-list in json format. Assign the option-list to as an input for autocomplete. (Its obviously better than to fire a ajax-request everytime user starts to type-in the search box.)
If you use jquery it can be something like this.
$(function(){ //runs on page load
$.ajax({
type: "POST",
url: "/searchlist/", //server function that returns the search list
data: '',
dataType: "json",
success: function(json){
search_choices = json.list; // search option list
$("input#searchbox").autocomplete(search_choices, {
max: 4,
scroll: false,
autoFill: true,
multiple: true,
matchContains: true,
multipleSeparator: " ",
width: 180
});
}
});
});
I can provide you with example in libraries other than jquery, but i hope this can make you find your way.
Edit: No, your database needn't to have sorted choices. It is your server function, that should be doing all the sorting. Use,
autocomplete( url_to_server_function, options)
and your server function will get search term (keyword user types in search-box), as get request. Filter your database there, and this is the place where you can hook related words along with the results. Just make a list of everything you want to show as suggestion, and return in serialize json format and let autocomplete to take care of matching and sorting the data.

Resources