Select2 use a dynamic Ajax URL on call - jquery-select2

I use the Select2 plugin (v 3.5.2) with Ajax to dynamically load elements in the list.
I have an issue as between the initialization of the Select2 (where a url property is set in the ajax helper) and the time the ajax call is made, this url might need to be changed.
So I have something like this :
$box.select2({
containerCssClass: "form-control"
minimumInputLength: 0,
allowClear: true,
ajax: {
url: someUrl,
dataType: 'json',
quietMillis: 100,
...
}
I can't figure out how, when, where to change the ajax.url value before it launches.
The help of Select2 says:
Select2 uses jQuery's $.ajax function to execute the remote call by default. An alternative transport function can be specified in the ajax settings, or an entirely custom implementation can be built by providing a custom query function instead of using the ajax helper.
But I can't find any example on how to do it.
Thanks in advance for any help. Much appreciated.

I can't figure out how, when, where to change the ajax.url value before it launches.
The ajax.url option can be specified as a static string or a method returning one in both Select2 3.5.x and 4.0.0.
$("select").select2({
ajax: {
url: function () {
return UrlHelper.RemoteAPI();
}
}
});
This is useful for changing the base URL, for example when the URL is determined at runtime or is automatically generated in a different method. If you need to change the query parameters, such as the one used for sending the search term, you need to override the ajax.data option.
$("select").select2({
ajax: {
data: function (args) {
// args is the search term in 3.5.x
// args is an object containing the query parameters in 4.0.0
// args.term is the search term in 4.0.0
return {
search: args.term || args;
};
}
}
});
The data here will be appended as query parameters by default, and will be sent as the request body if the method type is changed from GET (the default) to anything else.
Select2 uses jQuery's $.ajax function to execute the remote call by default. An alternative transport function can be specified in the ajax settings, or an entirely custom implementation can be built by providing a custom query function instead of using the ajax helper.
But I can't find any example on how to do it.
Select2 does allow for a different AJAX transport to be used by changing the ajax.transport option.
In 3.5.2, this must be a $.ajax-compatible method, so it must be able to take an object containing the success and failure callbacks.
$("select").select2({
ajax: {
transport: function (args) {
// args.success is a callback
// args.failure is a callback
// should return an object which has an `abort` method.
return $.ajax(args);
}
}
});
In 4.0.0, this must be a method which takes a params object (the same one passed to ajax.data), a success callback, and a failure callback.
$("select").select2({
ajax: {
transport: function (params, success, failure) {
var $request = $.ajax(params);
$request.then(success);
$request.fail(failure);
return $request;
}
}
});

Very Simple Javascript code to handle the same, can be used in Suitescript(Netsuite) also.
// prepare your dynamic URL inside this method and return
function getURL() {
return url + params;
}
// While binding the select2 with the dropdown set url to call a anonymous function which internally calls another function.
jQuery("select.itemDropDown").select2({
placeholder: "Select an item",
width: "200px",
minimumInputLength: 3,
ajax: {
url: function() {
return getURL()
},
dataType: 'json'
}
});

Related

Calling controller method with a get type not working in ASP.NET MVC

I have a java script function that calling a controller method using Ajax, this call should get me the user profile page, I have a controller for this purpose. When I run the program and fire the java script function it's trigger the controller and every thing is good but when the debugging has ended no changes happens and the view doesn't present in the screen.
I tracked the call and every thing is working fine, passing parameter and reaching the method in the controller.
Note: the view which has the JS call related to a different controller.
View contain java script call:
<td onclick="ViewProfile('#item.CustomerId')"></td>
Java script file
function ViewProfile(id) {
console.log("sucsses");
$.ajax({
type:"GET",
url: "/ViewUserProfile/Index",
data: { "userId": id }
});
};
Controller: ViewUserProfileController
public ActionResult Index(string userId)
{
var ProfileInformation = new UserProfileVM
{
//some logic here
};
return View(ProfileInformation);
}
You are fetching ViewUserProfile in $.ajax but you are not using .done(function() { }) to process the result you receive from that call.
In your case I would simply suggest to use window.location.href in ViewUserProfile() as below.
function ViewProfile(id) {
window.location.href = "/ViewUserProfile/Index?userId=" + id;
}

Add a new method to a jQuery UI widget

The jQuery UI docs give an example of extending an existing UI widget method, like this:
$.widget("ui.dialog", $.ui.dialog,
{
open: function()
{
console.log("open");
return this._super();
}
});
That works for me using UI 1.12.1, I see the expected log entry when a dialog is opened.
However, using the same technique to recreate the removed .url() method of jQuery UI Tabs does not, throws the error "Uncaught TypeError: $(...).url is not a function". This is my code:
$.widget("ui.tabs", $.ui.tabs,
{
url: function (index, url)
{
console.log("url");
$(this.data("uiTabs").anchors[index]).attr("href", url);
return this;
}
});
What's the difference here, besides the fact that the url() method is being created rather than extended? Is it possible to do what I'm attempting?
It is possible however I am unsure of that line after the log, i.e. the .data() method seems invalid here?
Perhaps you meant this:
$.widget("ui.tabs", $.ui.tabs, {
url: function(index, url) {
$(this.anchors[index]).attr("href", url);
}
});

ajax request php class function

i have content listed in a div and i have a dropdown with various options to order and filter that content.
I'm using ajax to filter/order that content and is working but i use other php page with the content i want on the div that has the content, like this
function order(str){
$.post("order_products.php",
{
q: str,
},
function(data, status){
document.getElementById("txtHint").innerHTML = data;
});
}
What i wanted was to instead of putting the code (data) to change in another page just for that, i could put that code inside a class php function that i have.
<?php
class products{
function list(){
blablabla
}
That way i would "save space" and organize everything, considering that i have many other things to order/filter but i don't know to to make the ajax request to that function, or if it's possible without having a page in between and then get the response from the function and put it on the div.
You can do this using Laravel by setting up a route to a function that will do the ordering. Please note I've made a lot of assumptions in the following answer as I can't see all your code and have made it quite general, please adjust the code to your project or provide more details of your code if you don't understand the answer fully.
routes.php
Route::post('products/order', [
'as' => 'products.order',
'uses' => 'ProductsController#orderProducts'
]);
Your view (assuming you're using blade)
$txtHint = $('#txtHint'); // grab the reference to txtHint dropdown
$.post( '{{ route("products.order") }}', // hit our route
{
q: str,
},
function(data, status){
$txtHint.empty(); // clear the dropdown
// loop through the data and assign each element to the dropdown
$.each(data, function(value, key) {
$txtHint.append($("<option></option>")
.attr("value", value)
.text(key));
});
});
ProductsController.php
public function orderProducts()
{
$orderBy = \Input::get('q');
return \Products::lists('name', 'id')->orderBy($orderBy);
}
For outside of a framework just change the url to your php file and add in a data attribute for the method you require to be fired from the file.
$.post( 'products.php', // hit our route
{
action: 'order',
q: str,
},
...
Then in products.php you'd do something like this
if(isset($_POST['action']) && !empty($_POST['action'])) {
$action = $_POST['action'];
switch($action) {
case 'order' : order();break;
case 'otherFunction' : otherFunction();break;
}
}
function order()
{
// order logic here
// get $_POST['q']
// do your ordering
// return data as json
}
See here for similar question: using jquery $.ajax to call a PHP function

When I update a panel with Ajax, do I need to set all events in that moment?

I'm gonna show some pieces of my code. In my razor view, I've got a HTMLForm, and I want to use it with Ajax.
Look the following code for submit.
var editQuestionFormSubmit = function () {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
$('#target2').html(result);
//$("#editQuestionForm").submit(editQuestionFormSubmit);
}
});
return false;
};
var editQuestion = function () {
$.ajax({
url: this.href,
type: "get",
success: function (result) {
$("#target2").html = result;
$("#editQuestionForm").submit(editQuestionFormSubmit);
}
});
return false;
};
The editQuestion function is for the first time when the user does click in a hyperlink, with it the result contains a form and that's the reason why I've set it the submit event.
Now, when the user does the post, let's go to imagine that it's not validated, so I show again the same form but with the current model
public ActionResult EditQuestion(QuestionTemplate qt)
{
if (ModelState.IsValid)
{
....
return ...
}
return PartialView("_EditQuestion", qt);
}
So, the last code I return the same form but displaying the errors to validate and again I have to register the submit event handler. Am I doing a good approach or are there better ways to not register each event handler in each callback.
Darf,
In the case of a submit event, handling cannot be delegated to an ancestor element because the event does not bubble. That denies you of the first choice approach to handling events arising from dynamically added elements.
So, with your approach to validation, you would have to attach the submit event handler each time the form is replaced.
However, you should be able to avoid the need to do so by replacing only the contents of the form (its .html()), leaving an original, hard-coded <form> element in place in the document.

Returning an List<> with JsonResult

I am using jQuery to consume my action.
$.ajax({ url: '',
data: 'json',
type: 'post',
dataType: options.dataType,
async: false,
success: function (obj) { returnValue = obj; }
});
now....
if I return this one...
var test1 = Json(new { Message = "Any message here.", Status="True" });
the return on my Ajax call is JUST fine..
BUT.. if i return this one(List of users from EF)
var test2 = Json(IoC.Resolve<IUserService>().GetUsers());
I will get undefined/500 (Internal Server Error).
Now the question is how to properly return a JSON from an object so that jQuery ajax can read it properly?
Thanks
Lee,
Have never seen the usage:
var test2 = Json(IoC.Resolve<IUserService>().GetUsers());
before and am not going to comment. However, you MAY get away with merely adding a .ToList() to the end of the statament, i.e.:
var test2 = Json(IoC.Resolve<IUserService>().GetUsers().ToList());
The reason for the issue is due to the fact that you haven't yet enumerated the object out before attempting to populate the json object, therefore you experience all sorts of latency and object reference problems. By adding ToList() you mitigate these problems as the object is fully enumerated before it hits the Json() method.
it might just work, ... or blow right up :)
public ActionResult MethodName(){
var returnList = IoC.Resolve<IUserService>().GetUsers().ToList();
retun JSON(returnList,JSONRequestBehaviour.AllowGet);
}
jQuery Function
success: function (obj) {
alert(obj.d.ListProperty);
// you can access all the properties you have in the list.
}

Resources