Selecting a value in select2 having optGroup - javascript

I'm giving following data input to select2
data = [{
"id": "all",
"text": "All",
"children": [{
"id": "item1",
"text": "item1"
}, {
"id": "item2",
"text": "item2"
}]
}];
and I'm initialising select2 as:
$(parent).select2({"data":data});
Now to select the value "item1", I did
$(parent).select2("val",["item1"]);
However instead of value "item1" value "all" is getting selected. How to select value item1?

To set the selected value using select2 you should use:
$(parent).val("item1").trigger("change");
From the release notes:
You should directly call .val on the underlying element instead. If you needed the second parameter (triggerChange), you should also
call .trigger("change") on the element.
$("select").val("1"); // instead of $("select").select2("val", "1");

JSFiddle where item1 is selected.
JS:
var data = [{
id: 'all',
text: 'All',
children: [{
id: 'item1',
text: 'item1'
}, {
id: 'item2',
text: 'item2'
}]
}];
$('.js-example-data-array').select2({data:data});
$('.js-example-data-array').select2('val',['item1']);
HTML:
<select class="js-example-data-array">
</select>

I tried to make this demo to show you that it works. The demo, uses the select tag as a selector for an empty and existing select element. Indeed, I don't know what are you meaning by parent:
<select>
</select>
<script>
data = [{
"id": "all",
"text": "All",
"children": [{
"id": "item1",
"text": "item1"
}, {
"id": "item2",
"text": "item2"
}]
}];
$('select').select2({
"data": data
});
$('select').select2("val", ["item2"]);
</script>

