unable to update the ngmodel of select list - angularjs

Case :
I am trying to update the value of ng-model inside the controller but it is not working and i wonder why , any idea ?
HTML :
<select ng-model="dumm" ng-options="item.name as item.type for (name, item) in availableFilters" ng-change="selectFilter()"></select>
JS :
$scope.selectFilter = function () {
$scope.availableFilters[$scope.dumm].visible = true;
$scope.dumm = "";
};
$scope.availableFilters = {
name: {
type: 'Name',
name: 'name'
},
producttype: {
type: 'Product type',
name: 'producttype',
data: $scope.xxx
},
status: {
type: 'Status',
name: 'status',
data: $scope.unitStatusTypes
}
};

$scope.dumm should be an object rather than a string, otherwise the binding won't work - this fact is quite obscure in Angular's docs. The binding should look like this:
<select ng-model="dumm.value"...
and the variable's definition:
$scope.dumm = {value: ""};

Related

How to select a value for option dropdown in angularJS UnitTest

My html code is something like this and I want to select a value from dropdown and verify the same in AngularJS UnitTestCase using Jasmine
I tried using option.value but it's not working out..
<select id="company" ng-model="company" ng-change="companychange(company)" ng-options="company.ID as company.Name for company in companies"></select>
My AngularJS UnitTestCase is something like this
//somecode has been left out
$templateCache.put('selectcompany.html', directiveTemplate);
templateHtml = $templateCache.get('selectcompany.html');
formElem = angular.element('<div>' + templateHtml + '</div>');
//console.log(directiveTemplate);
$compile(formElem)($scope);
form = $scope.companyform;
companyform = form;
form2 = $compile(directiveTemplate)($scope);
$scope.$apply('companies=[{ Name: "Gold", value:0, ID: 0 },{ Name: "Silver", value:1, ID: 1 }, { Name: "Bronze", value: 2, ID: 2 }]');
}));
describe(' company ', function () {
it('selecting a dropdown ', function () {
var options = form2.find('[id="company"]')[0];
angular.element(options["value='2'"]).trigger('click');
$scope.$digest();
console.log(options.innerHTML);
expect($scope.company).toBe(2);
});
});

Vue.js filtering on array

