I am trying to use selectize.js to populate a combo-box on a form in my application.
I am trying to follow the "Rotten Tomatoes" model on the selectize web page. But I am a little puzzled about the timing of this call. The author prefers to initialize the select with a little <script> immediately following the specification of the <select> in the html file, but I would rather keep all my script in a separate js file.
Anyway I do the following
function loadSelect()
{
var myAPI = "my/api/";
var count = 0;
console.log('in loadSelect()');
$('#myselect').empty();
$('#myselect').selectize({
valueField: 'id',
labelField: 'name',
searchField: 'name',
options: [],
create: true,
load: function(query, callback) {
console.log("loading data");
if (!query.length) {
console.log("no data loaded");
return callback();
}
$.ajax({
url: myAPI,
type: 'GET',
dataType: 'json',
data: {
q: query,
},
error: function() {
console.log("failure");
callback();
},
success: function(res) {
console.log("success");
count = res.data.length;
callback(res.data);
}
});
}
});
}
No matter when I call this loadSelect() function, whether it be from the $(document).ready(function(){ or directly from the html page after the declaration of the select as the selectize author does, I find that the load() method never gets called. Note the console.log statements. The first one, 'in loadSelect()' always fires but any logs inside the load() function never fire.
Project documentation describes the load callback as follows:
Invoked when new options should be loaded from the server.
but this begs the question when should new options be loaded from the server.
In any event, what can I do to insure that load callback fires?
add the option preload:true to the array of options passed to the selectize call.
Related
I'm using Vue.js to modify my DOM. I'm triggering the fetch_data() method which trying to update data.messages to read 'Love the Vue.JS' after the successful completion of the AJAX call.
The AJAX call is working successfully and it does indeed update data.message in this line:
self.message = 'Love the Vue.JS'
I can see it works because it prints in the console. The problem is that the DOM is not updating with the new definition of data.message. How do I get this to work and update the DOM when the data is updated?
var app = new Vue({
delimiters: ['[[', ']]'],
el: '#app',
data: { message: 'Hello Vue.js!' },
methods: {
fetch_data: function() {
console.log('Running script for ajax...');
$("#retrieve_data_wait").text("Retrieving data. This will update when complete...");
$.ajax({
url: '/test_json',
dataType: 'json',
timeout: 60000,
success: function(data) {
$("#retrieve_data_wait").text(data.test);
self.message = 'Love the Vue.JS';
console.log('SUCCESS')
console.log(self.message);
},
error: function(data) {
$("#retrieve_data_wait").text("Fail");
}
// error: function(jqXHR, status, errorThrown) {
// //the status returned will be "timeout"
// alert('Got an error (or reached time out) for data generation. Please refresh page and try again. If you see this more than once, please contact your customer success agent.');
// }
});
}
}
})
<div id="app">
<span id="retrieve_data_wait"></span>
</div>
The problem is that your this context gets lost when you call out to jQuery. The callback method you have (success: function) doesn't have a reference back to Vue. The way to pass the correct context is, conveniently enough, the context property in your $.ajax call.
It's all documented at the jQuery site: https://api.jquery.com/jQuery.ajax/ - just search for the word "context" and you'll find it.
Your improved ajax call should look something like this:
$.ajax({
url: '/test_json',
context: this,
// [... etc ...]
success: function(data) {
this.message = "reference to Vue data message";
}
);
You can just bind the ajax call to the parent component Vue, by adding bind(this) at the end of the ajax success sentence. It would look like the following (I have updated, I realized I had a flaw, now it should work):
$.ajax({
url: '/test_json',
// etc.
//... etc.
success: function(data) {
this.message = "reference to Vue data message";
}bind(this),
);
I am using a jQuery plugin called Maplacejs (https://maplacejs.com/) to make Google Maps manipulation easier for me (I am new with this subject).
I first create a variable to set (initialize) Maplace:
var maplace = new Maplace({
map_div: '#mappanel',
controls_type: 'dropdown',
controls_title: 'Select a point:',
controls_position: google.maps.ControlPosition.TOP_LEFT
});
Then I create a function to load the locations in Maplace using ajax, when a certain date is selected in a dropdown menu:
function loadMap() {
$.ajax({
url: 'includes/ajax_getmap.php',
type: 'POST',
cache: false,
timeout: 5000,
data: { date: $('#dateselect').val() },
dataType: 'json',
success: function(data) {
maplace.SetLocations(data.locations, true);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown)
}
});
}
Here is an example of the locations array loaded with ajax:
{"locations":[
{"lat":52.1,"lon":11.3,"title":"Title 1","html":"<h3>Content 1</h3>","zoom":8},
{"lat":51.2,"lon":22.2,"title":"Title 2","html":"<h3>Content 2</h3>","zoom":8},
{"lat":49.4,"lon":35.9,"title":"Title 3","html":"<h3>Content 3</h3>","zoom":8},
{"lat":47.8,"lon":15.6,"title":"Title 4","html":"<h3>Content D2</h3>","zoom":8}
]}
And here is the code used to "call" the function (list of dates):
$('#dateselect').selectmenu({
style: 'dropdown',
change: function(event, data) {
loadMap();
}
});
The problem is: everytime this function is called, controls get duplicated in the map. Here is an example image after I call the function 3 times:
I already tried to create the maplace variable inside the ajax "sucess" event, and even set the variable to "null" or "undefined", but without sucess :(
Please, can you help me?
For whom have the same problem, it was an issue and was fixed by latest version 0.2.8 (March 2017). Download last version here.
See the following code snippet:
$("#someid").autocomplete({
source: function (req, resp) {
$.ajax({
url: "/api/someapi",
type: "GET",
dataType: "json",
data: { id: req.someid },
beforeSend : function()
{
},
success: function (data) {
resp($.map(data, function (item) {
return {
label: "<div class='result'>" + item.name + "</div>",
value: item.Name,
emailName: item.EmailName
};
}));
}
}
});
});
My questions are listed below:
the source of ajax call is a function - function(req, resp) - does jQuery accept a function with two parameters as source data provider? Is this by default?
Can any one explain the function after success:? Basically, I could get that it uses the data from ajax response; map each data to one item with some css decoration. But my question is: what's the goal of wrapping $.map with resp?
We can see that there're a couple of callbacks in this code snippet. However, since I'm pretty new to jQuery, I wonder how to determine how many parameters to pass into each callback, say after source: we can have a callback with two parameters; after $.map, we can have another callback with only one parameter ?
yes we can pass multiple parameters, It depends upon event which is being called & how it defined.
Success is callback for Ajax being called for autocomplete feature.
You should read documentation of such functions on jQuery website.
jQuery API Doc
I am trying to get typeahead (v0.10.5)/bloodhound to bind the returned JSON data. Unfortunately, nothing appears in my suggestion window (ie, <input >). In addition, I am using jQuery v2.0.3.
The call to my endpoint is successful. When I inspect the results in Chrome, I see a properly formatted Response (ie, data and Content-type). There are no errors appearing in the Chrome's console window. There is an example of the JSON below.
I have inserted debugger; statements in the code but they are not getting hit.
The jqXHR.setRequestHeader() is there because I was making some cross site calls.
Html code
<div id="remote">
<input class="typeahead" type="text" placeholder="Prescription names">
</div>
Javascript code
I left the // debugger; statements to show where I was trying to add breakpoints.
<script type="text/javascript">
$(document).ready(function () {
var prescriptions = new Bloodhound({
datumTokenizer: function (d) { return Bloodhound.tokenizers.whitespace(d.value); },
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/Prescription/GetPrescriptions/?searchTerm=%QUERY',
filter: function (prescriptions) {
//debugger;
return $.map(prescriptions, function (user) {
//debugger;
return {
value: user.Name
};
});
},
ajax: {
type: 'GET',
dataType: 'jsonp',
beforeSend: function (jqXHR, settings) {
var authHeaders;
// pull apart jqXHR, set authHeaders to what it should be
//debugger;
jqXHR.setRequestHeader('Access-Control-Allow-Origin', '*');
}
}
}
});
// initialize the bloodhound suggestion engine
prescriptions.initialize();
// instantiate the typeahead UI
$('#remote .typeahead').typeahead({
minLength: 3,
highlight: true,
hint: true
},
{
name: 'prescriptions',
displayKey: 'value',
source: prescriptions.ttAdapter()
});
});
</script>
JSON Result
[{"Name":"Drug1"}]
Any thoughts would be appreciated.
Steve
The issue I had with my code turned out to be the dataType: "jsonp" statement. I went through a number of iterations of my code. At one point, I was referencing an different domain. Which led me to use the jsonp datatype.
In the end, I am referencing a Relative Url which did not need to have the jsonp datatype.
I changed the ajax call to dataType: "json" and it was fixed.
I am having one of those ajax asynchronous problems. I have this function which accepts two parameters to send data to the server by jquery ajax. I know this can be done by using promises and callback functions but this is my specific problem.
function fillLightbox(id, text, callback)
{
// get json request of studyunit details
$.ajax(
{
type: 'GET',
url: 'updateExam',
data:
{
get_details: true,
exam_code: text,
event_id: id
},
dataType: 'json',
success: callback
});
}
That is my ajax request, then I have this function for an API:
scheduler.createGridView(
{
name:"grid",
fields:
[
{id:"text", label:'Unit Code', sort:'str', width:200},
{id:"date", label:'Date', sort:'date', width:'*'},
{id:"exam-title", label:'Title', sort:'str', width:'*',
template: function(start, end, ev)
{
fillLightbox(ev.id, ev.text, function(data)
{
var title = data.title;
// i can get my data here..
});
return title; // how can I do this?
}
}
]
});
My question is how can I modify the template function available in this API to be able to return the property. i.e. can I somehow pass a callback function there as well?
Please do not suggest async: false (This obviously works but lags on the browser)
EDIT: more details about Create Grid View template are found here: http://docs.dhtmlx.com/scheduler/grid_view.html#datatemplates
Thanks for your help