I'm not sure if you mean that the value "All" gets selected at start or if you want to select "item1" by code and it doesn't work. I find it strange that "All" gets selected as value since it should be treated as a category, even by adding
$(".select2-text").select2("val",["item1"]);
it won't select "All" for me. If i add
$(".select2-text").select2("val",["item2"]);
It will select "item2" for me (which means the method to select the item works, though it's not the best way, as stated in Lelio Faieta's Answer)
if i add
$(".select2-text").select2("val",["all"]);
it won't select "All" for me, it will just show me a blank select. So I think there must be an issue with your code because in a clean page there seems to be no way to select "All"
Can you show us the whole code, including the html of your page (at least the part relevant to the select). I have tried this (see plunker here: http://plnkr.co/edit/m6pFUt?p=preview )
<script>
$(document).ready(function() {
data = [{
"id": "all",
"text": "All",
"children": [{
"id": "item1",
"text": "item1"
}, {
"id": "item2",
"text": "item2"
}]
}];
$(".select2-text").select2({
"data": data
});
});
</script>
<select class="select2-text"></select>
And it starts with item1 selected, while "All" is treated as a category. So maybe it's just because something is wrong in your code/HTML.
What version of Select2 are you using? i'm using 2-4.0.0

Related

check if item exists in json file then get it if exists. And if not complete executing the code

I get a json file from outer link by ajax call. i want to check element is exists in this json file or not and get it if exists. because it changes every time and items increases or decreases. If I get item and this item not existing, I get error and the code not complete. i want to check this item json.children[1].children and json.children[2].children ,..... if exists.
{
"num": 1,
"name": "aa",
"properites": [
{
"name": "prop1",
"value": "value1"
}
],
"children": [
{
"num2": 1,
"name2": "name2",
"properites": [
{
"name": "name",
"value": "value"
}
],
"children": []
},
{
"name": 1,
"num": "1",
"attributes": [
{
"name": "name",
"value": "value"
}
],
"children": []
.......................... big json file
I have tried to get these Items and set in local storage to use in table by this:
localStorage.setItem("row1-item1", json.children[1].children);
localStorage.setItem("row1-item2", json.children[2].children);
localStorage.setItem("row1-item3", json.children[3].children);
localStorage.setItem("row1-item4", json.children[4].children);
localStorage.setItem("row2-item1", json.name[1].children);
localStorage.setItem("row2-item2", json.name[2].children);
localStorage.setItem("row2-item3", json.name[3].children);
localStorage.setItem("row2-item4", json.name[4].children);
the problem here is if json.children[4].children not existing the code not complete the next line and jump out of ajax call even if json.name[1].children is exists. I tried try/catch but not solved it
Try to use map
json.children.map((children,index)=>{
localStorage.setItem('row${index}-item${index}`, children);
}
Or you can use forEach or for loop instead of map.

How to make linked(dynamic?) select fields in oracle jet?

Im very new to JS and OJET. I'm using oracle jet to create a form. I need to create two select fields, the firts displays a client's name and the next one must change is values with the selected client's team members.
I have a JSON File with this format:
{
"clients": [
{
"id": "C01",
"name": "Client 1",
"manager": "Manager 1",
"team": [
{
"id": "C1MEM1",
"name": "member 1"
},
{
"id": "C1MEM2",
"name": "member 2"
},
{
"id": "C1MEM3",
"name": "member 3"
},
{
"id": "C1MEM4",
"name": "Member 4"
}
]
},
{
"id": "C02",
"name": "Client 2",
"manager": "Manager 2",
"team": [
{
"id": "C2MEM1",
"name": "member 1"
},
{
"id": "C2MEM2",
"name": "member 2"
},
{
"id": "C2MEM3",
"name": "member 3"
},
{
"id": "C2MEM4",
"name": "member 4"
}
]
}
I managed to create a select field with the clients name:
self.clientsListVal = ko.observableArray(['C01']);
self.clientsList = ko.observableArray();
$.getJSON("http://localhost:8000/js/json/clients.json").
then(function(data){
$.each(data["clients"],function(){
self.clientsList.push({
value: this.id,
label: this.name
});
});
});
Then I tried to get the next select fields this way, but it doesn't work :( :
self.memberList = ko.observableArray();
$.getJSON("http://localhost:8000/js/json/clients.json").
then(function(data){
$.each(data["clients"],function(){
if (this.id === self.clientsListVal ) {
$.each(this["team"], function(){
self.memberList.push({
value: this.id,
label: this.name
});
});
}
});
});
This is the HTML im using:
<div class="oj-applayout-content">
<div role="main" class="oj-hybrid-applayout-content">
<div class="oj-hybrid-padding">
<h3>Dashboard Content Area</h3>
<div>
<label for="clients">Clients</label>
<select id="clients"
data-bind="ojComponent:
{component: 'ojSelect',
options: clientsList,
value: clientsListVal,
rootAttributes: {style:'max-width:20em'}}">
</select>
<label for="select-value">Current selected value is</label>
<span id="select-value" data-bind="text: clientsListVal"></span>
<label for="members">Members</label>
<select id="members"
data-bind="ojComponent: {component: 'ojSelect',
options: memberList,
value: memberListVal,
rootAttributes: {style:'max-width:20em'}}">
</select>
</div>
</div>
</div>
Any help or hint? thank you!.
EDIT:
I think the problem is that self.clientsListVal is returning a function not the current selected value. I added console.log(self.clientsListVal) to the view model to see the current value.
If I change self.clientsListVal for a string:
if(this.id === 'C01'){}
I get the members of the client "C01".
I tried changing self.clientsListVal to $('#clients').val(), this is the id of the select input and i get undefined in the console.log.
How can I get the select field string value inside the viewmodel?
In Knockout, observables are functions -- so when you ask for the observable directly, like self.clientsListVal, you get the function definition. To get the underlying value, call the observable like a function: self.clientsListVal().
So your test becomes if (this.id === self.clientsListVal() ) {
Now you have another problem -- the observable holds an array, not an ID. The array may have a single ID element in it, but you have to reach into the array to get it.
Since you didn't show us how a value gets into clientsListVal, it's hard to say what you need to do. Is it bound to an input field where the user specifies a value? Is it populated from a data call? either way, do you ever need to have more than one ID in clientsListVal? If you only need to hold one ID at a time, change clientsListVal from an observableArray to a simple observable and your test will work.
If clientsListVal can hold multiple values, you'll need to loop over them. There are various ways to do this. You can get the underlying array by assigning the value of the observableArray to a variable: var clients = clientsListVal(). clients now holds the array, and you can use jQuery's $.each, the native Array.each, or some other way to loop over or map the array. Or you can use Knockout's built-in array utilities, like arrayForEach
if you don't want to change to a regular observable but expect the array to only have a single element, you can get at it like clientsListVal()[0] -- that's the 0th (first) element of the array. Watch out for empty arrays, tho.

How to form mongoose query for $all in array

Given this collection:
[{
"users": [{
"name": "one"
}, {
"name": "two"
}]
}, {
"users": [{
"name": "one"
}, {
"name": "three"
}]
}, {
"users": [{
"name": "fifteen"
}, {
"name": "one"
}]
}]
How can I query this using values (ie, "one" and "two") so that the findOne method returns only the document that has both "name":"one"and "name":"two" (order not relevant)? The users array will always have 2 elements, no more, no less.
I was trying something along the lines of:
Collection.findOne({"users":{$all:["one", "two"]}})
But it isn't working. Can anyone help?
EDIT: Latest attempt:
Collection.findOne({"users":{"name": {$all:["one","two"]}}})
Try this one:
{"users": {$all: [{"name": "one"}, {"name": "two"}]}}
Or use dot notation as proposed by JohnnyHK.
See here how $all is used: https://docs.mongodb.org/manual/reference/operator/query/all/
EDIT: Data was changed.
You can do this by using dot notation to identify a specific field within the array to which the $all operator should be applied:
Collection.findOne({'users.name': {$all: ['one', 'two']}})

Radio button not working within nested ng-repeats

I have a web page with check boxes & radio buttons within nested ng-repeats. When I am clicking the check boxes the underlying view model is getting updated properly, but when I click on the radio buttons, the view model is not getting updated properly. Within a group, when I select an option the selected model property gets updated to true but the other one doesn't change to false.
e.g. when I click on the radio buttons against chicken one by one, all of them becomes true. When I select any one, I want the other ones to become false
My view model is given below.
$scope.itemGroups = [{
"name": 'Non Veg',
"items": [{
"selected": false,
"name": 'Chicken',
"Portions": [{
"selected": false,
"name": '1 Cup'
}, {
"selected": false,
"name": '2 Cups'
}, {
"selected": false,
"name": '3 cups'
}]
}, {
"selected": true,
"name": 'Egg',
"Portions": [{
"selected": false,
"name": '1 Cup'
}, {
"selected": false,
"name": '2 Cups'
}, {
"selected": false,
"name": '3 cups'
}]
}]
}, {
"name": 'Veggie',
"items": [{
"selected": false,
"name": 'Potato',
"Portions": [{
"selected": false,
"name": '1 Cup'
}, {
"selected": false,
"name": '2 Cups'
}, {
"selected": false,
"name": '3 cups'
}]
}, {
"selected": false,
"name": 'Tomato',
"Portions": [{
"selected": false,
"name": '1 Cup'
}, {
"selected": false,
"name": '2 Cups'
}, {
"selected": false,
"name": '3 cups'
}]
}]
}];
The way I bind to the html:
<div ng-repeat="itemGrp in itemGroups">
<h1>{{itemGrp.name}}</h1>
<div ng-repeat="item in itemGrp.items">
<input type="checkbox" ng-model="item.selected" />{{item.name}}
<label ng-repeat="portion in item.Portions">{{portion.name}}
<input type="radio" name="radio_{{itemGrp.name}}" ng-model="portion.selected" ng-value="true" />
</label>
</div>
</div>
Fiddle: http://jsfiddle.net/awqv0rb0/16/
Can you please guide me on what can be the issue here? Is there a better way of achieving what I am trying to do here? I need to loop through the JSON and get the values of the selected items.
This is a trivial issue. I too, faced it an earlier stages.
If you are looping over a group of items and each item has a set of radio buttons, then all the radio buttons for a given item must have the 'name' attribute value as the item name.
Ex. If the item name is 'Chicken', all it's radio buttons labelled as '1 Cup', '2 Cups', '3 Cups' should have their name='{{item.name}}' i.e. 'Chicken'.
Change Point in your Code:
<input type="radio" name="{{item.name}}" ng-model="portion.selected" ng-value="true" />
Here is the JSFiddle demo
The code you have posted here doesn't quite match the fiddle you provided, but your issue is the result of giving each radio button it's own name, and therefore, it's own group. This allows all radio buttons to essentially function as check boxes and all be set to true instead of the desired behavior of allowing only one.
Instead, you should give all radio buttons under that item the same group name, like:
name="{{item.name}}"
Your nested ng-repeats should look something like this when you're done:
<div ng-repeat="item in itemGrp.items">
<input type="checkbox" ng-model="item.selected" />{{item.name}}
<label ng-repeat="portion in item.Portions">{{portion.name}}
<input type="radio" name="{{item.name}}" ng-model="portion.selected" ng-value="true" />
</label>
</div>
Updated per your Comment
To update the selected:true value of each of your portions when you change one, you'll need a little bit more code. This is a little messy, so it may not be the best solution--but I was able to get it to work.
In addition to the ng-value="true" you should also add an ng-change="toggleRadio(itemGrp,item,portion)"to your radio buttons. In your js, you should add the following function:
$scope.toggleRadio = function(itemGrp, item, obj) {
var indexOfItemGrp = $scope.itemGroups.indexOf(itemGrp);
var indexOfItem = $scope.itemGroups[indexOfItemGrp].items.indexOf(item);
var indexOfPortion = $scope.itemGroups[indexOfItemGrp].items[indexOfItem].Portions.indexOf(obj);
angular.forEach($scope.itemGroups[indexOfItemGrp].items[indexOfItem].Portions, function(value,key) {
if(indexOfPortion != key) {
value.selected = false;
}
});
};
Basically, this code will iterate through all of the portion options inside the item inside the itemGroup and update their value to false unless they were the selected option.
You can see a working example in a fork of your original fiddle that I created: here.
One More Update
Have a look at this question: AngularJS Binding Radio Buttons To Booleans Across Multiple Objects. If you can change the model of your json object, this might be a viable solution. If you can't change the model, manually updating the other values is your cleanest option.

Change Corresponding Bar Stack Color

Currently I have the following implementation which assumes all items are different; in other words, there are no common/grouped objects in the dataset. It works fine.
However, I would like to know what if there are two common/grouped objects in the dataset, is there a way to change the corresponding bar color?
For example, by looking at the last objects of following data[0] and data[1], these items name are same, and I would like to give same color to corresponding bar stack.
data[0]=[{"value":29, "series":"item1", "category":"Men", "name":"HY"},{"value":44, "series":"item2", "category":"Men","name":"NY"}]
data[1]=[{"value":16, "series":"item3", "category":"Women", "name":"RY"},{"value":23, "series":"item5", "category":"Women", "name":"NY"}]
JSfiddle
You need to add color: function(data){....} and then you can use two way,
By adding some condition either like this one the color function and refer to jsfiddle :
series: [{
type: "column",
field: "value",
stack: true,
name: "#= group.value #",
highlight: {
visible: false,
},
color: function (data) {
//check if the item fname is NY
if (data.dataItem && data.dataItem.fname == "NY") {
//give the color you wanted
return "#CC6699";
}
}
}],
Or if you want , add the color into the data like this :
data[0] = [{
"value": 29,
"series": "item1",
"category": "Men",
"fname": "NY",
"color" : "#CC6699"
}, {
"value": 44,
"series": "item2",
"category": "Men",
"fname": "GY",
"color" : "#99FF99"
}]
and the color function return data.dataItem.color

Categories

Resources