Using select2: When using transport-function, results are not selectable - javascript

I am using the select2 plugin and I need to to use the transport-function to perform the ajax request on my own, because I need to set API Keys in the request-header. But as soon as I do this, select2 responses the results correctly and also formats and displays it like I want, but the results shown are not selectable. I can neither click at them, nor navigate to them with the arrow-keys, nor is there any mouseover effect when I go over them with the mouse.
Here's some code (I want to show suggestions for usernames):
ajax: {
data: function (term, page) {
return {
Searchtext: term
};
},
transport: function(queryParams){
// Api.Ajax delivers { Ajax: *the $.ajax object*, RequestId: *some requestId* }
var req = Api.Ajax("/api/suggestion/share/" + queryParams.data.Searchtext, "POST", { UserOnly: true }, queryParams.success);
return req.Ajax;
},
// parse the results into the format expected by Select2.
results: function(resp, page) {
return {
results: resp.Data,
more: false
};
}
},
Like I said, as soon as I use my own Ajax-function by implementing the transport-function, the results in the dropdown list are all shown, but not selectable.
Is this a bug, or am I doing something wrong?

#thnew This Answer will show you how to set request headers without requiring the transport function.

Related

How to specify function to use using an object in JS

I am trying to build a function that allows users to retrieve data from the database, but in a dynamic way. So allowing them to specify the source table, as well as which columns they would like to retrieve.
I have already built out the part that allows them to choose the table and columns, and these users only have access to data we are happy for them to retrieve.
I want this to be as dynamic as possible, so I am building a function to help me with this. I have run into one problem though so far. I have this function:
const modelMap = (model, action, criteria, options) => {
const models = {
EXTERNAL_USER: {
READ: services.externalUser.readExternalUser(criteria, options),
},
TASK: {
READ: services.task.readTask(criteria, options),
},
USER: {
READ: services.user.readUser(criteria, options),
},
}
return models[model][action]
}
So, for example, I call this function using
modelMap('EXTERNAL_USER', 'READ', { id: userID }, { populates: ['documents'] }).
This returns the data I want, however I get an ``OperationError` in my terminal:
OperationalError [UsageError]: Invalid populate(s).
Details:
Could not populate `documents`. There is no attribute named `documents` defined in this model.
The error is saying that the Task model has no attribute documents, which it doesn't. So I am guessing that even though I am not trying to access the readTask function, it is being called anyway. How can I get around this?
SOLUTION
I altered the models object to the following:
const models = {
EXTERNAL_USER: {
READ: () => services.externalUser.readExternalUsers(criteria, options),
},
TASK: {
READ: () => services.task.readTask(criteria, options),
},
USER: {
READ: () => services.user.readUser(criteria, options),
},
}
And I can then use await modelMap(model, action, criteria, options)() to get the data I need.
Yes. The functions called anyway

URL is updating but Ajax call still going to old one

I am editing someone else project and they have used a lot of DOM which I'm not familiar with.
First select box
<select name="task_projectid" id="task_projectid"
data-assigned-dropdown="assigned"
data-ajax--url="/feed/projects?ref=general"></select>
When user select project I'm using following to update the data-ajax--url in task_itemid
$(document).on('change', '#task_projectid', function() {
$('#task_itemid').attr('data-ajax--url', '/feed/items?ref=' + this.value);
});
here is task_itemid box
<select name="task_itemid" id="task_itemid"
data-assigned-dropdown="assigned"
data-ajax--url="/feed/items?ref=">
</select>
It's working and url on task_itemid changed to
/feed/items?ref=4
But the Ajax call still going to
/feed/items?ref=
Please help.
I found this
$(".js-select2-basic-search-modal").select2({
theme: "bootstrap",
width: null,
containerCssClass: ':all:',
minimumInputLength: 1,
minimumResultsForSearch: 1,
ajax: {
dataType: "json",
type: "GET",
data: function (params) {
var queryParameters = {
term: params.term
}
return queryParameters;
},
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.value,
id: item.id
}
})
};
}
}
});
See the documentation:
It is recommended that you declare your configuration options by passing in an object when initializing Select2. However, you may also define your configuration options by using the HTML5 data-* attributes, which will override any options set when initializing Select2 and any defaults.
You're changing the attribute, but by that time Select2 has already been initialised and read the old value.
I think you can use the dynamic urls feature to read the value when the Ajax request is triggered.
ajax: {
url: () => $('#task_itemid').attr('data-ajax--url'),
I haven't tested this, and it might override the logic for adding a query string to the URL, in which case you'll need to make that function add the data from params.term too.

Vue JS 2 data manipulation

I have an instance of mounted in Vue, where I'm trying to set a date picker having the starting date depends on a data fed by an ajax response. Let's say this data property is named start_date. I run my ajax request via the created instance in Vue.
It's a little weird when I tried to console log vm.myObject, it shows the correct value start_date property coming from the ajax response. However, whenever I access the specific property via vm.myObject.start_date it will show you the default one I've created for data binding. My code structure below:
<script>
export default {
mounted() {
const vm = this;
console.log(vm.myObject); // this will show the data from ajax response
console.log(vm.myObject.start_date); //this will show the default value I set which si the 2017-10-25
},
created() {
const self = this;
$.ajax({
url: ApiRoutes.paths.GetDealData,
data: { id: 1 },
success: function(res) {
self.myObject.start_date = res.start_date;
}
});
},
data() {
return {
myObject: { start_date: "2017-10-25" }
};
}
};
</script>
I'm very new to Vue JS, so I'm currently having a hard time handling the data in the component via ajax request. I've already tried all the instances included beforeCreate, beforeMount but it didn't fix my issue still. How can I understand this kind of behavior?
Your code can't really work the way you described in your answer.
you are doing asynchronous operation (ajax call) and try to print the values right after synchronous operation? nope.
If you want to console.log(response) , you can do it in your callback function.
If you want to print the value on the page, but show nothing until the value is fetched (asynchronous operation), you can define on your data an attribute that signal if the fectching process is finished or not. and toggle it inside your callback.
I have edited the code to show how to declare the date-picker (have to be declared from the template side.
You have to pass the start_date as a props (I assume the prop name for the date-picker is start-date). when the ajax request is finished, the reactivity of vue will take care of re-rendering of the date-picker
<template>
<div>
<datePicker :start-date="myObject.start_date" />
</div>
</template>
<script>
export default {
created() {
$.ajax({
url: ApiRoutes.paths.GetDealData,
data: { id: 1 },
success: function(res) {
self.myObject.start_date = res.start_date;
self.isFetchedFinished = true
}
});
},
data() {
return {
startDate: ''
};
}
};
</script>
The reason is console.log() working before AJAX response is returned, so console.log(vm.myObject.start_date) prints unchanging string with initial value. However, console.log(vm.myObject) prints your object, which then changes, and you can see actual property value in browser console.
Example:
var obj = { "name": "oldName" };
console.log(obj);
obj.name = "newName";
If you want a "frozen" version of your object, you can create a copy for logging:
console.log(Object.assign({}, vm.myObject));
Also, instead self.myObject.start_date = res.start_date; you probably want to use this.$set(this.myObject, 'start_date', res.start_date); for change tracking.

Cannot get response content in mithril

I've been trying to make a request to a NodeJS API. For the client, I am using the Mithril framework. I used their first example to make the request and obtain data:
var Model = {
getAll: function() {
return m.request({method: "GET", url: "http://localhost:3000/store/all"});
}
};
var Component = {
controller: function() {
var stores = Model.getAll();
alert(stores); // The alert box shows exactly this: function (){return arguments.length&&(a=arguments[0]),a}
alert(stores()); // Alert box: undefined
},
view: function(controller) {
...
}
};
After running this I noticed through Chrome Developer Tools that the API is responding correctly with the following:
[{"name":"Mike"},{"name":"Zeza"}]
I can't find a way to obtain this data into the controller. They mentioned that using this method, the var may hold undefined until the request is completed, so I followed the next example by adding:
var stores = m.prop([]);
Before the model and changing the request to:
return m.request({method: "GET", url: "http://localhost:3000/store/all"}).then(stores);
I might be doing something wrong because I get the same result.
The objective is to get the data from the response and send it to the view to iterate.
Explanation:
m.request is a function, m.request.then() too, that is why "store" value is:
"function (){return arguments.length&&(a=arguments[0]),a}"
"stores()" is undefined, because you do an async ajax request, so you cannot get the result immediately, need to wait a bit. If you try to run "stores()" after some delay, your data will be there. That is why you basically need promises("then" feature). Function that is passed as a parameter of "then(param)" is executed when response is ready.
Working sample:
You can start playing with this sample, and implement what you need:
var Model = {
getAll: function() {
return m.request({method: "GET", url: "http://www.w3schools.com/angular/customers.php"});
}
};
var Component = {
controller: function() {
var records = Model.getAll();
return {
records: records
}
},
view: function(ctrl) {
return m("div", [
ctrl.records().records.map(function(record) {
return m("div", record.Name);
})
]);
}
};
m.mount(document.body, Component);
If you have more questions, feel free to ask here.

jquery.couchdb.js Ajax success/error not being called

I'm using jquery.couchdb.js to query my CouchDB database. The view I want to query has both map and reduce functions within. When sending the basic query as shown below:
$(document).ready(function() {
view_name = db_name+'/jobs_by_mod_stat'
options = {'group': 'true' , 'reduce': 'true' };
mod_stat = {};
$db.view(view_name , {
success: function(data) {
console.log(data)
for (i in data.rows) {
console.log(data.rows[i].value);
}
},
error: function(e) {
alert('Error loading from database: ' + e);
}
});
});
I see a sensible log for the data, indicating the query has been successful. However, changing the line:
$db.view(view_name , {
To
$db.view(view_name , options, {
I don't get a success outcome from the Ajax query, but an error message is not shown either. Firebug shows the query being sent, and the JSON data returned looks sensible:
{"rows":[
{"key":["template","completed"],"value":2},
{"key":["template","running"],"value":2},
{"key":["template","waiting"],"value":6}
]}
But the success function is not entered. Any ideas why I'm seeing this behaviour, I did wonder if it's a bug in jquery.couch.js (I have couchdb 1.1.0).
Cheers.
I've had a bit of trouble myself with the list function, until I went and looked through the source code of jquery.couch.js (the online documentation I found at http://bradley-holt.com/2011/07/couchdb-jquery-plugin-reference/ seems to be outdated).
Basically, the parameters for view and list are different, the list having an extra parameter for the options, instead of having everything under the same parameter as with views.
View:
$.couch.db('yourdb').view('couchapp/' + viewName, {
keys: ['keys here'],
success: function (data) {
}
});
List:
$.couch.db('yourdb').list('couchapp/' + listName, viewName, {
keys: ['keys here']
}, {
success: function (data) {
}
});

Categories