I am using Select2 4.0.3 in my web forms .net application. I am trying to Load Remote data using a webservice, but its not working as expected.
First Issue am facing is that the webservice method is not getting called and am getting a console error:
System.InvalidOperationException: Missing parameter: text.
at System.Web.Services.Protocols.ValueCollectionParameterReader.Read(NameValueCollection collection)
at System.Web.Services.Protocols.HtmlFormParameterReader.Read(HttpRequest request)
at System.Web.Services.Protocols.HttpServerProtocol.ReadParameters()
at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()
So I tried removing the paremeter from the webservice call
<WebMethod()> _
Public Function GetDataFromService() As String
Doing this the method got fired, but still the items in the select2 did not get populated (screenshot atached).
Can someone help me to figure out where am I making a mistake.
Here are the details:
Select2 Code in the Webform:
$("#ddlEntity").select2({
ajax: {
url: "Service/InvoiceHTMLService.asmx/GetDataFromService",
type: 'POST',
delay: 250,
params: {
contentType: 'application/json; charset=utf-8'
},
dataType: 'json',
data: function (term, page) {
return {
text: term,
};
},
processResults: function (data, params) {
// parse the results into the format expected by Select2
// since we are using custom formatting functions we do not need to
// alter the remote JSON data, except to indicate that infinite
// scrolling can be used
params.page = params.page || 1;
return {
results: data.items,
pagination: {
more: (params.page * 30) < data.total_count
}
};
},
cache: true
},
escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
minimumInputLength: 1,
templateResult: formatRepo, // omitted for brevity, see the source of this page
templateSelection: formatRepoSelection // omitted for brevity, see the source of this page
});
WebService Method:
<WebMethod()> _
Public Function GetDataFromService(text As String) As String
Return "{['id':1, 'text':'Test1'],['id':2, 'text':'Test2']}"
End Function
Try this please
var fd = new FormData();
fd.append("text",term);
ajax: {
url: "Service/InvoiceHTMLService.asmx/GetDataFromService",
type: 'POST',
delay: 250,
params: {
contentType: 'application/json; charset=utf-8'
},
dataType: 'json',
data: fd
...
I think you did not create template for this select2. since you are using templateResult and templateSelection it requires template or you can remove those two options.
For your reference : https://select2.github.io/examples.html#templating
Updated:
they have changed query callback from
data: function (term, page) {
return {
text: term,
};
},
into
data: function (params) {
return {
q: params.term, // search term
page: params.page
};
},
Related
I want to show the dropdown list with data response via Ajax call. Everything is working fine but I am getting this ValueError: Cannot use None as a query value error.
view:
def load_brand(request):
if request.is_ajax():
term = request.GET.get('term')
brand = Brand.objects.all().filter(brand__icontains=term)
return JsonResponse(list(brand.values()), safe=False)
ajax:
$('#id_brand').select2({
ajax: {
url: '/brand/ajax/load-brand/',
dataType: 'json',
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {id: item.id, text: item.brand};
})
};
}
},
minimumInputLength: 1
});
In your ajax call you have not send the data i.e : which user type inside select2 and you are accessing them i.e : request.GET.get('term') which is empty so your .filter(brand__icontains=term) giving you error because term value is null.
Instead you can add below as well in your ajax call :
$('#id_brand').select2({
ajax: {
url: '/brand/ajax/load-brand/',
dataType: 'json',
data: function(params) {
var query = {
term: params.term, //this will be paass
type: 'public' //optional..
}
// Query parameters will be ?term=[values]&type=public
return query;
},
processResults: function(data) {
return {
results: $.map(data, function(item) {
return {
id: item.id,
text: item.brand
};
})
};
}
},
minimumInputLength: 1
});
Also , at your server end you can check if the term has any value i.e :
if term:
brand = Brand.objects.all().filter(brand__icontains=term)
For more information check this
I want to return a Partial View in ajax call in Sitecore, I am already using web APIs, i can return JSON object, but i want to return the view with HTML :
[HttpGet]
public ActionResult StoreSearchResultsPartial()
{
return PartialView("/views/components/StoreSearchResults.cshtml");
}
my ajax call :
var ajaxUrl = "/api/sitecore/components/StoreSearchResultsPartial"
$.ajax({
type: "GET",
url: ajaxUrl,
contentType: "application/json; charset=utf-8",
success: function (result) {
$("#searchResults").html(result);
},
error: function (result) {
}
});
i am using web API for other functionalities, so i added my routing :
public void Process(PipelineArgs args)
{
var config = GlobalConfiguration.Configuration;
RouteTable.Routes.MapHttpRoute(
name: "NamedActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
).RouteHandler = new SessionRouteHandler();
config.Routes.MapHttpRoute("DefaultApiRoute",
"api/{controller}/{id}",
new { id = RouteParameter.Optional });
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
}
When I comment this routing everything is working fine.
It is working fine now, I changed my routing to start with something not "api", so i changed this api/{controller}/{action}/{id} to be mywebapi/{controller}/{action}/{id}, then i was able to call : /api/sitecore/components/StoreSearchResultsPartial
I am quite new to Yesod and currently try to develop a frontend website and a backend restful webservice. To access the API from the website I use AJAX requests. For the URLs of the requests I want to use shakespearean template like calls:
$.ajax({
url: '#{PersonR}',
type: 'GET',
contentType: "application/json",
data: JSON.stringify({...}),
success: function (data) {...}
});
On the backend site the route to my PersonR handler is defined as follows:
/api/person/#Int/get PersonR GET
For this to work the handler has a signature like
getPersonR :: Int -> Handler Value
However now the julius template needs a parameter to be a valid. I experimented a bit and found that I can directly use haskell code also in #{...}. Maybe I missed that point in the doku.
Question 1: Is there a way to tell that one of the parameters could be given in JavaScript? Maybe with a renderer to output something like this:
function(var1){return '/api/person/'+var1+'/get';}
I think this lacks the point of type safety though. Which leads to my second question (which kinda negates the first): Is there any other way to achieve getting data into the URLs on the client side?
I haven't used this package much, but yesod-js-routes seems like it fits the bill. Basically the package takes your routes file and generates Javascript functions you can use to create the URLs.
The package hasn't seen active development in awhile, but based on testing it still works fine. It's not on Hackage, but it's one file, so I just copied it into my project (I also needed to add import Prelude to that file, and add mtl to my build-depends section of the Cabal file). The README of the project covers the basic integration of the package you need to do.
Here's some example output. For this routes file:
/static StaticR Static appStatic
/auth AuthR Auth getAuth
/favicon.ico FaviconR GET
/robots.txt RobotsR GET
/ HomeR GET POST
/comments CommentR POST
/jsRoutes JSRoutesR GET
/test/#Text/#Integer TestR GET POST
I got this Javascript:
;
var jsRoutes = {}; /* Subsite not supported */ ; /* Subsite not supported */ ;
jsRoutes.FaviconR = {
get: function() {
return {
method: "get",
url: "/favicon.ico/"
};
}
};
jsRoutes.RobotsR = {
get: function() {
return {
method: "get",
url: "/robots.txt/"
};
}
};
jsRoutes.HomeR = {
get: function() {
return {
method: "get",
url: "/"
};
},
post: function() {
return {
method: "post",
url: "/"
};
}
};
jsRoutes.CommentR = {
post: function() {
return {
method: "post",
url: "/comments/"
};
}
};
jsRoutes.JSRoutesR = {
get: function() {
return {
method: "get",
url: "/jsRoutes/"
};
}
};
jsRoutes.TestR = {
get: function() {
return {
method: "get",
url: "/test/" + arguments[0] + "/" + arguments[1] + "/"
};
},
post: function() {
return {
method: "post",
url: "/test/" + arguments[0] + "/" + arguments[1] + "/"
};
}
};
For a route like TestR, you can call:
jsRoutes.TestR.get("a",2).url
to return
"/test/a/2/"
Unfortunately, neither the generated Javascript nor Javascript the language is doing anything to protect against e.g. passing 3 arguments to that function, or passing arguments of the wrong type. I don't know what your expectations are, but the Javascript code generation looks simple enough that you could improve what's generated.
i surely an committing a very lame mistake but couldn't figure out where...
here is my web method
[WebMethod]
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public int Add(int x, int y) {
return x + y;
}
and im calling it via ajax like this
$.ajax({
type: "GET",
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: { x: 4, y: 5 },
url: 'http://localhost:14436/Service1.asmx/Add',
success: function (data) {
alert('success');
var d = $(data);
console.log(d);
}
});
the problem is i cannot get the returned data in success,
in fiddler its showing {"d":9} but i keep on getting data empty... what am i doing wrong here... TIA
Edit
my web service is at http://localhost:14436/Service1.asmx and my web application from which im accessing the web service is located at http://localhost:3587/
so i guess this makes it a cross domain request?
try the following function:
function AjaxSucceeded(result)
{
alert(result.d);
}
still not getting any result?
UPDATE:
You can read more about the .d wrapper at:
http://encosia.com/2009/02/10/a-breaking-change-between-versions-of-aspnet-ajax/
Here's the exact sample as what you're trying to achieve:
http://www.joe-stevens.com/2010/01/04/using-jquery-to-make-ajax-calls-to-an-asmx-web-service-using-asp-net/
This one's killing me. I've read through a lot of Oleg's comments, and through the documentation, but I think I'm overlooking something really simple.
I have a jqGrid populated by calling a webmethod that returns JSON. We're good there. I'm using the Navigator for my "Add" button, and using onSelectRow w/ jqGrid.editRow() for my editing.
I get the dialog box when clicking the "Add" button, and can fill everything in. However, I get a error Status: 'Internal Server Error'. Error code: 500 return message after clicking the Submit button. Using Firebug, the Response is {"Message":"Invalid JSON primitive: FileType.","StackTrace":..... and the Post is FileType=3&ExportDate=12%2F29%2F2010&oper=add&id=_empty.
Obviously, my post is not getting "jsonified". I have tried using serializeEditData, and beforeSubmit in an attempt to manually return JSON.stringify(eparams);, but nothing has worked. Please see my code below.
Webmethod
<WebMethod()> _
<ScriptMethod()> _
Public Sub ModifyFileLog(ByVal FileType As String, _
ByVal ExportDate As Nullable(Of Date), _
ByVal oper As String, ByVal id As String)
Try
' blah
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
End Sub
JS - Globals
jQuery.extend(
jQuery.jgrid.defaults, {
type: "POST",
mtype: "POST",
datatype: "json",
ajaxGridOptions: { contentType: "application/json" },
ajaxRowOptions: { contentType: "application/json" },
rowNum: 10,
rowList: [10, 20, 30],
serializeGridData: function(data) {
return JSON.stringify(data);
},
gridview: true,
viewrecords: true,
sortorder: "asc"
},
jQuery.jgrid.edit, {
ajaxEditOptions: { contentType: "application/json" },
recreateForm: true,
serializeEditData: function(postData) {
return JSON.stringify(postData);
}
}
);
JS - jqGrid
var tblName = "tblFiles";
var pager1 = '#pagerFiles';
var grid = $("#" + tblName);
grid.jqGrid({
url: 'WebService.asmx/GetFileLog',
colNames: ['ID', 'File Type', 'Report Date', 'Export Date', 'EE Count'],
ajaxGridOptions: {
success: function(data, textStatus) {
if (textStatus == "success") {
ReceivedClientData(JSON.parse(getMain(data)).rows, grid); // populates grid
endGridRequest(tblName); // hides the loading panel
}
},
error: function(data, textStatus) {
alert(textStatus);
alert('An error has occured retrieving data!');
}
},
editurl: "WebService.asmx/ModifyFileLog",
serializeEditData: function(postData) {
return JSON.stringify(postData);
},
recreateForm: true,
pager: pager1,
...
}); // end .jqGrid()
grid.jqGrid('navGrid', pager1, { add: true, del: false, edit: true, view: false, refresh: true, search: false },
{}, // use default settings for edit
{
//beforeSubmit: submitAddFileLog,
closeAfterAdd: false,
closeAfterEdit: true
}, // use default settings for add
{}, // delete instead that del:false we need this
{multipleSearch: false }, // enable the advanced searching
{closeOnEscape: true} /* allow the view dialog to be closed when user press ESC key*/
); // end grid/jqGrid('navGrid')
NOTE: I started out populating by using $.ajax() by way of datatype: function(data), but thought I would return to the simplest example to get this to work. If you care to offer your thoughts on the advantages of using $.ajax() over simply using grid.jqGrid({ url: blah });, I'd love to learn more. Otherwise, please let me know if it would be more appropriate to post it as a separate question.
Also, please let me know if I'm just flat out doing this the wrong way. I'm not locked in to any one way of getting this done. I would prefer to be wrong and to learn how to do this the right way, than to be "right" in my own mind and continue to hack my way through it.
Any help, along w/ examples, would be hugely appreciated.
In my opinion your main problem is in JS - Globals. You use jQuery.extend function in a wrong way. You should replace one call
jQuery.extend(
jQuery.jgrid.defaults, {
// ...
},
jQuery.jgrid.edit, {
// ...
}
);
to two separate calls:
jQuery.extend(
jQuery.jgrid.defaults, {
// ...
}
);
jQuery.extend(
jQuery.jgrid.edit, {
// ...
}
);
After that the edit request to the server will be {"FileType":3,"ExportDate"="12/29/2010","oper":"add","id":"_empty"} instead of FileType=3&ExportDate=12%2F29%2F2010&oper=add&id=_empty.
Next, I am not sure that you can use ExportDate as a Date (DateTime ???) type. Probably you should start with String type and then convert the input data to the datatype which you need.
Next remark. Be sure that ModifyFileLog return JSON data. For example you can use <ScriptMethod(ResponseFormat:=ResponseFormat.Xml)> instead of <ScriptMethod()>. If you use .NET 4.0 you can achieve the same in many other ways.
One more thing. The ModifyFileLog should be Function instead of Sub and return the Id of new added object. In case of edit or del operations the return value will be ignored.
Because ModifyFileLog Function will be returned JSON data you have to decode/parse it. You can do this almost in the same way which I described here. In case of ASMX web service you can do about following:
jQuery.extend(
jQuery.jgrid.edit, {
ajaxEditOptions: { contentType: "application/json" },
recreateForm: true,
serializeEditData: function(postData) {
return JSON.stringify(postData);
},
afterSubmit: function (response, postdata) {
var res = jQuery.parseJSON(response.responseText);
return [true, "", res.d];
}
}
);