angular using ui-select2 to assign an object as a model property - jquery-select2

Hypothetical example to illustrate a problem I am having using angular-UI select2. Let's say I have a screen where I want to edit a "game" model. A game, among other things has players. I want to be able to set the players via a select2 drop down menu. Here's some example code:
app.js
$scope.getGamePromise().then(function(results) {
$scope.game = results;
console.log(game.players); //prints [{name:'Joe',age: 15},{name:'Sally',age:16}]
});
$scope.players = [
{
name: 'Joe',
age: 15
},
{
name: 'Fred',
age: 14
},
{
name: 'Sally',
age: 16
},
{
name: 'Lucy',
age: 13
}
]
view.html
<select ngModel="game.players" ui-select2 multiple>
<option ng-repeat="player in players" value="player">{{ player.name }}</option>
</select>
When I want to save this 'game' object, I send the game object up to the server. The server is expecting game.players to be an array of objects. However, what is being sent up is a string. I am moderately familiar with angular, and completely new to select2. How can I get my select2 to set game.players as an array of objects instead of strings?

I guess you find another solution or you don't have the problem anymore. Anyway I post it here:
Use
<input>
instead of
<select>
Example:
<input type="hidden" ui-select2="playersCfg" ng-model="players"/>
And following configuration:
$scope.playersCfg = {
multiple: true,
allowClear: true,
data: { results: Player.query(), text: 'name' },
formatResult: function(item) {
return "<div class='select2-user-result'>" + item.name + "</div>";
},
formatSelection: function(item) {
return item.name;
}
};
Player.query()
is a resource which returns a list of player containing a name (name) and an identifier (id)
Hope it would help somebody!

Related

Form Data not submitting complete string

