I am using AngularJs + Select2. I am trying to get the data from remote. Below is my code
HTML :
<div class="col-md-4 left">
<input type="text" style="width:300px" ui-select2="multi" ng-model="multi2Value" multiple="multiple" />
</div>
JS : [UPDATED]
$scope.multi = {
ajax: {
headers: { 'Content-Type': 'application/json' },
url: "http://localhost:63591/Lookup?lookup=Lookup&key=acc",
data: function (term, page) {
return {};
},
results: function (data, page) {
console.log(data);
return {results: data.LookupValue};
}
}
And my response will be
{ "LookupValue" : [ "AAAA","BBBB","CCC" ] }
But in the console i am seeing the response. But it is not loading into the select dropdown.
What went wrong in my code. Can anyone plz help me ? Thanks
I think that you must your response save in some scope variable like $scope.listLookup and return it in your ajax, and after this step, try to bind it in HTML like:
<select ui-select2 ng-model="multi2Value" data-placeholder="Pick a Lookup">
<option value=""></option>
<option ng-repeat="lookup in listLookup " value="{{lookup.value}}">{{lookup.text}}</option>
</select>
where lookup is every item in your list if items of listLookup, and value and text are some dummy properties of lookup...
Take look on this article, hope that you understand the idea.
instead of
return {results: data};
use
return {results: data.LookupValue};
It might be either array of primitive types
[string,string,string]
or array of objects
[{},{},{}]
as well as :
data: function (term, page) {
return {
q: term, //search term
page: page // page number
};
},
Related
Using select2.js to retrieve remote data bound to a hidden input.
<input type="hidden" id="departmentNameEntry" style="width:300px"/>
I have set the placeholder in the initialization:
$("#departmentNameEntry").select2({
placeholder: "Search for a department",
minimumInputLength: 2,
ajax: {
url: "Handlers/DeptNameSearch_handler.ashx",
cache: false,
dataType: 'json',
type: 'GET',
data: function (term, page) {
return {
departmentNameFragment: term // search term entered into querystring for handler
};
},
results: function (data, page) { // parse the results into the format expected by Select2.
return { results: data };
}
},
formatResult: function (item) {
return item.text;
},
formatSelection: formatDepartmentNames,
formatNoMatches: function (term) {
return 'no department name matches your query';
}
});
But as soon as an item is selected, the placeholder goes blank. How can I reset it to the original string? I have tried placing the init code in a separate function and execing it again, but no joy. Other questions I have seen answered seem to be specific to binding to a SELECT. What am I doing wrong?
I didn't RTFM closely enough.
The formatSelection option requires you to return a string that is then displayed in the select2 in place of the placeholder text. Here is my function:
function formatDepartmentNames(dept) {
$('#hfDepartmentID').val(dept.id); // when user has selected from the list, put id in an input
$('#hfDepartmentName').val(dept.text); // stash the dept name for later
DepartmentCurrentBossesGet(dept.id, dept.text); // call another function
DepartmentBossHistoryGet(dept.id); // call yet another function
$('.row4').show(); // show useful data on the page
return dept.text; // return the dept name so select2 can display it
}
Hopes this helps someone.
I am making a request management system for my company.
The requirements are:
-Able to add a new row of the request.
-Choosing the description of the request will generate the parameters to be chosen. Parameters are on the same row as its respective description.
-Store the description and parameter as an array.
To approach this, we've used vue.js to do scripting within a blade template in the Laravel framework.
Vue.component('request', {
props: ["index"],
// Template for every individual row of test
template: `
<tr>
<td>#{{ index }}</td>
<td>
<select :name="description" #change="populate" required>
<option value="" selected disabled>--Select--</option>
#foreach ($types->sortBy('description') as $types)
<option value="{{$types->description}}">{{$types->description}}</option>
#endforeach
</select>
</td>
<td>
<select :name="parameter" required >
<option >#{{ shared.parameter.parameter1 }}</option>
<option >#{{ shared.parameter.parameter2 }}</option>
<option >#{{ shared.parameter.parameter3 }}</option>
</select>
</td>
`,
data(){
return{
// bind the name field of the form, for submission
shared: store,
description: 'tests['+this.index+'][description]',
parameters: 'tests['+this.index+'][parameter]',
something: 2,
}
}
,
methods: {
populate: ()=>{
var self = this.index;
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url:'/parametersByDescription',//this is specified in web routes
type: 'POST',
data: {description: this.description},
success: function(data){
store.parameter = data;
}
})
return;
}
}
})
let store = {
parameter: [],
index increases with a function in methods of root. A new row is also added when done so. The whole basis of adding another row is the reason a large chunk of the form is generated by the template in vue.component request. The populate function sends my description through data: to the function in my controller specified by the URL.
This is where I start having problems. I need to parse the description I have selected in the form in the populate function, however I can't find the specific term to use. In Vue Devtools, I can see description as one of the data values but I get Uncaught TypeError: Cannot read property 'description' of undefined when I try to parse this.description. I have also hard-coded the value of 2 into something and tried to parse it, however the same error appears. I just need to get this particular description value and everything else should run smoothly. Thank you for your time.
The this in this.description refers to the ajax object, declare let self = this; so it becomes self; self.description.
Also as a side note, use Axios instead of Ajax, it saves you from a lot of trouble.
I made a simple change in syntax together with the suggestion made by #Quinten and it works now.
data: function(){
return{
// bind the name field of the form, for submission
shared: store,
description: 'tests['+this.index+'][description]',
parameters: 'tests['+this.index+'][parameter]',
something: 2, //some placeholder value, I am adding another variable in my actual code along with the template of the component
}
}
,
methods: {
populate: function(){
var self = this.something;
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url:'/parametersByDescription',//this is specified in web routes
type: 'POST',
data: {description: self},
success: function(data){
store.parameter = data;
}
})
return;
}
}
})
Ok, I feel like I'm going crazy here. I'm using the select2 jquery plugin (version 4), and retrieving data via ajax. So you can type in a name, and it will return that contact information. But I also want to return what organization that contact is a part of.
Here is my select2 initialization:
$('#contact_id').select2({
ajax: {
url: 'example.com/contacts/select',
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term,
page: params.page
};
},
processResults: function (data) {
return {
results: data
};
},
cache: true
},
minimumInputLength: 3,
maximumSelectionLength: 1
});
And here is the data I'm returning (laravel framework):
foreach($contacts as $con) {
$results[] = [
'id' => $con->contact_id,
'text' => $con->full_name,
'org' => [
'org_id' => $con->organization_id,
'org_name' => $con->org_name
]
];
}
return response()->json($results);
So isn't 'org' supposed to be attached to either the created option or select element by select2? So I could do something like $('#contact_id').select2().find(':selected').data('data').org or $('#contact_id').select2().data('data').org or something like that?
Idealistically, this would look like:
<select>
<option value="43" data-org="{org_id:377, org_name:'Galactic Empire'}">Darth Vader</option>
</select>
I swear I confirmed this worked last week, but now it's completely ignoring that org property. I have confirmed that the json data being returned does include org with the proper org_id and org_name. I haven't been able to dig anything up online, only this snippet of documentation:
The id and text properties are required on each object, and these are the properties that Select2 uses for the internal data objects. Any additional paramters passed in with data objects will be included on the data objects that Select2 exposes.
So can anyone help me with this? I've already wasted a couple hours on this.
EDIT: Since I haven't gotten any responses, my current plan is to use the processResults callback to spawn hidden input fields or JSON blocks that I will reference later in my code. I feel like this is a hacky solution given the situation, but if there's no other way, that's what I'll do. I'd rather that than do another ajax call to get the organization. When I get around to implementing it, I'll post my solution.
Can't comment for now (low reputation).. so... answering to slick:
Including additional data (v4.0):
processResults: function (data) {
data = data.map(function (item) {
return {
id: item.id_field,
text: item.text_field,
otherfield: item.otherfield
};
});
return { results: data };
}
Reading the data:
var data=$('#contact_id').select2('data')[0];
console.log(data.otherfield);
Can't remember what I was doing wrong, but with processResults(data), data contains the full response. In my implementation below, I access this info when an item is selected:
$('#select2-box').select2({
placeholder: 'Search Existing Contacts',
ajax: {
url: '/contacts/typeahead',
dataType: 'json',
delay: 250,
data: function(params){
return {
q: params.term,
type: '',
suggestions: 1
};
},
processResults: function(data, params){
//Send the data back
return {
results: data
};
}
},
minimumInputLength: 2
}).on('select2:select', function(event) {
// This is how I got ahold of the data
var contact = event.params.data;
// contact.suggestions ...
// contact.organization_id ...
});
// Data I was returning
[
{
"id":36167, // ID USED IN SELECT2
"avatar":null,
"organization_id":28037,
"text":"John Cena - WWE", // TEXT SHOWN IN SELECT2
"suggestions":[
{
"id":28037,
"text":"WWE",
"avatar":null
},
{
"id":21509,
"text":"Kurt Angle",
"avatar":null
},
{
"id":126,
"text":"Mark Calaway",
"avatar":null
},
{
"id":129,
"text":"Ricky Steamboat",
"avatar":null
},
{
"id":131,
"text":"Brock Lesnar",
"avatar":null
}
]
}
]
I'm using select2 in order to create styled select boxes with autocomplete. I have 2 choices, load the data from a json file, or create a simple array from that json and use a workaround to populate the select tag. I read through their api examples but obviously I'm missing something. My goal is to create a drop down list with many elements, the problem is that the data is a huge array, which consists of aprox 15k cells. I tried a workaround using this code:
HTML:
<select multiple="multiple" data-placeholder="Select item" id="itemsList">
JS:
var list = $("#itemsList");
var txt = "";
for(var i=0;i<itemsArray.length;i++){
txt =txt+ '<option value='+itemsArray[i]+'>'+itemsArray[i]+'</option>';
}
list.append(txt);
This works, but obviously select2 manages things more efficiently, as this "method" takes several good seconds to load the data in to the DOM.
The second approach is to load the json straight to the select2 box and let the framework to manage the construction, but this leads me to an error: Cannot read property 'slice' of undefined.
JSfiddle here
This is the code:
HTML:
<div class="input-group" id="itemContainer">
<label> Select an item: </label>
<select multiple="multiple" data-placeholder="Items list" id="itemList">
</select>
</div>
JS:
$("select").select2({
ajax: {
//this is a small demo json to illustrate its structure
url: "https://api.myjson.com/bins/5amne",
dataType: 'json',
delay: 0,
data: function (params) {
return {
q: params.term, // search term
page: params.page
};
},
processResults: function (data, params) {
console.log(data);
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,
});
Your processData function should handle custom data format, e.g. parse it in a way that is understandable by the select2. Here's how it can be done:
processResults: function (data) {
var results = $.map(data, function (value, key) {
return {
text: key,
children: $.map(value, function (v) {
return {
id: v,
text: v
};
})
};
});
return {
results: results,
};
},
See the updated JSFiddle
Edit
If you want the select2 to handle filtering for you, there are two ways of doing that:
Adding server-side support;
Handling everything on the client.
Since you're loading data via from a static JSON file, you need to go #2. In order to do that, you first need to load all the data, parse it, and only then initialize the select2 control. You can do it like this:
function processData(data) {
return $.map(data, function (value, key) {
return {
text: key,
children: $.map(value, function (v) {
return {
id: key + v,
text: v
};
})
};
});
}
function initSelect2(data) {
$("select").select2({
data: data
});
}
$.ajax({
url: "https://api.myjson.com/bins/1n1rm",
dataType: 'json',
cache: true,
success: function (data) {
initSelect2(processData(data));
}
});
In order to use json for select2, the json format should be something like this:
{ results: [ {id:'first', text:'a'}, {id:'second', text: 'b'} ]
, more: false }
JSON format for jquery-select2 multi with ajax
Your current json doesn't seem to have the right format. I think you should change your json format.
I am working on an ASP.NET MVC 4 app. In my app, I'm trying to replace my drop down lists with the Select 2 plugin. Currently, I'm having problems loading data from my ASP.NET MVC controller. My controller looks like this:
public class MyController : System.Web.Http.ApiController
{
[ResponseType(typeof(IEnumerable<MyItem>))]
public IHttpActionResult Get(string startsWith)
{
IEnumerable<MyItem> results = MyItem.LoadAll();
List<MyItem> temp = results.ToList<MyItem>();
var filtered = temp.Where(r => r.Name.ToLower().StartsWith(startsWith.ToLower());
return Ok(filtered);
}
}
When I set a breakpoint in this code, I notice that startsWith does not have a value The fact that the breakpoint is being hit means (I think) my url property below is set correct. However, I'm not sure why startsWith is not set. I'm calling it from Select 2 using the following JavaScript:
function formatItem(item) {
console.log(item);
}
function formatSelectedItem(item) {
console.log(item);
}
$('#mySelect').select2({
placeholder: 'Search for an item',
minimumInputLength: 3,
ajax: {
url: '/api/my',
dataType: 'jsonp',
quietMillis: 150,
data: function (term, page) {
return {
startsWith: term
};
},
results: function (data, page) {
return { results: data };
}
},
formatResult: formatItem,
formatSelection: formatSelectedItem
});
When this code runs, the only thing I see in the select 2 drop down list is Loading failed. However, I know my api is getting called. I can see in fiddler that a 200 is coming back. I can even see the JSON results, which look like this:
[
{"Id":1,"TypeId":2,"Name":"Test", "CreatedOn":"2013-07-20T15:10:31.67","CreatedBy":1},{"Id":2,"TypeId":2,"Name":"Another Item","CreatedOn":"2013-07-21T16:10:31.67","CreatedBy":1}
]
I do not understand why this isn't working.
From the documentation:
Select2 provides some shortcuts that make it easy to access local data
stored in an array...
... such an array must have "id" and "text" keys.
Your json object does not contain "id" or "text" keys :) This should work though i have not tested it:
results: function (data, page) {
return { results: data, id: 'Id', text: 'Name' }
}
There's further documentation following the link on alternative key binding... I believe thats where your problem lies.
Hopefully this helps.