I am using MaterializeCSS 0.9.8 (with Angular-materialize directives) and angular 1.5.0
My objective is to generate some rows in a table, each of those rows need to have an autocomplete with basically the same autocomplete data (user list) But I can't get those working....
Here is the code I got so far, I have made a small example showing my problem.
HTML
<!DOCTYPE html>
<html lang="en" ng-app="myApp" class="no-js">
<head>
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Import materialize.css-->
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.6/css/materialize.min.css" media="screen,projection" />
<!--Import jQuery before materialize.js-->
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/js/materialize.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular-materialize/0.2.2/angular-materialize.min.js"></script>
<script type="text/javascript" src="test.js"></script>
</head>
<body>
<div ng-controller="myController" ng-init="getUsers()">
<table>
<thead>
<tr>
<th>User</th>
<th>login</th>
</tr>
</thead>
<tbody>
<tr style ="border : 1px solid silver" ng-repeat="a in accesses">
<td>
<input type="text" placeholder="User" class="autocompleteUser" ng-model='a.fullName'>
</td>
<td>{{a.login}}</td>
</tr>
</tbody>
</table>
<a id="addButton" ng-click="addAccess()" href="#">Add user</a>
{{accesses}}
</div>
</body>
</html>
test.js
'use strict';
$(document).ready(function() {
$('select').material_select();
});
// Declare app level module which depends on views, and components
var module = angular.module('myApp', ['ui.materialize'])
.controller('myController', ['$scope', function($scope) {
$scope.users = [
{login : 'jdoe', fullName : 'John Doe'},
{login : 'fbar', fullName : 'Foo Bar'},
{login : 'mmax', fullName : 'Mad Max'}
];
$scope.accesses = [];
/**
* Add a new access to the table
*/
$scope.addAccess = function() {
$scope.accesses.push({
login : '',
fullName : ''
});
};
/**
* Get all users in the DB
*/
$scope.getUsers = function () {
//Simulate HTTP request
$scope.usersAutocomplete = {
'John Doe' : null,
'Foo Bar' : null,
'Mad Max' : null
};
$('input.autocomplete').autocomplete({
data: $scope.usersAutocomplete,
limit: 20,
onAutocomplete: function(val) {
$scope.getUserByName(val);
},
minLength: 1
});
};
/**
* Get a user given his name and surname
* @param fullName name + surname
*/
$scope.getUserByName = function (fullName) {
var row = $scope.users.filter(function (user) {
return user.fullName === fullName;
});
//Assign row.login here
};
}]);
If I initialize a field with some autocomplete, it works.... but not if I declare those fields dynamically (like I do when I add a row to my table).
Is there a way to get this working dynamically or at least a workaround for this?
EDIT
I have tried inserting the line Materialize.updateTextFields() but still not working.
There're just 2-3 things you need to update:
1) You've to run the .autocomplete() function every time you're adding new field dynamically. For that just create one function for executing autocomplete for each field on dom. (calling it once only execute it for the first field in your ng-repeat). Function can be:
$scope.runAutocomplete = function(){
$timeout(function(){
$("input.autocomplete").autocomplete({
data: $scope.usersAutocomplete
});
});
}
So addaccess function should be:
$scope.addAccess = function() {
$scope.accesses.push({
login : '',
fullName : ''
});
$scope.getUsers();
$scope.runAutocomplete();
};
Here timeout
is just enough small time to make sure your new object is pushed & element is created on dom by ng-repeat
. And if in real time youre going to call service in getUsers()
then you should execute $scope.runAutocomplete()
in its callback function.
2) In your version of materialize library in css there's some problem & thus somehow it's giving style display
none & opacity
0 to .dropdown-content which's essential component of autocomplete so you can handle that by overriding it in your particular view css.
And there're other minor things like, have angular & non-angular code in different files or in different script tags, module
is a keyword in angularjs avoid using it as variable name. Also, you've misspelled class name, the one on input element is not same as what you selected using jq selector inside controller during calling autocomplete()
.
This's the working version of your code: https://plnkr.co/edit/EdP5cw7R5bADRMgnHfA9?p=preview
(I've used minimum configuration just for purpose of running it you can integrate in your actual app with having other detail config items for autocomplete & other components)