Could someone tell me what my form data's string ends at the comma? I'm sending a form with react with a string with foo, bar but only foo is sent in the form data. This has nothing to do with the database as in the chrome dev tools, under network, I see only one value of the string. Here's a image of my actual views:
Only Wordpress, gets submitted. Noticed the ,?
Some code, in React (I'm using react-select):
<form action="/" method="post">
<Select ref="stateSelect" options={skillsOptions} simpleValue multi={this.state.multi} value={this.state.skillsSelectValue} name="skills" onChange={this.skillsUpdateValue} valueKey="value" labelKey="name" loadOptions={this.getContributors} />
</form>
skillsUpdateValue: function(newValueCnd) {
// var str = newValueCnd.split(',');
this.setState({
skillsSelectValue: newValueCnd
});
this.setState({
skills: newValueCnd
});
},
Am I missing something from the form? Using just Rails, all words great.
Edit:
Input options:
var skillsOptions = [
{ value: 'one', name: 'One' },
{ value: 'two', name: 'Two' }
];

$filter angular returning object issue

i am working on angularjs .my LocationList having two properties ID and Name.Id are 1,11,13,14,15.
I wanted name as per exact match ID 10.but problem is i am getting more than object.i mean it's not returning exact match ID value.why it's consider 1,11,13,14 15 as well.below is my code.please let me know how to get exact match value using filter.
Name = $filter('filter')($scope.LocationList, { ID: 10});
<div ng:app="myApp">
<div ng-controller="HelloCntl">
<ul>
<li > <span>{{itemxx[0].label}}</span>
</li>
</ul>
</div>
</div>
angular.module('myApp', [])
.controller('HelloCntl', [ '$scope', '$filter', function($scope, $filter) {
$scope.items = [
{ ID: 8, label: 'item 8' },
{ ID: 9, label: 'item 9' },
{ ID: 13, label: 'item 13' } ,
{ ID: 10, label: 'item 10'},
{ ID: 1, label: 'item 1'},
{ ID: 11, label: 'item 11' },
{ ID: 12, label: 'item 12' }
];
$scope.itemxx = $filter('filter')($scope.items, { ID: 1 });
//console.log(item10);
}]);
her items ID is not ordered.so when i am trying to get value of ID 1 then its returing value of Id 13.
This should work:
angular.module('myApp',[]).filter('ID', function(){
return function(items, value){
return items.filter(function(item) { return item.ID === value });
};
});
Here's a full jsFiddle: http://jsfiddle.net/jochenvanwylick/0suogLpk/
Usage:
<li ng-repeat="item in items | ID: 10">
<span>{{item.label}}</span>
</li>
EDIT
You do not need to write a special filter as it turns out, you can just use out-of-the-box filtering:
<li ng-repeat="item in items | filter: {ID:10}">
<span>{{item.label}}</span>
</li>
EDIT 2
I misunderstood - you're trying to do this in the controller, AND there's a small catch in the AngularJS filter. By default it will treat the object property value as a string and then do a 'contains' like filter operation on it.
If you want exact matching, you'll have to utilize the 3rd argument of the filter function, the comparator and supply an exactmatch comparator:
$filter('filter')($scope.items, { ID: 1 }, function(a,b) { return a === b; });
This will effectively do a 1 === 1 comparison and thus will return true for this case and false in any other. ( http://jsfiddle.net/jochenvanwylick/0suogLpk/7/ )
Your example will return an array of objects matching ID: 1. If you have multiple items in that list, your will get multiple results.
If you know - or don't care - that there will always be excatly one match, you can get your result like this:
var Name = $filter('filter')($scope.LocationList, { ID: 1 }, true)[0];
Notice the indexer [0] on the result of $filter to get the first element in the return list. Also notice the true parameter stating that the match has to be excat (not matching 11, 12, 13, etc)
http://plnkr.co/edit/gY7yeflfpURFfWsfV0Ro?p=preview
If you still don't get the expected result, use console.log($scope.LocationList) and expect the result in the chrome(pref. for me) console window. Alternativly you can write the content like this in the HTML
{{ LocationList | json }}
To inspect the object.

Accessing values in ViewModel in a dxList - PhoneJS

So in my PhoneJS web app, I have a dxList widget, with checkboxes on each item. I want to be able to select multiple items, and then do something with them. I'm trying to bind the 'checked' binding to an observable, but I get an 'undefined' error.
Here's the code for the dxTemplate for the list
<div data-options="dxTemplate:{name:'item'}">
<span data-bind="text: $data.information"></span>
<div data-bind="dxCheckBox: { checked: check_boxes }"></div>
</div>
The problem is that check_boxes is in the viewModel, not the item array. I need to access values in the viewModel. I've tried viewModel.check_boxes, but with no success.
Here's the js code:
AppNamespace.otherView = function (params) {
var viewModel = {
my_list: [
{
key: 'Group 1',
items: [
{ information: 'Test 1' },
{ information: 'Test 2'},
{ information: 'Test 3' }
]
}
],
check_boxes: ko.observable(false),
//...etc
Has anyone had any experience with this, and is there a solution?
Thanks!
Knockout provides special properties to access parent binding contexts. In your case both $parent and $root should work.
More on this topic in Knockout docs: Binding context.

How to fetch category name of a venue from result object of fouresquare venue search?

I am developing an ios app using phonegap in which I am using foursquare venue search api for listing all the near by venues.
This is the code I have used to list the name of all the near by venues.
$.getJSON('https://api.foursquare.com/v2/venues/search?ll='+pos+'&radius=10000&client_id=2POUFAUU4ZBJ2MTDOY3S2YHR2NIT52FYW0LUTPHBMNTJFJNQ&client_secret=YFDZI1YWV3ZI5S5SPM2DZJEQIEBPIDJ5XFZBWTIKIQZVQNYM&v=20120101&limit=60',
function(data) {
console.log(pos);
$.each(data.response.venues, function(i,venues){
content = '<li id="list-item"> <p><a href="#reviewPage" onClick="reviewPageAction(this)">' + venues.name + '</li>';
/*$(content).appendTo("#names");*/
$(content).appendTo("#mer");
});
});
And now my problem is , I want to display the category name with name of each venue. I have tried the following code
venues.categories.name
but it didn't work.
Is it possible to fetch the category name of each venue.?? Please help me!!
The Venues endpoint will return all the categories assigned to a venue. There can be multiple categories assigned to a venue, one of the categories will have a field "primary" that is set to true to indicate that it is the primary category.
Look for something like this in the result set:
categories: [
{
id: "4bf58dd8d48988d143941735",
name: "Breakfast Spot",
pluralName: "Breakfast Spots",
shortName: "Breakfast",
icon: {
prefix: "https://foursquare.com/img/categories_v2/food/breakfast_",
suffix: ".png"
},
primary: true
},
{
id: "4bf58dd8d48988d16a941735",
name: "Bakery",
pluralName: "Bakeries",
shortName: "Bakery",
icon: {
prefix: "https://foursquare.com/img/categories_v2/food/bakery_",
suffix: ".png"
},
}
}
]

Select2 dropdown but allow new values by user?

I want to have a dropdown with a set of values but also allow the user to "select" a new value not listed there.
I see that select2 supports this if you are using it in tags mode, but is there a way to do it without using tags?
The excellent answer provided by #fmpwizard works for Select2 3.5.2 and below, but it will not work in 4.0.0.
Since very early on (but perhaps not as early as this question), Select2 has supported "tagging": where users can add in their own value if you allow them to. This can be enabled through the tags option, and you can play around with an example in the documentation.
$("select").select2({
tags: true
});
By default, this will create an option that has the same text as the search term that they have entered. You can modify the object that is used if you are looking to mark it in a special way, or create the object remotely once it is selected.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
}
});
In addition to serving as an easy to spot flag on the object passed in through the select2:select event, the extra property also allows you to render the option slightly differently in the result. So if you wanted to visually signal the fact that it is a new option by putting "(new)" next to it, you could do something like this.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
},
templateResult: function (data) {
var $result = $("<span></span>");
$result.text(data.text);
if (data.newOption) {
$result.append(" <em>(new)</em>");
}
return $result;
}
});
For version 4+ check this answer below by Kevin Brown
In Select2 3.5.2 and below, you can use something like:
$(selector).select2({
minimumInputLength:1,
"ajax": {
data:function (term, page) {
return { term:term, page:page };
},
dataType:"json",
quietMillis:100,
results: function (data, page) {
return {results: data.results};
},
"url": url
},
id: function(object) {
return object.text;
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return this.text.localeCompare(term)===0;
}).length===0) {
return {id:term, text:term};
}
},
});
(taken from an answer on the select2 mailing list, but cannot find the link now)
Just for the sake of keep the code alive, I'm posting #rrauenza Fiddle's code from his comment.
HTML
<input type='hidden' id='tags' style='width:300px'/>
jQuery
$("#tags").select2({
createSearchChoice:function(term, data) {
if ($(data).filter(function() {
return this.text.localeCompare(term)===0;
}).length===0)
{return {id:term, text:term};}
},
multiple: false,
data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});
Since many of these answers don't work in 4.0+, if you are using ajax, you could have the server add the new value as an option. So it would work like this:
User searches for value (which makes ajax request to server)
If value found great, return the option. If not just have the server append that option like this: [{"text":" my NEW option)","id":"0"}]
When the form is submitted just check to see if that option is in the db and if not create it before saving.
There is a better solution I think now
simply set tagging to true on the select options ?
tags: true
from https://select2.org/tagging
Improvent on #fmpwizard answer:
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return term.localeCompare(this.text)===0; //even if the this.text is undefined it works
}).length===0) {
return {id:term, text:term};
}
},
//solution to this error: Uncaught TypeError: Cannot read property 'localeCompare' of undefined
Thanks for the help guys, I used the code below within Codeigniter I I am using version: 3.5.2 of select2.
var results = [];
var location_url = <?php echo json_encode(site_url('job/location')); ?>;
$('.location_select').select2({
ajax: {
url: location_url,
dataType: 'json',
quietMillis: 100,
data: function (term) {
return {
term: term
};
},
results: function (data) {
results = [];
$.each(data, function(index, item){
results.push({
id: item.location_id,
text: item.location_name
});
});
return {
results: results
};
}
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, results) {
if ($(results).filter( function() {
return term.localeCompare(this.text)===0;
}).length===0) {
return {id:term, text:term + ' [New]'};
}
},
});
I just stumbled upon this from Kevin Brown.
https://stackoverflow.com/a/30019966/112680
All you have to do for v4.0.6 is use tags: true parameter.
var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;
In most cases we need to compare values with insensitive register. And this code will return false, which will lead to the creation of duplicate records in the database. Moreover String.prototype.localeCompare () is not supported by browser Safary and this code will not work in this browser;
return this.text.localeCompare(term)===0;
will better replace to
return this.text.toLowerCase() === term.toLowerCase();

Resources