I have done a lot of research and cannot find an answer. I want to integrate JSTREE with MVC3.0. Here is my Javascript setup:
setupTree: function (treeDivId) {
$('#' + treeDivId).jstree({
"json_data": {
"ajax": {
url: CustomTree.SectorLoadUrl,
type: "POST",
contentType: "application/json;charset=utf-8",
dataType: "json",
data: function (n) {
return { id: n.attr ? n.attr("id") : "0" };
},
success: function (data, textstatus, xhr) {
alert(data);
},
error: function (xhr, textstatus, errorThrown) {
alert(textstatus);
}
}
},
"themes": {
"theme": "default",
"dots": true,
"icons": false
},
"plugins": ["themes", "json_data"]
});
}
I also get the data correctly as can be seen in the uploaded image:
However, the following lines of code:
data: function (n) {
return { id: n.attr ? n.attr("id") : "0" };
},
Always return a -1 for n.
And I get a parser error on the OnError handler in my textstatus.
I am going to answer this question in the hopes that it helps someone.
I spent a total of 5hrs trying to understand what was going on and finally added a hack.
Using Firebug, I noticed that a callback was being appended to the URL. When the data was returned, the callback was not getting executed. I didn't specify any callbacks, so that was the first item to look into.
Per documentation, turns out that jquery1.5 onwards it will automatically append a callback if it thinks the data type is jsonp. However, I explicitly mentioned 'json' as my data type so I don't understand why it appended that callback.
Here's what the jquery documentation says:
"jsonp": Loads in a JSON block using JSONP. Will add an extra "?callback=?" to the end of your URL to specify the callback.
So this made me wonder what was going on. Also turns out, as of jquery 1.5, you can now specify multiple data types in the AJAX call and jquery will automatically try to convert.
Buried deep within the jquery documentation is this: "As of jQuery 1.5, jQuery can convert a dataType from what it received in the Content-Type header to what you require."
So I just thought it would be better to return the data type as text, then use jquery to convert it to json. The moment I changed my dataType to "text json" instead of just "json", everything magically started working.
My guess is, there's something up with auto-inference on data types with the new jquery. I am on a strict deadline so I cannot research this issue anymore, but if someone finds answers, please do post.
Here is my modified Javascript:
setupTree: function (treeDivId) {
$('#' + treeDivId).jstree({
"json_data": {
"ajax": {
"url" : CustomTree.SectorLoadUrl,
"type" : "POST",
"dataType" : "text json",
"contentType" : "application/json charset=utf-8",
}
},
"themes": {
"theme": "default",
"dots": true,
"icons": false
},
"plugins": ["themes", "json_data"]
});
Related
I need to make an Elastic Search query with Ajax. What I'm trying to do is search for a specific category name, and return the list of names associated with that category. The structure in Elastic Search is that each _source has a name fields (the name of the category), and an items fields. It also has name.raw so that I can search by exact name.
This is my request:
var query = {
query: {
filtered: {
filter: {
term: { "name.raw": category }
}
}
}
}
$.ajax({
url: "http://192.168.0.240:9200/dropdowns/category/_search",
type: 'post',
dataType: 'json',
success: function(data) {
alert("Success");
},
error: function(data) {
// should be only one item in hits
$(data.hits.hits).each(function(index, hit) {
alert(hit._source.items);
});
},
data: query
});
For now, I'm trying to simply get it to work enough to alert me to the items in the hit. I'm getting a 400 Bad Request error. What's wrong with my Ajax call?
With help from Jonathon Lerner, I figured out that the problem with my query was that it had to be stringified. So, I simply changed it to
data : JSON.stringify(query)
You should be able to send the query in the URL using a GET method, with this syntax:
var query = '{"query":{"filtered":{"filter:{"term":{"name.raw": category}}}}}';
$.ajax({
url: `http://192.168.0.240:9200/dropdowns/category/_search?
source_content_type=application/json&source=${query}`,
success: function(data) {
console.log(data);
}
});
Using the following code:
var query = {
query: {
filtered: {
filter: {
term: { "name.raw": category }
}
}
}
};
$.ajax({
url: "http://192.168.0.240:9200/dropdowns/category/_search",
type: 'GET',
dataType: 'json',
success: function(data) {
console.log('Success');
$(data.hits.hits).each(function(index, hit) {
console.log(hit._source.items);
});
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus);
console.log(errorThrown);
},
data: query
});
you should be able to debug the problem with your query in the Javascript Console, as well as see successful output. Here are some directions on how to see the JS console in different browsers: https://webmasters.stackexchange.com/questions/8525/how-to-open-the-javascript-console-in-different-browsers
Edit: It seems like those directions are for Windows specifically. I know that on Mac, Command+Option+j opens the Chrome JS console. Im sure if your browser/OS isnt covered here you can find the correct shortcut on Google.
The HTTP libraries of certain languages (notably Javascript) don’t allow GET requests to have a request body.
See this: http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/_empty_search.html
So I think it's correct to use POST method here, you simply forget to stringify the request body.
So I've been beating my head against the wall for a day or so trying to get this to work. if it's simple and stupid - sorry and thanks. It's pretty long post as I'm trying to describe everything I've done thus far.
So I have a ASMX web service that I would like to use to populate a Kendo UI listview. This works perfectly until I add the data: to my transport request. So my web service looks like this now:
WebMethod(Description = "Return All Pending Actions Based")]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public PendingActionResult GetPendingActions(string sUsername, string sPassword, string sUserID, string sClubID)
{
//code is here;
}
And my full dataSource looks like this:
dataSource = new kendo.data.DataSource({
transport: {
read: {
type: "POST",
data: "{'sUsername':'admin#mail.com','sPassword':'13123','sUserID':'1539','sClubID':'1'}",
url: "http://sdk.domain.com/services/general.asmx/GetPendingActions",
contentType: "application/json; charset=utf-8",
dataType: "json"
}
},
schema: {
data: "d.Data", // ASMX services return JSON in the following format { "d": <result> }. Specify how to get the result.
total: "d.Total",
model: {
id: "activityID",
fields: {
activityID: { type: "number", validation: {min: 1, required: true } },
taskName: { type: "string" },
taskNote: { type: "string" },
openDate: { type: "datetime" },
dueDate: { type: "datetime" },
priority: { type: "number" },
statusID: { type: "number" },
openedByID: { type: "number" },
assignedToID: { type: "number" },
statusName: { type: "string" },
complete: { type: "bool" }
}
}
}
});
that.set("pendingActionsDataSource", dataSource);
The error I get back is:
{"Message":"InvalidJSONprimitive:"\u00261={\u00262=\u0027\u00263=s\u00264=U\u00265=s\u00266=e\u00267=r\u00268=n\u00269=a\u002610=m\u002611=e\u002612=\u0027\u002613=:\u002614=\u0027\u002615=a\u002616=d\u002617=m\u002618=i\u002619=n\u002620=#\u002621=m\u002622=a\u002623=i\u002624=l\u002625=.\u002626=c\u002627=o\u002628=m\u002629=\u0027\u002630=,\u002631=\u0027\u002632=s\u002633=P\u002634=a\u002635=s\u002636=s\u002637=w\u002638=o\u002639=r\u002640=d\u002641=\u0027\u002642=:\u002643=\u0027\u002644=1\u002645=3\u002646=1\u002647=2\u002648=3\u002649=\u0027\u002650=,\u002651=\u0027\u002652=s\u002653=U\u002654=s\u002655=e\u002656=r\u002657=I\u002658=D\u002659=\u0027\u002660=:\u002661=\u0027\u002662=1\u002663=5\u002664=3\u002665=9\u002666=\u0027\u002667=,\u002668=\u0027\u002669=s\u002670=C\u002671=l\u002672=u\u002673=b\u002674=I\u002675=D\u002676=\u0027\u002677=:\u002678=\u0027\u002679=1\u002680=\u0027\u002681=}\u002682=".","StackTrace":"atSystem.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(Stringinput,Int32depthLimit,JavaScriptSerializerserializer)\r\natSystem.Web.Script.Serialization.JavaScriptSerializer.DeserializeT\r\natSystem.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContextcontext,WebServiceMethodDatamethodData)","ExceptionType":"System.ArgumentException"}
So I started searching high and low for anything that was similar and found other people missing a ' or a " in the data request so I tried a ton of different variations of it, tried using JSON.stringify but the error continued. So I went to fiddler to see what was being sent to the server and here is my problem. Junk is being sent. Fiddler shows this in TextView being sent to the server:
0=%7B&1='&2=s&3=U&4=s&5=e&6=r&7=n&8=a&9=m&10=e&11='&12=%3A&13='&14=a&15=d&16=m&17=i&18=n&19=%40&20=m&21=a&22=i&23=l&24=.&25=c&26=o&27=m&28='&29=%2C&30='&31=s&32=P&33=a&34=s&35=s&36=w&37=o&38=r&39=d&40='&41=%3A&42='&43=1&44=3&45=1&46=2&47=3&48='&49=%2C&50='&51=s&52=U&53=s&54=e&55=r&56=I&57=D&58='&59=%3A&60='&61=1&62=5&63=3&64=9&65='&66=%2C&67='&68=s&69=C&70=l&71=u&72=b&73=I&74=D&75='&76=%3A&77='&78=1&79='&80=%7D
(I'll post a picture online of this so it's a little easier to see)
So here I can clearly see that the string isn't being sent in the correct format. So I decided to give this a go without using Kendo dataSource but instead just use JSON/AJAX. So I typed this up:
function getPAs() {
$.ajax({
type: "POST",
url: "http://sdk.domain.com/services/general.asmx/GetPendingActions",
data: "{'sUsername':'admin#mail.com','sPassword':'13123','sUserID':'1539','sClubID':'1'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: getPAs_Success,
error: app.onError
});
}
function getPAs_Success(data, status) {
console.log("START getPAs_Success");
var cars = data.d;
var sout = document.getElementById('nav');
var output = "";
$.each(cars, function(index, car) {
output += '<p><strong>' + car.taskName + ' ' +
car.taskNote + '</strong><br /> Priority: ' +
car.priority + '<br />Status: ' +
car.statusID + '<br />Opened By: ' +
car.openedByID + '<br />Assigned To' +
car.assignedToID + '</p>';
});
sout.innerHTML = output;
console.log("END getPAs_Success");
}
And if I look at fiddler in TextView I see this being sent to the server:
{'sUsername':'admin#mail.com','sPassword':'13123','sUserID':'1539','sClubID':'1'}
And I clearly see my JSON results in fiddler as well.
So my question is after all of that:
Is there something special I need to be doing with the Kendo UI Datasource in order to pull this off? If it matters, I'm using Icenium and trying to build a quick mobile app for fun.
Thanks,
Richard
UPDATE #1
Tried both and no further.
data: {"sUsername":"admin#mail.com","sPassword":"13123","sUserID":"1539","sClubID":"1"},
which validates using jsonlint.com but when I look at fiddler now I see this being sent to the server:
sUsername=admin%40mail.com&sPassword=13123&sUserID=1539&sClubID=1
So maybe it's because I don't have quotes around the data now so I tried this:
data: '{"sUsername":"admin#mail.com","sPassword":"13123","sUserID":"1539","sClubID":"1"}',
and when I do that I get same mess of 0=%7... like above.
When I try to use toJSON I get an object function has no method. Doing something like this:
var jsPost = $.toJSON({
sUsername: "admin#mail.com",
sPassword: "13123",
sUserID: "1539",
sClubID: "1"
});
Found someone on the telerik forums which said not to use toJSON and instead use JSON.stringify so I tried this:
var jsPost = {
sUsername: "admin#mail.com",
sPassword: "13123",
sUserID: "1539",
sClubID: "1"
};
...
data: JSON.stringify(jsPost),
But still results in the crazy garbage.
A valid JSON format needs double quotes, instead of single. You can try validating your string in services like http://jsonlint.com/ . Even better, you can use toJson on an object instead of building it manually.
I upgraded my page from using jquery 1.4.4 to jquery 1.9.1 and suddenly my ajax calls stopped working. If i revert to jquery 1.4.4 it works again. I am getting below error.
No conversion from text to string
Below is my code
$.ajax({ url: "/Reporting/RunQuery",
type: "Post",
data: { prm_Query: qrytxt }, dataType: "string",
error: function (XMLHttpRequest, status, error) {
debugger;
alert("The following error occured while adding data: " + error);
},
success: function (data) {
debugger;
$('#divQuerytextarea').html('').append(data);
}
});
My call to /Reporting/RunQuery succeeds and it has valid return string in the RunQuery method. Then it falls into error: of ajax call with 'No conversion from text to string' error.
Not finding much in google for this. Any help is appreciated.
I agree with Kevin. I was having the same problem just because I've put :
dataType: JSON
instead of :
dataType: "json"
after what everything worked fine.
Be aware that this "dataType" property commes from the HTTP head where there is the MIME type wich is the type of the resource called by the HTTP request. So there is no "string" type. You should use "text" instead (if you want a string, of course).
I am trying to post an array of check box ids to an action in my controller. Here is the script from my index.ctp:
<script type="text/javascript">
$('.editSel_dialog').click(function()
{
var selected = [];
alert('Edit Selected Has Been Clicked');
$("#[id*=LocalClocks]").each(function()
{
if(false != $(this).is(':checked'))
{
selected.push($(this).attr('id').replace('LocalClocks', ''));
}
});
alert(selected);
/*$.ajax(
{
type: 'POST',
url: "/LocalClocks/editSelected/",
data: selected,
traditional: true,
//contentType: "application/json",
dataType: "text",
success: function(data){ alert(data); alert('Edit Success');}
});*/
$.post('/LocalClocks/editSelected', { "Session" : selected }, function(data){
alert(data);
});
});
</script>
I have both an ajax request and a post request. I was using the ajax until I saw that the post can actually modify a php variable. The code in the braces { "Session" : selected } should modify the Session variable with the array selected.
I tried using debug on $this->data, and $this->request->data, and $_POST, but they all are empty.
I need help getting the selected array written to a variable or something. I was thinking of trying to write to $this->Session but I am not sure how I would go about doing that.
Thanks in advance
With Cake, to get posted values in $this->request->data, their names have to be prefixed with data:
Javascript:
$.post('/LocalClocks/editSelected', { "data[Session][selected]" : selected }, function(data){
alert(data);
});
Controller:
function editSelected()
{
if($this->request->is('post'))
{
if(isset($this->request->data['Session']['selected']))
{
$this->Session->write('selected', $this->request->data['Session']['selected']);
}
}
}
Maybe I'm wrong, but I think you cannot do that directly from the client side using ajax. Can you share the source your statement regarding you can modify the php variable? I googled for that with no luck, and it will be weird to me being able to modify the PHP session.. it would be really insecure, saying you could use Session Fixation/Injection or other malicious techniques
Edited
For assigning the value on a existing variable you need
Make the ajax call
$.post('/LocalClocks/editSelected', { "selected" : selected }, function(data){
alert(data);
});
and on your controller you'll have a function like this
function editSelected($selected){
$_SESSION["selected"] = $selected;
}
and voila
If I call a function to load my grid data, loadComplete does not fire. I need to handle this event so I can manually update multiselect checkbox correctly. If I update in gridComplete, I have to click the checkbox twice to uncheck it.
In your previous question you wrote that you use WCF on the server side. In the case you don't need to use datatype as function. Instead of that you can just use the following parameters:
datatype: "json",
ajaxGridOptions: { contentType: "application/json" },
serializeGridData: function (data) {
return JSON.stringify(data);
}
To be sure that JSON.stringify are supported in old web browsers you should include json2.js which you can load from here.
In the old answer you can find more code examples (and download the demo) which shows how you can use WCF with jqGrid.
Now I will answer on your original question: "Why loadComplete does not fire" if you use datatype as function. The short answer is: if you use datatype as function your code is responsible for calling of loadComplete.
If you use datatype as function your code is responsible to some things which jqGrid do typically. So first of all you have to understand what should the datatype function do. An example from the documentation (see here) shows the simplest, but not full, implementation of datatype as function. More full code example looks like the following:
$("#list").jqGrid({
url: "example.php",
mtype: "GET",
datatype: function (postdata, loadDivSelector) {
var ts = this, // cache 'this' to use later in the complete callback
p = this.p; // cache the grid parameters
$.ajax({
url: p.url,
type: p.mtype,
dataType: "json",
contentType: "application/json",
data: JSON.stringify(postdata),
cache: p.mtype.toUpperCase() !== "GET",
beforeSend: function (jqXHR) {
// show the loading div
$($.jgrid.jqID(loadDivSelector)).show();
// if loadBeforeSend defined in the jqGrid call it
if ($.isFunction(p.loadBeforeSend)) {
p.loadBeforeSend.call(ts, jqXHR);
}
},
complete: function () {
// hide the loading div
$($.jgrid.jqID(loadDivSelector)).hide();
},
success: function (data, textStatus, jqXHR) {
ts.addJSONData(data);
// call loadComplete
if ($.isFunction(p.loadComplete)) {
p.loadComplete.call(ts, data);
}
// change datatype to "local" to support
// "loadonce: true" or "treeGrid: true" parameters
if (p.loadonce || p.treeGrid) {
p.datatype = "local";
}
},
error: function (jqXHR, textStatus, errorThrown) {
if ($.isFunction(p.loadError)) {
p.loadError.call(ts, jqXHR, textStatus, errorThrown);
}
});
},
... // other parameters
});
You can see that the code in not so short. In the above example we still not support some jqGrid options like virtual scrolling (scroll: 1 or scroll: true).
Nevertheless I hope that I cleared now why I don't recommend to use datatype as function. If you use it you have to understand many things how jqGrid work internally. You should examine it's source code to be sure that you do all things correctly. If you skip somethings, than your code will works incorrect in some situations or in some combination of jqGrid parameters.
If you look at the code which I included at the beginning of my answer (the usage of ajaxGridOptions and serializeGridData) you will see that the code is very easy. Moreover it works with all other legal combination of jqGrid parameters. For example you can use loadonce: true, loadComplete, loadError or even virtual scrolling (scroll: 1 or scroll: true). All things needed depend on the parameters do jqGrid for you.