I am trying to filter an array using a computed property in vue.js. I would like to search on on multiple fields, name, state, tags etc.
My data:
events: [
{
id: 1,
name: 'Name of event',
url: '#',
datetime: '2017-05-10T00:00:00Z',
description: 'The full text of the event',
state: 'VIC',
tags: [
'ordinary',
'advanced'
]
},
{
id: 2,
name: 'Another event',
url: '#',
datetime: '2017-05-12T00:00:00Z',
description: 'The full text of the event',
state: 'VIC',
tags: [
'beginner'
]
},
{
id: 3,
name: 'Great event',
url: '#',
datetime: '2017-05-18T00:00:00Z',
description: 'The full text of the event',
state: 'NSW',
tags: [
'beginner'
]
}
]
},
The following function works as expected, however I cant work out how to have it search the items in 'tags' (commented out).
searchevents: function(){
let result = this.events
if (this.filterValue){
result = result.filter(event =>
event.name.toLowerCase().includes(this.filterValue.toLowerCase()) ||
event.state.toLowerCase().includes(this.filterValue.toLowerCase())
// event.tags.toLowerCase().values().includes(this.filterValue.toLowerCase())
)
}
return result
}
The following returns a blank array, this method works ok when i have done it in angular but not in vue.
searchevents2: function(){
var searchRegex = new RegExp(this.filterValue,'i')
this.events.filter(function(event){
return !self.filterValue || searchRegex.test(event.name) || searchRegex.test(event.state)
})
}
Ideally I would either like to be able to list array items to filter by or just filter by the entire array.
Appreciate any help, first post here so be gentle. I have a lot more experience with Python than Javascript so i may also use incorrect terminology at times.
You weren't too far off.
For your searchEvents filter, you just needed to add the tag filter. Here's how you might do that.
searchevents: function(){
let result = this.events
if (!this.filterValue)
return result
const filterValue = this.filterValue.toLowerCase()
const filter = event =>
event.name.toLowerCase().includes(filterValue) ||
event.state.toLowerCase().includes(filterValue) ||
event.tags.some(tag => tag.toLowerCase().includes(filterValue))
return result.filter(filter)
}
Array.some() is a standard array method that returns true if any element of the array passes your test.
searchevents2: function(){
const searchRegex = new RegExp(this.filterValue,'i')
return this.events.filter(event =>
!this.filterValue || searchRegex.test(event.name) || searchRegex.test(event.state))
}
With searchEvents2 you really only left an errant self in there. Either you needed to set self before you executed the filter, or, as I have done here, turned it into an arrow function.
Example.
const app = new Vue ({
el: '#app',
data: {
search: '',
userList: [
{
id: 1,
name: "Prem"
},
{
id: 1,
name: "Chandu"
},
{
id: 1,
name: "Shravya"
}
]
},
computed: {
filteredAndSorted(){
// function to compare names
function compare(a, b) {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
}
return this.userList.filter(user => {
return user.name.toLowerCase().includes(this.search.toLowerCase())
}).sort(compare)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<div id="app">
<div class="search-wrapper">
<input type="text" v-model="search" placeholder="Search title.."/>
<label>Search Users:</label>
</div>
<ul>
<li v-for="user in filteredAndSorted">{{user.name}}</li>
</ul>
</div>

dynamically load formly typeahead options

I am using Angular Formly, and try to build a form with a Select field which allows to pick the state of a country.
The second field is a typeahead field, which allows to enter valid area names belonging to this state.
However, I am failing to dynamically change the typeahead options array.
I have taken the Typeahead type definition from the Formly Examples, and works fine with a static array of options:
formlyConfig.setType({
name: 'typeahead',
template: '<input type="text" ng-model="model[options.key]" ' +
'uib-typeahead="item for item in to.options | filter:$viewValue | limitTo:8" ' +
'class="form-control">',
wrapper: ['bootstrapLabel', 'bootstrapHasError'],
});
This is my form definition:
$scope.selectZoneFormFields = [
{
key: 'stateid',
type: 'select',
templateOptions:{
label: Constants.DIVPOL,
valueProp: 'id',
labelProp: 'nombre',
options: StatesManager.get()
}
},
{
key: 'zoneName',
type: 'typeahead',
templateOptions: {
label: 'Zona',
options: $scope.zoneNames
}
}
];
Then, I watch changes in stateid and refresh $scope.zoneNames:
$scope.$watch('geo.stateid', function(newValue, oldValue) {
if (newValue === undefined || newValue.length !== 2 || newValue === oldValue )
return;
console.log(' !!! STATE change detected: ' + oldValue + '-->' + newValue);
refreshZones(newValue);
});
The problem is that the options for the typeahead field remain those which are loaded at the beginning (initial value of $scope.zoneNames)
I have tried to use a controller inside formly field definition, but with no success.
Ideas?
{
key: 'zoneName',
type: 'typeahead',
templateOptions: {
label: 'Zona',
options: []
},
expressionProperties: {
'templateOptions.options': function($viewValue, $modelValue, $scope){
$scope.to.options = []; //set to an empty array
if($scope.model.stateid) { //if the state has been selected
$scope.to.options = //whatever code you use to get the zones
return $scope.to.options; //return the options
}
}
}
}

Error when passing filter parameter in Uigrid with cell nav

I have a editable Uigrid with ui-grid-cellnav directive to enable edit on focus. I also have a filter to display value instead of id in the dropdown.
<div ui-grid="gridOptions" ui-grid-edit ui-grid-cellnav class="grid"></div>
JS
$scope.gridOptions.columnDefs = [
{ name:'name', width:100 },
{ name:'age', width:100},
{ name: 'gender', displayName: 'Gender', editableCellTemplate: 'ui-grid/dropdownEditor', width: '20%',
cellFilter: "griddropdown:this", editDropdownIdLabel:'id',
editDropdownValueLabel: 'gender', editDropdownOptionsArray: [
{ id: 1, gender: 'male' },
{ id: 2, gender: 'female' }
] }
];
An error occurs whenever the dropdown value is modified. It seems the filter parameter is passed as a string instead of actual object, but not sure why. Works ok if I remove the cellnav directive.
Plnkr
Thanks in advance!
Interesting, I played with it a little bit and it looks like you are getting the desired results, just that occasionally ui-grid likes to pass a string as a parameter instead of the object.
If you add a check for a string in your filter it looks like you will still be getting the desired results, that's if I am understanding properly:
String check to add:
if (typeof context !== 'string') {}
Full Filter:
.filter('griddropdown', function() {
return function (input, context) {
if (typeof context !== 'string') {
var map = context.col.colDef.editDropdownOptionsArray;
var idField = context.col.colDef.editDropdownIdLabel;
var valueField = context.col.colDef.editDropdownValueLabel;
var initial = context.row.entity[context.col.field];
if (typeof map !== "undefined") {
for (var i = 0; i < map.length; i++) {
if (map[i][idField] == input) {
return map[i][valueField];
}
}
} else if (initial) {
return initial;
}
}
return input;
};
});

How to customize the UriCell's render of BackGrid

I have the following
name: "id", // The key of the model attribute
label: "User Id", // The name to display in the header
editable: false, // By default every cell in a column is editable, but *ID* shouldn't be
cell: Backgrid.UriCell.extend({
orderSeparator: ''})
}, {
Using the Backgrid.UriCell has
href: formattedValue,
title: formattedValue**,
Is there any way that define href has "session" + formatedValue ? In other words, how to customize the UriCell so I can define href different from title?
Try this:
var UriCell = Backgrid.UriCell.extend({
render: function () {
this.$el.empty();
var rawValue = this.model.get(this.column.get("name"));
var formattedValue = this.formatter.fromRaw(rawValue, this.model);
var href = _.isFunction(this.column.get("href")) ? this.column.get('href')(rawValue, formattedValue, this.model) : this.column.get('href');
this.$el.append($("<a>", {
tabIndex: -1,
href: href || rawValue,
title: this.title || formattedValue,
target: this.target
}).text(formattedValue));
this.delegateEvents();
return this;
}
});
Then, you can write this:
name: "id",
label: "User Id",
editable: false,
cell: UriCell,
href: function(rawValue, formattedValue, model){
return "session" + formattedValue;
}

Resources