I have a md-autocomplete field:
<md-autocomplete md-selected-item="videoInfo.lineUp[1]" md-items="item in searchQuery(searchText)" md-search-text="searchText" md-item-text="item.display"></md-autocomplete>
I populate md-items with
$scope.searchQuery = function (searchText) {
var users = [];
angular.forEach($scope.users,
function (value, key) {
// value = user object
// key = userId
var dN = value["display_name"];
if (dN) {
var obj = {};
obj[key] = value;
obj["display"] = dN;
if (dN.toLowerCase().indexOf(searchText.toLowerCase()) !== -1) {
users.push(obj);
}
}
});
return users;
}
It working in the sense that I can type in the input field and suggestions are loaded, however the dropdown is empty, i.e. it doesn't show display_name as I would have expected. When I select one of the options, the display_name of the selected item does show up in the input field. Any ideas what I could be doing wrong?
You need to define how you display information in the dropdown within the <md-autocomplete> tag. Here's an example - CodePen
Markup
<div ng-controller="AppCtrl as vm" ng-cloak="" ng-app="MyApp">
<md-autocomplete flex
md-selected-item="text"
md-no-cache="true"
md-items="item in vm.items()"
md-min-length="0">
<span id="autocompleteText" md-highlight-text="searchText">{{item}}</span>
</md-autocomplete>
</div>
https://material.angularjs.org/latest/demo/autocomplete
Related
I have an md-autocomplete component from AngularJS Material and it does not show the dropdown with the options after first click in the input, as it is supposed to shown. It shows the full list of options in the dropdown when I click on input after I've done a search and then delete the entered input. Can anyone tell what is wrong in my code?
Here is my code:
I tried the md-min-legth attribute but it does not work.
<md-autocomplete ng-disabled="false"
md-no-cache="true"
name="projectAutocompleteFormRecord"
md-selected-item="model.TimeRecord.Project"
md-items="project in querySearchForProjectRecord(searchProjectTextRecord)"
md-item-text="project.Code + (project.DerivedCode ? project.DerivedCode : '') + '-' + project.Title"
md-search-text="searchProjectTextRecord"
md-min-length="0"
placeholder="Project">
<md-item-template>
<div class="item-title">
<span md-highlight-text="searchProjectTextRecord"
md-highlight-flags="ig">
{{project.Code + (project.DerivedCode ? project.DerivedCode : "") + "-" + project.Title}}
</span>
</div>
</md-item-template>
</md-autocomplete>
<script>
// initialize of $scope.projs;
$scope.searchProjectTextRecord = "";
$scope.querySearchForProjectRecord = function (query) {
var results = [];
var projects = $scope.projs;
if (projects) {
results = query ? projects.filter(item => item.Code.toLowerCase().includes(query.toLowerCase()) ||item.Title.toLowerCase().includes(query.toLowerCase())) : projects;
}
return results;
}
</script>
I managed to fix it by adding the <md-not-found> element.
I am new to angular js. In my code user changes the value of radio buttons. And depending on the value of the selected radio button, a piece of code is loaded from the ng-switch
HTML:
<body ng-app="">
<div ng-repeat="button in modes">
<label>
<input type="radio" ng-model="data.mode" value="{{button.value}}" ng-click="clearObjectIdModal()" name="e_modes">
{button.label}}
</label>
</div>
<div ng-switch on="data.mode">
<div ng-switch-when="client">
<label for="e_selected_object_item_id">Select Client name: </label>
<select id="e_selected_object_item_id" name="e_selected_object_item_id" ng-model="currentDataItem.object_id" required>
<option ng-repeat="item in customersListArr" value="{{ item.id }}">{{ item.Name }}</option>
</select>
</div>
<div ng-switch-when="agent">
// This part is similar to the previous one
</div>
</div>
</body>
Controller part:
$scope.data = {};
$scope.setFile = function () {
if ($scope.data.mode == 'client')
return 'client';
else if ($scope.data.mode == 'agent')
return 'agent';
$scope.modes = [{
value: 'client',
label: 'Client'
},{
value: 'agent',
label: 'Agent'
}];
$scope.currentDataItem = data; // data is preloaded from inputs in form
There is also a ng-click="clearObjectIdModal()" that clears the model when switching radio buttons:
$scope.clearObjectIdModal = function() {
$scope.currentDataItem = "";
}
The problem is that every time when the radio button is switched to the select value, which dynamically changes, the value of the first option in it becomes equal to undefined. Because in the array from where these options are built there is no such object_id (This is the id that is not there, so an empty field is drawn).
That is, there are all works. But the first option in the select(after switching to another radio button) is rendered as an empty string.
There are thoughts, how it can be fixed?
I'm not sure if I understand you problem correctly but I would suggest a few improvements.
change your setFile function to as follows
$scope.setFile = function (){return $scope.data.mode;}
I also do not see the closing brackets for your function in your code. Besides if your function will only return the data.mode then why need the function?
I would suggest initialize your data object properly like:
$scope.data = {mode:'client'};
Change your clearObjectIdModal function as:
$scope.clearObjectIdModal = function(mode)
{
$scope.currentDataItem = "";
$scope.data.mode=mode;
}
and in your HTML use it as ng-click="clearObjectIdModal(button.mode)"
So in function clearObjectIdModal() I wrote:
$scope.clearObjectIdModal = function() {
if ($scope.e_data["mode"] == 'client') {
if ($scope.customersListArr.length > 0) {
$scope.currentDataItem.object_id = $scope.customersListArr[0]['id'];
}
}
else if ($scope.e_data["mode"] == 'agent') {
if ($scope.agentsListArr.length > 0) {
$scope.currentDataItem.object_id = $scope.agentsListArr[0]['id'];
}
}
}
And after this when I change radio buttons the first option in current select(which every time is changed) will be not empty.
Also the problem with an additional empty option is possible to solve when you add a title as the first item in the list:
<option value="" disabled>Select</option>
I'm using Angular Xeditable api.I need to change the text field's value according to the value of the drop down.But it's not working.Could you tell me why ? Thanks.
Html
<td>
<span editable-select="user.status" e-form="tableform" e-ng-options="s.value as s.text for s in statuses" e-ng-change="setName($data,user)">
{{ showStatus(user) }}
</span>
</td>
js
$scope.setName = function (id, user) {
var selected = [];
if (id) {
selected = $filter('filter')($scope.statuses, { value: id });
}
if (selected.length) {
user.name = selected[0].text;
}
};
Generated html : you can see that it has been changed text of the name filed as expected (status3).But it doesn't update the text box properly. In other words it doesn't show on the text box.Why ?
<td>
<!-- editable username (text with validation) -->
<span editable-text="user.name" e-form="tableform" onbeforesave="checkName($data, user.id)" class="ng-scope ng-binding editable editable-hide">
status3
</span><span class="editable-wrap editable-text ng-scope"><div class="editable-controls form-group" ng-class="{'has-error': $error}"><input type="text" class="editable-input form-control ng-pristine ng-valid" ng-model="$data"><div class="editable-error help-block ng-binding" ng-show="$error" ng-bind="$error" style="display: none;"></div></div></span>
</td>
UPDATE :
I have tried like this.But then it changes all the rows values.So how can I detect only the changed row ?
$scope.setName = function (id, user,form) {
var selected = [];
if (id) {
selected = $filter('filter')($scope.statuses, { value: id });
}
if (selected.length) {
for (var i = 0; i < form.$editables.length; i++) {
if (form.$editables[i].name === 'user.name') {
form.$editables[i].scope.$data ="sampath"
}
}
}
};
Here is the JsFiddle
I try with your old source code and it's works for me:
if (selected.length) {
user.name = selected[0].text;
}
May be i miss understand your problem.
http://jsfiddle.net/NfPcH/14573/
If I understand it right, you just want to update the text on the textbox (which is bound to the user's name) depending on the status change, right?
If so, then your UPDATED code is too complicated. Just update the property directly on the user object passed to the setName function (like in your first example). It is already bound to the textbox, so you don't have to go all the way around and update the textbox directly. That's the whole point of using angular. You update the models on the scope and the rest happens automatically.
$scope.setName = function (id, user) {
if (!id || !user) {
// Do something to handle this...
return;
}
var selected = $filter('filter')($scope.statuses, { value: id });
selected = selected.length ? selected[0] : null;
user.name = 'sampath (' + selected.text + ')';
};
Here is an udpated fiddle:
http://jsfiddle.net/NfPcH/14765/
I have the following in my autocomplete
md-autocomplete(flex-gt-sm="50"
placeholder="Select label or enter new label",
md-selected-item="ctrl.node.label",
md-items="item in ctrl.getLabels() | filter:ctrl.labelSearchText",
md-item-text="item",
md-search-text="ctrl.labelSearchText",
md-floating-label="Label")
md-item-template
span {{item}}
With the following as getLabels
this.getLabels = function() {
return Restangular.all('label').getList();
};
When I run this code it does not filter the results instead I get the entire list. Is there a way to filter these results?
I am not sure if you can filter with angular filters in the tag itself. But you can do this with lodash.filter or angular filters in the javascript function.
md-autocomplete(flex-gt-sm="50"
placeholder="Select label or enter new label",
md-selected-item="ctrl.node.label",
md-items="item in ctrl.getLabels(ctrl.labelSearchText)",
md-item-text="item",
md-search-text="ctrl.labelSearchText",
md-floating-label="Label")
md-item-template
span {{item}}
And the getLabels function.
this.getLabels = function(searchText) {
return this.$q(function (resolve) {
Restangular.all('label').getList().then(function (result) {
resolve(_.filter(result.data, function(label) {
// filter here, simple case string equality
return label === searchText;
}));
});
});
};
Yes, this is very rare situation but somehow, if i use the autocomplete as follows, i get all the dom elements blocked and i cant interact anymore with an element from my page.
This is the html-part:
<md-autocomplete style="background-color:white; height:10px;"
md-selected-item="selectedItem"
md-search-text-change="searchTextChange(searchText)"
md-search-text="searchText"
md-selected-item-change="selectedItemChange(item)"
md-items="item in querySearch(searchText) | orderBy:'text'"
md-item-text="item.text"
md-min-length="0"
placeholder="Filteren op tag"
md-menu-class="autocomplete-custom-template">
<md-item-template style="background-color:white;">
<span class="select-title">
<!--<md-icon md-svg-icon="selectboxIcon.svg"></md-icon>-->
<span class="item-tags"> {{item.text}} </span>
</span>
</md-item-template>
</md-autocomplete>
and this is the corresponding parts from my controller:
$scope.querySearch = function (query) {
var results = query ? $scope.allTags.filter($scope.createFilterFor(query)) : $scope.allTags;
return results;
}
$scope.createFilterFor = function (query) {
var lowercaseQuery = angular.lowercase(query);
return function filterFn(item) {
console.log(item);
var itemName = angular.lowercase(angular.lowercase(item.text));
return (itemName.indexOf(lowercaseQuery) === 0);
};
}
$scope.searchTextChange = function searchTextChange(text) {
$log.info('Text changed to ' + text);
}
$scope.selectedItemChange = function selectedItemChange(item) {
console.log("selected");
console.log(item);
}
ps: every functionality works fine and without error. Just clicking the clear button - as shown in the following image- causes this problem -tested in last versions of chrome and mozilla-.
There is an issue posted on github regarding this.
You can check it out here.
It is resolved in the update 0.10.1-rc4.
Update your angular-material to master.
Temporary Workaround:
CSS:
.md-scroll-mask{
position: initial
}