I'm developing a web application with jax-rs, i made a rest client with jquery. I'm getting the result as json or xml, then showing them to html table. To facilitate table, im using JqGrid library. My problem is, for example Jqgrid wants to json object like below ;
[
{yaziNo:"1",yazar:"abc",yazi:"test",tarih:"2007-10-01"},
{yaziNo:"2",yazar:"cdfe",yazi:"test2",tarih:"2007-10-01"},
{yaziNo:"3",yazar:"cdfe",yazi:"test3",tarih:"2007-10-01"},
{yaziNo:"4",yazar:"abc",yazi:"test",tarih:"2007-10-01"},
{yaziNo:"5",yazar:"cdfe",yazi:"test2",tarih:"2007-10-01"},
{yaziNo:"6",yazar:"abc",yazi:"test3",tarih:"2007-10-01"},
{yaziNo:"7",yazar:"cdfe",yazi:"test",tarih:"2007-10-01"},
{yaziNo:"8",yazar:"abc",yazi:"test2",tarih:"2007-10-01"},
{yaziNo:"9",yazar:"abc",yazi:"test3",tarih:"2007-10-01"} ]
But, returned JSON from my rest server those like below;
{"yazi":
[{"tarih":"26.01.2012","yazar":"sdasdadsadasda","yazi":"gdfgdfgd","yaziNo":"1756"},
{"tarih":"26.01.2012","yazar":"sdasdadsadasda","yazi":"gdfgdfgd","yaziNo":"1755"},
{"tarih":"26.01.2012","yazar":"sdasdadsadasda","yazi":"gdfgdfgd","yaziNo":"1754"},
{"tarih":"26.01.2012","yazar":"sdasdadsadasda","yazi":"gdfgdfgd","yaziNo":"1753"},
{"tarih":"26.01.2012","yazar":"sdasdadsadasda","yazi":"gdfgdfgd","yaziNo":"1752"}]
}
How can i delete the "yazi" node but keeping inside.
edited:
jQuery("#list27").jqGrid({
url:'http://localhost:43842/KodcuComRESTful/kodcuRS/yazilar',
datatype: "json",
height: 255,
width: 700,
jsonReader: {root: "yazi", repeatitems: false},
colNames:['Yazi No','Yazar', 'Yazi', 'Tarih'],
colModel:[
{name:'yaziNo',index:'yaziNo', width:80, sorttype:"int"},
{name:'yazar',index:'yazar', width:180},
{name:'yazi',index:'yazi', width:370},
{name:'tarih',index:'tarih', width:100, align:"right",sortype:"date"}
],
rowNum:10,
rowTotal: 2000,
rowList : [20,30,50],
loadonce:true,
mtype: "GET",
rownumbers: true,
rownumWidth: 40,
gridview: true,
pager: '#pager27',
sortname: 'yaziNo',
viewrecords: true,
sortorder: "asc",
caption: "Loading data from server at once"
});
I see no problem with the data returned from the server. You should just use jsonReader option of jqGrid which informs jqGrid how to read the data from the server response. For example
jsonReader: {root: "yazi", repeatitems: false}
UPDATED: The demo uses the exact JSON data which you posted and it displays the results in the grid. I used the JavaScript code which you posted and replaced only height: 255 to height: "auto" to have more compact results.
The only problem which I see in your code is the usage of full URL: url:'http://localhost:43842/KodcuComRESTful/kodcuRS/yazilar'. Because of same origin policy restriction one can't get JSON data per Ajax from another source as the same site and port. So in case of usage datatype: "json" you should always use relative URL path like url:'/KodcuComRESTful/kodcuRS/yazilar' for example.
Related
I have a kendo grid which is reading data from a remote json file. I want that the grid columns should also be read from the same json file so that I dont have to change the client side code again and again. Whatever comes in the json file it should be capable enough to present the same data without any hard coding on client side. My json file looks like
{ "data":[
{"_type":"ProductDetails:#NWProducts","Discount":0,"OrderId":10248,"ProductId":11,"UnitPrice":14.0000,"quanity":12},{"_type":"ProductDetails:#NWProducts","Discount":0,"OrderId":10248,"ProductId":42,"UnitPrice":9.8000,"quanity":10},{"_type":"ProductDetails:#NWProducts","Discount":0,"OrderId":10248,"ProductId":72,"UnitPrice":34.8000,"quanity":5},{"_type":"ProductDetails:#NWProducts","Discount":0,"OrderId":10249,"ProductId":14,"UnitPrice":18.6000,"quanity":9}],
"columns":[
{"field":"_type","title":"Type"},{"field":"Discount","title":"Discount($)"},{"field":"OrderId","title":"Order ID"},{"field":"ProductId","title":"Product ID"},{"field":"UnitPrice","title":"Unit Price"},{"field":"quanity","title":"Quanity"}]
}
HTML code is as below
<div id="grid"></div>
JS code is below
$("#grid").kendoGrid({
title: { text: "Stats" },
sortable: false,
pageable: {
pageSizes: true,
buttonCount: 5
},
columnMenu: true,
dataSource: {
transport: {
read: {
url: "............/demo.json",
dataType: "json"
}
},
schema: {
data: "data"
}
},
columns: {
//What should be done here.
}
});
I tried the same transport read schema way to fetch the column data but it did not work. If I store the same columns json data in a variable and substitute that variable for columns then it works. Is there any way to store the columns json data as such in a variable from the json file. What is the best approach to achieve this behavior. Any help would be appreciated.
Thanks in Advance.
I need to load my grid from a server that expect a URL + parameters + a serialized payload, i.e. the message body. I am using a POST method and the server expects this along with JSON payload.
The serialized payload is a JSON string for MongoDB that instructs mongo how to find the data we care about. I designed the RESTful interface to respond back in the JSON format that jqGrid expects, however, to use pagination, I expected jqGrid to append the values for "page", "rows", etc, etc as a query string: baseURL?rows=10&page=1
Here is my grid setup
grid.jqGrid({
ajaxGridOptions: {
contentType: "application/json",
},
altRows: true,
autoWidth: true,
caption: "Results for " + ADC_Idl.buildQueryTitle(),
colNames: displayNames,
colModel: columnModel,
datatype: "json",
height: "auto",
mtype: "POST",
pager: '#pager5',
//postData: ADC_Idl.buildQueryPayload(),
serializeGridData: function (postData) {
grid.jqGrid("setGridParam", "url", ADC_Idl.buildQueryURL() + "?" + jQuery.param(postData));
return ADC_Idl.buildQueryPayload();
},
beforeRequest: function() {
grid.jqGrid("setGridParam", "url", ADC_Idl.buildQueryURL() + "?page=" +
grid.jqGrid("getGridParam", "page") + "&rows=" +
grid.jqGrid("getGridParam", "rowNum") );
},
rowList: [10, 20, 30],
rowNum: 10,
url: ADC_Idl.buildQueryURL(),
viewrecords: true,
jsonReader: {
repeatitems: false
}
I've left a few things in there to show what I have tried. I tried having the serializedGridData function update the URL, with no luck, for whatever reason it seems to be ignored.
I tried updating the URL before the request, still no luck.
Originally I just set postData = serialized data, assuming the default pagination parameters would still be appended. This was not the case.
The documentation for postData just says "See API methods for manipulation" with no link (NO LINK IN A WIKI??!!! come on!!)
I've read every Oleg answer I could find here, nothing seems to address this scenario, which I find hard to understand, this must be a pretty common usecase.
This is how my server responds to the initial request for data (no pagination needed)
page: 1
records: 500
rows: [{_id: 1, REALM: "example.com", ACCOUNT: "8561000000",…},…]
total: 50
truncated for brevity.
After three days of trying everything I can think of, I'm pleading for some jqGrid experts to help!!
Thanks!
UPDATE
Figured it out and comments from Oleg made it even better. Posted as Answer!
Almost immediately after I posted this question I noticed something in another post from StackOverflow,
jqGrid("setGridParam"...
format is different for setting then getting, it excepts a hash for the update vs a parameter list for the get... UGH.
Once I fixed that, it worked!
Using some of the recommendations from Oleg's (thanks!) I have an even better solution as the code is cleaner and feels less hacky.
grid.jqGrid({
ajaxGridOptions: {
contentType: "application/json",
},
altRows: true,
autoWidth: true,
caption: "Results for " + ADC_Idl.buildQueryTitle(),
colNames: displayNames,
colModel: columnModel,
datatype: "json",
height: "auto",
gridview: true,
mtype: "POST",
pager: '#pager5',
postData: ADC_Idl.buildQueryPayload(),
beforeRequest: function() {
var gridParameters = jQuery(this).jqGrid("getGridParam");
var baseURL = gridParameters.url.split("?").shift();
var queryString = {
page: gridParameters.page,
rows: gridParameters.rowNum
};
gridParameters.url = baseURL + "?" + jQuery.param( queryString );
},
rowList: [10, 20, 30],
rowNum: 10,
url: ADC_Idl.buildQueryURL(),
viewrecords: true,
jsonReader: {
repeatitems: false,
id: "_id"
}
});
The relevant parts are:
postData: I use this to have jqGrid call my payload builder which returns JSON.stringify(payload object)
beforeRequest: Causes jqGrid to take the url used to define the grid with and remove any params already attached then update them with the newest values for page and rows.
jasonReader: added "id: "_id" as this is the key mongodb uses for the id.
gridview: true - This apparently speeds of the display of the grid? Oleg recommended, I did it, he's got a very detailed write up about it here: Oleg's explaination of gridview: true
It was also recommended that I provide my colModel, but I can't, this code is designed to build a jqGrid dynamically once the user submits a query that is directed at mongodb. The grid is built as a response to the users input, thus it is not something I have to share.
I'm wondering what the best way would be to load elements of a JSON response into a store.
What I have:
jQuery ajax request
var foodRequest = $.ajax({
url: "MyServlet",
type: "post",
cache: false,
dataType: "json",
data: JSON.stringify(searchquery),
error : function() {
alert ('ERROR!! Please re-enter the search criteria and try again.');
}
});
ajax response
{
"Foods":[
{
"Food":{
"name":"Spaghetti",
"id":"001",
"attributes":[
{
"attrname":"Price",
"attrvalue":"18.99"
},
{
"attrname":"Description",
"attrvalue":"Spaghetti is delicious, don't argue with me"
},
etc...
What I want:
(each element has 4 attributes)
var grid = Ext.define('Myapp.view.Grid' ,{
extend: 'Ext.grid.Panel',
id: 'mygrid',',
initComponent: function(columns) {
this.columns = [
{header: 'attrname', dataIndex: 'attrvalue', flex: 2 },
{header: 'attrname', dataIndex: 'attrvalue', flex: 2 },
{header: 'attrname', dataIndex: 'attrvalue', flex: 2 },
{header: 'attrname', dataIndex: 'attrvalue', flex: 2 },
etc...
How can I take the attributes from the json response and place them into a store my grid can use, as seen above?
Cheers!
The data you are returning looks like a tree. A normal grid works with fixed columns. In short:
a grid uses a store
the Store uses a number of fields or a Model.
a grid has a number of predefined columns, each column references a store(model) field by means of a dataIndex.
Now when the store loads data (either through a proxy or by manually dumping records in it). it creates a record internally. The fields on the record that are available are the fields you defined on the store or the fields you defined on the model the store uses.
Long story short, the normal setup of a grid and store is with a fixed number of columns and fields. In your case it would probably be better to use a TreePanel and store. Look at the treepanel example for this.
http://docs.sencha.com/extjs/4.0.7/extjs-build/examples/tree/treegrid.html
Good luck
i'm using solr+haystack(django plugin) on the backend and the search is working fine;
While Django(and Haystack) with its templates is doing everything for me(I mean its pretty simple to configure and use), ExtJS4 is a little more complex;
The question is how to use Solr using ExtJS4?
An example is very much appreciated;
Thanks for any help and sorry for my English;
As ExtJS4 is a MVC framework, the solution is done like MVC;
The controller/Search.js
Ext.define('yourapp.controller.Search',{
extend:'Ext.app.Controller',
stores:[
'Searches'
],
views:[
'search.Search',
'search.SearchList'
],
models:[
'Search'
],
init:function(){
this.control({
"search":{
'keyup':this.search,
},
});
},
search:function(inputedTxt, e, eOpts){
this.getSearchesStore().load({
//When sending a request, q will rely to request.POST['q'] on server-side;
//inputedTxt.getValue() -- a value, entered in textfield (or whatever)
params:{
q:inputedTxt.getValue()
},
callback:function(result){
if(result[0]){
//do something with the result
//i'd been creating a window with a grid inside. "Grid"'s view is written below.
}
}
}
});
The models/Search.js
Ext.define('yourapp.model.Search',{
extend:'Ext.data.Model',
fields:[
{name:'name', type:'string'}
]
});
The store/Searches.js
Ext.define('yourapp.store.Searches',{
extend:'Ext.data.Store',
storeId: "searchStore",
model:'yourapp.model.Search',
autoLoad: false,
proxy:{
type:'ajax',
// server-side url
url: '/searchlist/',
actionMethods:{create: "POST", read: "POST", update: "POST", destroy: "POST"},
reader:{
type:'json',
root:'searches'
}
}
});
The view/search/Search.js
//a Text field to input text;
Ext.define('yourapp.view.search.Search',{
extend:'Ext.form.field.Text',
alias: 'widget.search',
id: "searchView",
enableKeyEvents: true,
initComponent:function(){
this.callParent(arguments);
}
});
The view/search/SearchList.js
//a view for a result
Ext.define('yourapp.view.search.SearchList',{
extend: 'Ext.grid.Panel',
alias:'widget.searchlist',
title: 'search result',
store: 'Searches',
columns:[
{
header:'Name',
dataIndex:'name',
flex:1
}
]
});
Somewhere in the view/Viewport.js xtype: 'search', should be inserted for a text field to be displayed.
That's all for a ExtJS4 part.
On server-side -- Django:
'haystack' and Solr should be installed and configured (by 'configured' i mean: search should already work on the server-side);
In someapp/view.py
def searchlist(request):
from haystack.query import SearchQuerySet
# POST["q"] should be receivedt from our client-side
searchText = request.POST["q"]
sqs = SearchQuerySet().filter(name=searchText)
data = []
for result in sqs:
data.append({"name": result.object.name})
return HttpResponse('{ success:true, searches:'+simplejson.dumps(data)+'}', mimetype = 'application/json')
Finally in your urls.py you should add:
(r'^searchlist/','someapp.views.searchlist'),
That was for it. Best wishes.
P.S.
I know this is not the greatest answer and there's lack of explanation, but as for me, I rather prefer a code example than verbal explanation.
SOLR has JSON output from its queries using wt=json param and can readily be consumed by ExtJS.
http://wiki.apache.org/solr/SolJSON?action=fullsearch&context=180&value=jsonp&titlesearch=Titles#JSON_Response_Writer
if you need to use jsonp you can specify a callback function via this param json.wrf=callback
I found the very nice demo by Oleg (http://www.ok-soft-gmbh.com/jqGrid/FillToolbarSearchFilter.htm) which shows a "jqGrid toolbar search with autocomplete using local data" but have trouble to get this to work for json via ajax. Is there a good reason why the autocomplete feature won't work - even if I force the grid to be local after loading?
$(document).ready(function() {
var mygrid = $("#mylist"),
mygetUniqueNames = function(columnName) {
var texts = mygrid.jqGrid('getCol',columnName), uniqueTexts = [],
textsLength = texts.length, text, textsMap = {}, i;
for (i=0;i<textsLength;i++) {
text = texts[i];
if (text !== undefined && textsMap[text] === undefined) {
// to test whether the texts is unique we place it in the map.
textsMap[text] = true;
uniqueTexts.push(text);
}
}
return uniqueTexts;
};
mygrid.jqGrid({
url:'autocompleteTest.php',
datatype: "json",
colNames:['name', 'City','stateCd'],
colModel:[
{name:'name',index:'name',width:225, search: true},
{name:'City',index:'City',width:125},
{name:'stateCd',index:'stateCd',width:75},
],
rowNum: 100,
loadonce : true,
sortname: 'name',
sortorder: 'desc',
sortable: true,
viewrecords: true,
rownumbers: true,
sortorder: "desc",
ignoreCase: true,
pager: '#mypager',
height: "auto",
caption: "How to use filterToolbar better with data from server"
}).jqGrid('navGrid','#mypager',
{edit:false, add:false, del:false, search:false, refresh:false});
mygrid.jqGrid('setColProp', 'name',
{
searchoptions: {
sopt:['bw'],
dataInit: function(elem) {
$(elem).autocomplete({
source:mygetUniqueNames('name'),
delay:0,
minLength:0
});
}
}
});
mygrid.jqGrid('filterToolbar',
{stringResult:true, searchOnEnter:true, defaultSearch:"bw"});
});
It is difficult to provide an example in case of the usage of remote source parameter of jQuery UI Autocomplete. The main problem is that your question is about jqGrid which is pure JavaScript solution. If we would discuss the server part of tha solution we would have too options. Many users uses different languages: Java, C#, VB, PHP and so on. For example I personally prefer C#. Then we would have to choose the technology which we use: ASP.NET MVC, WCF, ASPX web service and so on. For example I would choose WCF. Then we should define the database access technology, for example, Entity Framework, LINQ to SQL, SqlDataReader, SqlDataAdapter and so on. Let us I would choose Entity Framework and would provide you the corresponding code example, but it would help you not really if you use for example PHP and MySQL.
So I just describe which interface should have the server for the remote source parameter of jQuery UI Autocomplete without any code.
You should replace in my example the source parameter to your server url like following:
dataInit: function(elem) {
$(elem).autocomplete({
source:'yourSearchUrl.php',
minLength:2
});
}
If the user types two characters (the value can be changed by minLength option), for example 'ab' then the autocomplete will make HTTP GET request with the parameter term=ab:
yourSearchUrl.php?term=ab
your server should answer with the JSON data in the same format as for the local source. I used the string array format in my previous example. Another supported format is array of objects with label/value/both properties like
[
{
"id": "Dromas ardeola",
"label": "Crab-Plover",
"value": "Crab-Plover"
},
{
"id": "Larus sabini",
"label": "Sabine`s Gull",
"value": "Sabine`s Gull"
},
{
"id": "Vanellus gregarius",
"label": "Sociable Lapwing",
"value": "Sociable Lapwing"
},
{
"id": "Oenanthe isabellina",
"label": "Isabelline Wheatear",
"value": "Isabelline Wheatear"
}
]
read the documentation for more information.
If you need to implement more complex scenario and send some additional data to the server or convert the server response in any way you can use custom source callback function. In the case you should use source: function(request, response) {/*your implementation*/}, where the request would be an object having term property (request.term). Inside of your implementation your should make ajax request to the server manually. The response would be callback function which you should call after your custom ajax request will be finished (inside of success event handler). The response function should be called with the parameter which should be array in the same format as mygetUniqueNames returns. I recommend you to examine the source code from the jQuery Autocomplete demo.
To de able to provide unique data from one column of tabele you should just use SELECT DISTINCT SQL statement which are supported in the most databases.
I hope that my description would help you.
UPDATED: If you have the local source the solution you could find in my old answer which you already use. What you just need to do is to call the filterToolbar after the source array are filled. Because you load the data from the server your should move the call of filterToolbar inside of loadComplete. You use loadonce:true jqGrid option which switch the datatype from 'json' to 'local' after the first data loading. So you can include in the loadComplete event handler of your grid the code like the following:
var grid = $('#list');
grid({
url:'autocompleteTest.php',
datatype: 'json',
loadonce: true,
// ... other parameters
loadComplete: function(data) {
if (grid.getGridParam('datatype') === 'json') {
// build the set 'source' parameter of the autocomplete
grid.jqGrid('setColProp', 'name', {
searchoptions: {
sopt:['bw'],
dataInit: function(elem) {
$(elem).autocomplete({
source:mygetUniqueNames('name'),
delay:0,
minLength:0
});
}
}
});
mygrid.jqGrid('filterToolbar',
{stringResult:true,searchOnEnter:true,
defaultSearch:"bw"});
}
}
});
If you will need to reload the data from the server (change the datatype to 'json' and call grid.trigger('reloadGrid')) you will have to change the code above so that you first destroy the autocomplete widget with $('#gs_name').autocomplete('destroy') and then create it one more time with the same code like inside of dataInit.