Angular autocomplete not working - angularjs

From the tutorial. The search box is styled correctly.
But when I type the drop down doesn't appear with the static data in my controller.
Here is my template.
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-4 col-lg-3">
<div class="panel panel-default panel-filter">
<div class="panel-heading">
<h3 class="panel-title">Calendar Filter</h3>
</div>
<div class="panel-body">
<div class="section section-filter">
<form ng-submit="$event.preventDefault()">
<div class="form-group" style="margin-bottom:0">
<div class="input-group input-group-sm addon-left">
<span class="input-group-addon">View By</span>
<select class="form-control" name="select_view" id="select_view">
<option value="taskown">Task Owner</option>
<option value="taskacc">Task Account</option>
</select>
</div>
</div>
<div class="form-group-taskown">
<div class="space15"></div>
<div class="form-group">
<div class="input-group input-group-sm addon-left">
<span class="input-group-addon"><i class="glyphicon glyphicon-search"></i></span>
<div class="autocompletedemoCustomTemplate">
<md-autocomplete
ng-disabled="taskCalendarCtrl.isDisabled"
md-no-cache="taskCalendarCtrl.noCache"
md-selected-item="taskCalendarCtrl.selectedItem"
md-search-text-change="taskCalendarCtrl.searchTextChange(taskCalendarCtrl.searchText)"
md-search-text="taskCalendarCtrl.searchText"
md-selected-item-change="taskCalendarCtrl.selectedItemChange(item)"
md-items="item in taskCalendarCtrl.querySearch(taskCalendarCtrl.searchText)"
md-item-text="item.name"
md-min-length="0"
placeholder=""
md-menu-class="autocomplete-custom-template">
<md-item-template>
<span class="item-title">
<md-icon md-svg-icon="img/icons/octicon-repo.svg"></md-icon>
<span> {{item.name}} </span>
</span>
<span class="item-metadata">
<span class="item-metastat">
<strong>{{item.watchers}}</strong> watchers
</span>
<span class="item-metastat">
<strong>{{item.forks}}</strong> forks
</span>
</span>
</md-item-template>
</md-autocomplete>
</div>
<!--
<input type="text" class="form-control" id="searchBox" name="typeahead_example_1" ng-model="searchBox" ng-change="change(text)" auto-complete ui-items="users">-->
</div>
</div>
</div>
</form>
</div><!--/section-->
</div>
</div>
</div>
<div class="col-sm-12 col-md-8 col-lg-6">
<div class="section section-calendar">
<div id='calendar'></div>
</div><!--/section-->
</div>
<div class="space20 hidden-lg"></div>
<div class="col-sm-12 col-sm-offset-0 col-md-8 col-md-offset-4 col-lg-3 col-lg-offset-0">
<div class="panel panel-default panel-tasks">
<div class="panel-heading">
<h3 class="panel-title">Tasks</h3>
</div>
<div class="list-group" ng-repeat="task in taskList | limitTo: 5">
<a href="{{task.url}}" class="list-group-item">
<span class="badge">{{task.status}}</span>
<h4 class="list-group-item-heading">{{task.heading}}</h4>
<ul class="list-unstyled">
<li><strong>Assigned To:</strong>{{task.assignedTo}}</li>
<li><strong>Releted To:</strong>{{task.relatedTo}}</li>
</ul>
</a>
</div><!--/list-group-->
</div>
</div>
</div><!--/row-->
</div> <!-- /container -->
and controller aka taskCalendarCtrl
'use strict';
angular
.module('taskCalendar')
.controller('taskCalendarCtrl', ['$scope', 'task', 'user', 'account', function($scope, task , user, account) {
}], taskCalendarCtrl);
function taskCalendarCtrl ($timeout, $q, $log) {
var self = this;
self.simulateQuery = false;
self.isDisabled = false;
self.repos = loadAll();
self.querySearch = querySearch;
self.selectedItemChange = selectedItemChange;
self.searchTextChange = searchTextChange;
// ******************************
// Internal methods
// ******************************
/**
* Search for repos... use $timeout to simulate
* remote dataservice call.
*/
function querySearch (query) {
var results = query ? self.repos.filter( createFilterFor(query) ) : self.repos,
deferred;
if (self.simulateQuery) {
deferred = $q.defer();
$timeout(function () { deferred.resolve( results ); }, Math.random() * 1000, false);
return deferred.promise;
} else {
return results;
}
}
function searchTextChange(text) {
$log.info('Text changed to ' + text);
}
function selectedItemChange(item) {
$log.info('Item changed to ' + JSON.stringify(item));
}
/**
* Build `components` list of key/value pairs
*/
function loadAll() {
var repos = [
{
'name' : 'Angular 1',
'url' : 'https://github.com/angular/angular.js',
'watchers' : '3,623',
'forks' : '16,175',
},
{
'name' : 'Angular 2',
'url' : 'https://github.com/angular/angular',
'watchers' : '469',
'forks' : '760',
},
{
'name' : 'Angular Material',
'url' : 'https://github.com/angular/material',
'watchers' : '727',
'forks' : '1,241',
},
{
'name' : 'Bower Material',
'url' : 'https://github.com/angular/bower-material',
'watchers' : '42',
'forks' : '84',
},
{
'name' : 'Material Start',
'url' : 'https://github.com/angular/material-start',
'watchers' : '81',
'forks' : '303',
}
];
return repos.map( function (repo) {
repo.value = repo.name.toLowerCase();
return repo;
});
}
/**
* Create filter function for a query string
*/
function createFilterFor(query) {
var lowercaseQuery = angular.lowercase(query);
return function filterFn(item) {
return (item.value.indexOf(lowercaseQuery) === 0);
};
}
}
I get these errors when I click and type in the search box
more details on my error

You have your controller declaration wrong in your code.
The syntax of dependency injection of the controller is not correct.
it should be,
.controller('taskCalendarCtrl', ['$scope', 'task', 'user',
'account','$timeout','$q','$log', function($scope, task , user,
account,$timeout,$q,$log) {
}])
Here is the change in the complete file.
'use strict';
angular
.module('taskCalendar')
.controller('taskCalendarCtrl', ['$scope', 'task', 'user', 'account','$timeout','$q','$log', function($scope, task , user, account,$timeout,$q,$log) {
var self = this;
self.simulateQuery = false;
self.isDisabled = false;
self.repos = loadAll();
self.querySearch = querySearch;
self.selectedItemChange = selectedItemChange;
self.searchTextChange = searchTextChange;
// ******************************
// Internal methods
// ******************************
/**
* Search for repos... use $timeout to simulate
* remote dataservice call.
*/
function querySearch (query) {
var results = query ? self.repos.filter( createFilterFor(query) ) : self.repos,
deferred;
if (self.simulateQuery) {
deferred = $q.defer();
$timeout(function () { deferred.resolve( results ); }, Math.random() * 1000, false);
return deferred.promise;
} else {
return results;
}
}
function searchTextChange(text) {
$log.info('Text changed to ' + text);
}
function selectedItemChange(item) {
$log.info('Item changed to ' + JSON.stringify(item));
}
/**
* Build `components` list of key/value pairs
*/
function loadAll() {
var repos = [
{
'name' : 'Angular 1',
'url' : 'https://github.com/angular/angular.js',
'watchers' : '3,623',
'forks' : '16,175',
},
{
'name' : 'Angular 2',
'url' : 'https://github.com/angular/angular',
'watchers' : '469',
'forks' : '760',
},
{
'name' : 'Angular Material',
'url' : 'https://github.com/angular/material',
'watchers' : '727',
'forks' : '1,241',
},
{
'name' : 'Bower Material',
'url' : 'https://github.com/angular/bower-material',
'watchers' : '42',
'forks' : '84',
},
{
'name' : 'Material Start',
'url' : 'https://github.com/angular/material-start',
'watchers' : '81',
'forks' : '303',
}
];
return repos.map( function (repo) {
repo.value = repo.name.toLowerCase();
return repo;
});
}
/**
* Create filter function for a query string
*/
function createFilterFor(query) {
var lowercaseQuery = angular.lowercase(query);
return function filterFn(item) {
return (item.value.indexOf(lowercaseQuery) === 0);
};
}
}
])

check if you have set ng-controller directive. If not then set it first.
eg :
<div class="container-fluid" ng-controller="taskCalendarCtrl as taskCalendarCtrl">
Next change
.controller('taskCalendarCtrl', ['$scope', 'task', 'user', 'account', function($scope, task , user, account) {
}], taskCalendarCtrl);
to
.controller('taskCalendarCtrl', taskCalendarCtrl);

Related

AngularJs : one of four params,passed to directive is undefined

I have a modal view(.jsp) that has integrated directive (named as 'querybuilder', Yellow part in the picture - a js file). Controller(named as 'addEditRuleSetCtrl') and directive is included from upper level and inclusion seems fine. We have initiated the directive from the view as :
<div ng-init="addEditRuleSetCtrl.initSelectors()">
<query-builder group="addEditRuleSetCtrl.filter.group"
rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
fields="addEditRuleSetCtrl.fieldCodes"
></query-builder>
</div>
Where "addEditRuleSetCtrl.initSelectors()" initiates all the params passed to the directive as :
self.initSelectors = function()
{
self.getRuleConditionOperators();
self.getRuleConditionSetOperators();
self.fieldCodes = self.getCorrespondingFields();
console.log("initSelectors : fieldCodes: " + JSON.stringify(self.fieldCodes ));
}
self.getCorrespondingFields = function()
{
return self.origin == 'DDE' ? self.fieldsDDE : self.fieldsATT;
};
And the params were declared in the controller in this way:
self.fieldsDDE = [
{ name: 'FirstnameDDE' },
{ name: 'LastnameDDE' },
{ name: 'BirthdateDDE' },
{ name: 'CityDDE' },
{ name: 'CountryDDE' }
];
self.fieldsATT = [
{ name: 'FirstnameATT' },
{ name: 'LastnameATT' },
{ name: 'BirthdateATT' },
{ name: 'CityATT' },
{ name: 'CountryATT' }
];
self.fieldCodes = [];
self.ruleConditionSetOperators = [];
self.ruleConditionOperators = [];
The problem is: one ( the param 'fieldCodes')of the four params that passed to the directive is "undefined" Although they were defined ,passed in similar way. I have cleaned the cache and tested all possible ways but nothing made any difference.As a result the associated dropdown is empty (in the red-arrowed dropdown in the screenshot).Any clue?
The full view :
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="UTF-8"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<link
href="<c:url value='aviato/ruleEngine/addEditRuleSet/css/addeditruleset.css' />"
rel="stylesheet">
</link>
<%--<script src="aviato/ruleEngine/addEditRuleSet/directive/addEditRuleSet_directive.js"></script>--%>
<form name="addEditRuleSetModalForm" novalidate class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
{{addEditRuleSetCtrl.windowHeader}}
<button type="button" class="btn btn-danger btn-sm pull-right"
ng-click="addEditRuleSetCtrl.close()" data-toggle="uibtooltip" title="Cancel" >
<span class="glyphicon glyphicon-remove-sign"></span>
</button>
</h4>
</div>
<div class="modal-body">
Hello world [origin] : {{ addEditRuleSetCtrl.origin }}
<br />
Hello world [iceField] : {{ addEditRuleSetCtrl.iceField }}
Output: {{ addEditRuleSetCtrl.output }}
<div class="alert alert-info">
<strong>Example Output</strong><br>
Output: {{ addEditRuleSetCtrl.output }}
</div>
<div ng-init="addEditRuleSetCtrl.initSelectors()">
<query-builder group="addEditRuleSetCtrl.filter.group"
rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
fields="addEditRuleSetCtrl.fieldCodes"
></query-builder>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" ng-click="addEditRuleSetCtrl.test()" data-toggle="tooltip" ><span class="glyphicon glyphicon-ok-sign" ></span></button><span></span>
</div>
</div>
</form>
<script type="text/ng-template" id="/queryBuilderDirective.html">
<div class="alert alert-warning alert-group">
<div class="form-inline">
<select ng-options="o as o.operator for o in ruleConditionSetOperators" ng-model="group.operator" class="form-control input-sm"></select>
<button style="margin-left: 5px" ng-click="addCondition()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Condition</button>
<button style="margin-left: 5px" ng-click="addGroup()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Group</button>
<button style="margin-left: 5px" ng-click="removeGroup()" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span> Remove Group</button>
</div>
<div class="group-conditions">
<div ng-repeat="rule in group.rules | orderBy:'index'" class="condition">
<div ng-switch="rule.hasOwnProperty('group')">
<div ng-switch-when="true">
<query-builder group="rule.group"
rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
fields="addEditRuleSetCtrl.fieldCodes"
></query-builder>
</div>
<div ng-switch-default="ng-switch-default">
<div class="form-inline">
<select ng-options="t.name as t.name for t in fields" ng-model="rule.field" class="form-control input-sm"></select>
<select style="margin-left: 5px" ng-options="c as c.operator for c in ruleConditionOperators" ng-model="rule.condition" class="form-control input-sm"></select>
<input style="margin-left: 5px" type="text" ng-model="rule.data" class="form-control input-sm"/>
<button style="margin-left: 5px" ng-click="removeCondition($index)" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</script>
The Directive:
AddEditRuleSetApp.directive('queryBuilder', ['$compile', function ($compile) {
return {
restrict: 'E',
scope: {
group: '=',
ruleConditionOperators: '=',
ruleConditionSetOperators: '=',
fields: '='
},
templateUrl: '/queryBuilderDirective.html',
compile: function (element, attrs) {
var content, directive;
content = element.contents().remove();
return function (scope, element, attrs) {
scope.fields = scope.$parent.fieldCodes;
scope.ruleConditionOperators = scope.$parent.ruleConditionOperators;
scope.ruleConditionSetOperators = scope.$parent.ruleConditionSetOperators;
window.alert("HEYYYYYY I'M CHANGING!!!!!! "
+ JSON.stringify(scope.group)
+ " ; "+ JSON.stringify(scope.ruleConditionOperators)
+ " ; "+ JSON.stringify(scope.ruleConditionSetOperators)
+ " ; "+ JSON.stringify(scope.fields));
scope.addCondition = function () {
scope.group.rules.push({
condition: '=',
field: 'Firstname',
data: ''
});
};
scope.removeCondition = function (index) {
scope.group.rules.splice(index, 1);
};
scope.addGroup = function () {
scope.group.rules.push({
group: {
operator: 'AND',
rules: []
}
});
};
scope.removeGroup = function () {
"group" in scope.$parent && scope.$parent.group.rules.splice(scope.$parent.$index, 1);
};
directive || (directive = $compile(content));
element.append(directive(scope, function ($compile) {
return $compile;
}));
}
}
}
}]);
The controller:
AddEditRuleSetApp.controller( 'AddEditRuleSetModalController', [ '$scope', '$rootScope', '$uibModalInstance','RuleEngineService', 'origin', 'iceField','FileService',
function( $scope, $rootScope , $uibModalInstance, RuleEngineService, origin, iceField, FileService )
{
var self = this;
self.origin = origin;
self.iceField = iceField;
self.data = '{"group": {"operator": "AND","rules": []}}';
self.output = 'bologna';
self.filter = JSON.parse(self.data);
self.fieldsDDE = [
{ name: 'FirstnameDDE' },
{ name: 'LastnameDDE' },
{ name: 'BirthdateDDE' },
{ name: 'CityDDE' },
{ name: 'CountryDDE' }
];
self.fieldsATT = [
{ name: 'FirstnameATT' },
{ name: 'LastnameATT' },
{ name: 'BirthdateATT' },
{ name: 'CityATT' },
{ name: 'CountryATT' }
];
self.fieldCodes = [];
self.ruleConditionSetOperators = [];
self.ruleConditionOperators = [];
self.initSelectors = function()
{
self.getRuleConditionOperators();
self.getRuleConditionSetOperators();
self.fieldCodes = self.getCorrespondingFields();
console.log("initSelectors : fieldCodes: " + JSON.stringify(self.fieldCodes ));
}
self.getRuleConditionOperators = function()
{
if ( self.ruleConditionOperators.length == 0 )
{
RuleEngineService.getAllRuleConditionOperators()
.then(
function( d )
{
self.ruleConditionOperators = d;
},
function( errResponse )
{
console.error( 'Error while fetching rule-condition-operators' );
}
);
}
return self.ruleConditionOperators;
};
self.getRuleConditionSetOperators = function()
{
if ( self.ruleConditionSetOperators.length == 0 )
{
RuleEngineService.getAllRuleConditionSetOperators()
.then(
function( d )
{
self.ruleConditionSetOperators = d;
},
function( errResponse )
{
console.error( 'Error while fetching rule-condition-operators' );
}
);
}
return self.ruleConditionSetOperators;
};
self.htmlEntities = function(str)
{
return String(str).replace(/</g, '<').replace(/>/g, '>');
};
self.displayErrorMessages = false;
self.createSuccess = '';
self.createHeader = '';
self.backendErr = "";
self.windowHeader = "Create/Edit Rule Group";
self.close = function()
{
$uibModalInstance.close();
};
self.getCorrespondingFields = function()
{
return self.origin == 'DDE' ? self.fieldsDDE : self.fieldsATT;
};
self.computed = function(group)
{
window.alert("Inside controller: computed");
if (!group) return "";
for (var str = "(", i = 0; i < group.rules.length; i++) {
i > 0 && (str += " <strong>" + group.operator + "</strong> ");
str += group.rules[i].group ?
self.computed(group.rules[i].group) :
group.rules[i].field + " " +
//htmlEntities(group.rules[i].condition)
group.rules[i].condition
+ " " + group.rules[i].data;
}
return str + ")";
};
$scope.$watch('filter', function (newValue)
{
//self.json = JSON.stringify(newValue, null, 2);
//TODO: do we need this??
//if( angular.isDefined( newValue ) )
//{
//window.alert("I am here again in watch!!!!" + JSON.stringify(newValue));
self.output = self.computed(newValue);
// self.ruleConditionOperators = self.getAllRuleConditionOperators();
// window.alert("I am HERE - end watch!!!!");
//}
}, true);
self.test = function()
{
window.alert(JSON.stringify( self.filter) );
};
}
]);
The screenshot:
At my first glance of the directive, I think you probably should change from:
var test = scope.$parent.fieldCodes;
scope.fields = scope.$parent.fields;
To:
//var test = scope.$parent.fieldCodes;
scope.fields = scope.$parent.fieldCodes;

Angular JS: One function in the controller is reached , other is not - from view during instantiation of a directive

I have a modal view(.jsp) that has integrated directive (named as 'querybuilder', Yellow part in the picture - a js file). Controller(named as 'addEditRuleSetCtrl') and directive is included from upper level and inclusion seems fine. We have initiated the directive from the view as :
<query-builder group="addEditRuleSetCtrl.filter.group"
ruleConditionOperators="addEditRuleSetCtrl.getRuleConditionOperators()"
fields="addEditRuleSetCtrl.getCorrespondingFields()"
></query-builder>
Now the problem, I am seeing is 'addEditRuleSetCtrl.getCorrespondingFields()' works fine (reaches controller , maps data to 'field' and hence the associated dropdown field displays right data) but looks like 'addEditRuleSetCtrl.getRuleConditionOperators()' does not even reach the function defined inside the controller (I have an window.alerm() inside the function in the controller that does not show up)and hence the associted dropdown is empty (In the screenshot , it is pointed by the upside arrow).
We are using angularjs 1.4.4 and java 1.8
Below are the details of the description , Here is my JSP-view, directive and controller:
Modal view (This is a JSP file and this includes the template, used by the directive):
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="UTF-8"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<link
href="<c:url value='aviato/ruleEngine/addEditRuleSet/css/addeditruleset.css' />"
rel="stylesheet">
</link>
<%--<script src="aviato/ruleEngine/addEditRuleSet/directive/addEditRuleSet_directive.js"></script>--%>
<form name="addEditRuleSetModalForm" novalidate class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
{{addEditRuleSetCtrl.windowHeader}}
<button type="button" class="btn btn-danger btn-sm pull-right"
ng-click="addEditRuleSetCtrl.close()" data-toggle="uibtooltip" title="Cancel" >
<span class="glyphicon glyphicon-remove-sign"></span>
</button>
</h4>
</div>
<div class="modal-body">
Hello world [origin] : {{ addEditRuleSetCtrl.origin }}
<br />
Hello world [iceField] : {{ addEditRuleSetCtrl.iceField }}
ahahahhaahahahahaahahhg1111!!!!! {{ addEditRuleSetCtrl.output }}
<div class="alert alert-info">
<strong>Example Output</strong><br>
<%--<span ng-bind-html="addEditRuleSetCtrl.output"></span>--%>
ahahahhaahahahahaahahhg!!!!! {{ addEditRuleSetCtrl.output }}
</div>
<query-builder group="addEditRuleSetCtrl.filter.group"
ruleConditionOperators="addEditRuleSetCtrl.getRuleConditionOperators()"
fields="addEditRuleSetCtrl.getCorrespondingFields()"
></query-builder>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" ng-click="addEditRuleSetCtrl.test()" data-toggle="tooltip" ><span class="glyphicon glyphicon-ok-sign" ></span></button><span></span>
</div>
</div>
</form>
<script type="text/ng-template" id="/queryBuilderDirective.html">
<div class="alert alert-warning alert-group">
<div class="form-inline">
<select ng-options="o.operator as o.name for o in ruleConditionSetOperators" ng-model="group.operator" class="form-control input-sm"></select>
<button style="margin-left: 5px" ng-click="addCondition()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Condition</button>
<button style="margin-left: 5px" ng-click="addGroup()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Group</button>
<button style="margin-left: 5px" ng-click="removeGroup()" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span> Remove Group</button>
</div>
<div class="group-conditions">
<div ng-repeat="rule in group.rules | orderBy:'index'" class="condition">
<div ng-switch="rule.hasOwnProperty('group')">
<div ng-switch-when="true">
<query-builder group="rule.group"></query-builder>
</div>
<div ng-switch-default="ng-switch-default">
<div class="form-inline">
<select ng-options="t.name as t.name for t in fields" ng-model="rule.field" class="form-control input-sm"></select>
<%--<select style="margin-left: 5px" ng-options="c.name as c.name for c in ruleConditionOperators" ng-model="rule.condition" class="form-control input-sm"></select>--%>
<select style="margin-left: 5px" ng-options="c.name as c.name for c in ruleConditionOperators" ng-model="rule.condition" class="form-control input-sm"></select>
<input style="margin-left: 5px" type="text" ng-model="rule.data" class="form-control input-sm"/>
<button style="margin-left: 5px" ng-click="removeCondition($index)" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</script>
The Directive: ( This is a .js file. If I uncomment 'scope.ruleConditionOperators' here, the red-arrow-pointed dropdown displays data)
AddEditRuleSetApp.directive('queryBuilder', ['$compile', function ($compile) {
return {
restrict: 'E',
scope: {
group: '=',
ruleConditionOperators: '=',
fields: '='
},
templateUrl: '/queryBuilderDirective.html',
compile: function (element, attrs) {
var content, directive;
content = element.contents().remove();
return function (scope, element, attrs) {
scope.ruleConditionSetOperators = [
{ name: 'AND' },
{ name: 'OR' }
];
/* scope.ruleConditionOperators = [
{ name: '=' },
{ name: '<>' },
{ name: '<' },
{ name: '<=' },
{ name: '>' },
{ name: '>=' }
];*/
scope.addCondition = function () {
scope.group.rules.push({
condition: '=',
field: 'Firstname',
data: ''
});
};
scope.removeCondition = function (index) {
scope.group.rules.splice(index, 1);
};
scope.addGroup = function () {
scope.group.rules.push({
group: {
operator: 'AND',
rules: []
}
});
};
scope.removeGroup = function () {
"group" in scope.$parent && scope.$parent.group.rules.splice(scope.$parent.$index, 1);
};
directive || (directive = $compile(content));
element.append(directive(scope, function ($compile) {
return $compile;
}));
}
}
}
}]);
The Controller:
AddEditRuleSetApp.controller( 'AddEditRuleSetModalController', [ '$scope', '$rootScope', '$uibModalInstance','RuleEngineService', 'origin', 'iceField',
function( $scope, $rootScope , $uibModalInstance, RuleEngineService, origin, iceField )
{
var self = this;
self.origin = origin;
self.iceField = iceField;
self.data = '{"group": {"operator": "AND","rules": []}}';
self.output = 'bologna';
self.fieldsDDE = [
{ name: 'FirstnameDDE' },
{ name: 'LastnameDDE' },
{ name: 'BirthdateDDE' },
{ name: 'CityDDE' },
{ name: 'CountryDDE' }
];
self.fieldsATT = [
{ name: 'FirstnameATT' },
{ name: 'LastnameATT' },
{ name: 'BirthdateATT' },
{ name: 'CityATT' },
{ name: 'CountryATT' }
];
self.ruleConditionOperators = [
{ name: '=' },
{ name: '<>' },
{ name: '<' },
{ name: '<=' },
{ name: '>' },
{ name: '>=' }
];
self.clientChanged = function( selCleintId )
{
self.getAllMachinesForClientForDuplication( self.duplicateClient );
self.displayErrorMessages = false;
}
self.getRuleConditionOperators = function()
{
window.alert("--------*******---------Reached client side controller to getAllRuleConditionOperators");
return self.ruleConditionOperators;
/* RuleEngineService.getAllRuleConditionOperators( )
.then(
function( d )
{
self.ruleConditionOperators = d;
},
function( errResponse )
{
console.error( 'Error while fetching rule-condition-operators' );
}
);
*/
};
self.htmlEntities = function(str)
{
return String(str).replace(/</g, '<').replace(/>/g, '>');
};
//self.output = null;
self.displayErrorMessages = false;
self.createSuccess = '';
self.createHeader = '';
self.backendErr = "";
self.windowHeader = "Create/Edit Rule Group";
self.close = function()
{
$uibModalInstance.close();
};
self.getCorrespondingFields = function()
{
// window.alert("---------------Reached client side controller to getCorrespondingFields");
return self.origin == 'DDE' ? self.fieldsDDE : self.fieldsATT;
};
self.computed = function(group)
{
window.alert("Inside controller: computed");
if (!group) return "";
for (var str = "(", i = 0; i < group.rules.length; i++) {
i > 0 && (str += " <strong>" + group.operator + "</strong> ");
str += group.rules[i].group ?
self.computed(group.rules[i].group) :
group.rules[i].field + " " +
//htmlEntities(group.rules[i].condition)
group.rules[i].condition
+ " " + group.rules[i].data;
}
return str + ")";
};
//self.json = null;
self.filter = JSON.parse(self.data);
$scope.$watch('filter', function (newValue)
{
self.output = self.computed(newValue);
}, true);
self.test = function()
{
window.alert(JSON.stringify( self.filter) );
};
}
]);
The screenshot:

Angular unselect item in all selected items

Below is my code. When user clicks on "select all" all items get selected.
what I want is when user click on any option that option should be disabled.
var app = angular.module('sampleApp', []);
app.controller('sampleController', ['$scope',
function($scope) {
$scope.selectAll = false;
}
])
.disabled {
opacity: 0.5
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="sampleApp">
<div ng-controller="sampleController">
<label ng-click="selectAll = !selectAll">Select all</label>
<div ng-class="selectAll ? 'enable' : 'disabled'">Option 1</div>
<div ng-class="selectAll ? 'enable' : 'disabled'">Option 2</div>
<div ng-class="selectAll ? 'enable' : 'disabled'">Option 3</div>
<div ng-class="selectAll ? 'enable' : 'disabled'">Option 4</div>
</div>
</div>
You need to wrap each item into a new object and place a field 'selected' on this object:
var app = angular.module('sampleApp', []);
app.controller('sampleController', ['$scope',
function($scope) {
$scope.options = [{
selected: false,
item: 'option 1'
}, {
selected: false,
item: 'option 2'
}, {
selected: false,
item: 'option 3'
}]
$scope.selectAll = function(select) {
angular.forEach($scope.options, function(o) {
o.selected = select;
});
};
}
])
.disabled {
opacity: 0.5
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="sampleApp">
<div ng-controller="sampleController">
<label ng-click="selectAll(true)">Select all</label>
<label ng-click="selectAll(false)">Deselect all</label>
<div ng-repeat="option in options" ng-class="{'disabled': !option.selected}" ng-click="option.selected = !option.selected">{{option.item}}</div>
</div>
</div>

Material Design Autocomplete not updating dropdown on remote call

I'm trying to get md-autocomplete to play nice with Algolia's Angular service. I'm stuck on getting the dropdown to display the results being returned from Algolia. The content is in console yet the dropdown will not populate with the updated results. What am I missing?
tl;dr: Plnkr
"Backend"
.controller('DemoCtrl', DemoCtrl);
function DemoCtrl ($timeout, $q, $log, algolia, $http, $scope) {
var self = this;
self.simulateQuery = false;
self.isDisabled = false;
self.repos = loadAll();
self.querySearch = querySearch;
self.selectedItemChange = selectedItemChange;
self.searchTextChange = searchTextChange;
// Algolia demo keys below
var client = algolia.Client('latency', '6be0576ff61c053d5f9a3225e2a90f76');
var index = client.initIndex('contacts');
$scope.query = '';
$scope.hits = [];
// Disable cache
$scope.noCacheResults = false;
// ******************************
// Internal methods
// ******************************
/**
* Search for repos... use $timeout to simulate
* remote dataservice call.
*/
function querySearch (query) {
// This returns objects in console
var results = self.algoliaSearch(query);
// This returns: TypeError: Cannot read property 'then' of undefined
// var results = query ? self.algoliaSearch( createFilterFor(query) ) : self.repos, deferred;
return results;
}
function searchTextChange(text) {
$log.info('Text changed to ' + text);
}
function selectedItemChange(item) {
$log.info('Item changed to ' + JSON.stringify(item));
}
/**
* Build `components` list of key/value pairs
*/
function algoliaSearch(text) {
try {
index
.search(text)
.then(function(content) {
// if (content.query !== $scope.query) {
// // do not take out-dated answers into account
// return;
// }
$scope.hits = content.hits;
return content.hits.map( function (hit) {
hit.value = hit.name.toLowerCase();
$log.debug(hit);
return hit;
});
}, function(content) {
console.log('Error: ' + content.message);
});
} catch(e) {
$log.debug(e);
}
}
function loadAll() {
var repos = [
{
'name' : 'Angular 1',
'url' : 'https://github.com/angular/angular.js',
'watchers' : '3,623',
'forks' : '16,175',
}
];
return repos.map( function (repo) {
repo.value = repo.name.toLowerCase();
return repo;
});
}
/**
* Create filter function for a query string
*/
function createFilterFor(query) {
var lowercaseQuery = angular.lowercase(query);
return function filterFn(item) {
return (item.value.indexOf(lowercaseQuery) === 0);
};
}
}
"Frontend"
<div ng-controller="DemoCtrl as ctrl" layout="column" ng-cloak>
<md-content layout-padding layout="column">
<form ng-submit="$event.preventDefault()">
<p>Use <code><md-autocomplete></code> with custom templates to show styled autocomplete results.</p>
<md-autocomplete
ng-disabled="ctrl.isDisabled"
md-no-cache="ctrl.noCacheResults"
md-selected-item="ctrl.selectedItem"
md-search-text-change="ctrl.searchTextChange(ctrl.searchText)"
md-search-text="ctrl.searchText"
md-selected-item-change="ctrl.selectedItemChange(item)"
md-items="item in ctrl.querySearch(ctrl.searchText)"
md-item-text="item.name"
md-min-length="0"
placeholder="Pick an Angular repository"
md-menu-class="autocomplete-custom-template">
<md-item-template>
{{item}}
<span class="item-title">
<md-icon md-svg-icon="img/icons/octicon-repo.svg"></md-icon>
<span> {{item.name}} </span>
</span>
<span class="item-metadata">
<span class="item-metastat">
<strong>{{item.watchers}}</strong> watchers
</span>
<span class="item-metastat">
<strong>{{item.forks}}</strong> forks
</span>
</span>
</md-item-template>
</md-autocomplete>
</form>
</md-content>
</div>
"Algolia default"
<section class="panel">
<header class="panel-heading">
<div class="search_box">
<form action="#" method="get">
<input autocomplete="off" class="autocomplete" placeholder="Start typing" type="text" spellcheck="false" id="q" ng-model="query" />
<div class="searchbutton">
<i class="icon-search icon-large"></i>
</div>
</form>
</div>
</header>
</section>
<h1>Results</h1>
<div class="hit" ng-repeat="hit in hits">
<div class="attribute" ng-repeat="(attribute,v) in hit._highlightResult">
<span>{{ attribute }}: </span>
<span ng-bind-html="v.value"></span>
</div>
</div>
<script type="text/javascript">
angular
.module('myapp', ['algoliasearch', 'ngSanitize'])
.controller('SearchCtrl', ['$scope', 'algolia', function($scope, algolia) {
$scope.query = '';
$scope.hits = [];
// Replace the following values by your ApplicationID and ApiKey.
var client = algolia.Client('latency', '6be0576ff61c053d5f9a3225e2a90f76');
// Replace the following value by the name of the index you want to query.
var index = client.initIndex('contacts');
$scope.$watch('query', function() {
index.search($scope.query, { hitsPerPage: 5 }).then(function(content) {
if (content.query !== $scope.query) {
// do not take out-dated answers into account
return;
}
$scope.hits = content.hits;
}, function(content) {
console.log('Error: ' + content.message);
});
});
}]);
</script>
You should return a Promise since the call to AlgoliaSearch is asynchronous:
function querySearch(query) {
return algoliaSearch(query);
// var results = query ? self.algoliaSearch( createFilterFor(query) ) : self.repos, deferred;
}
You can find the updated code here: http://plnkr.co/edit/C8fmsNRzNsXEC7InNM6a

fetching data and show them in proper place in backbone

I have an issue in backbone, I want to render 100 rows of data from backend ( fetched by url) and show between of button element and pagination. I have created two templates, and have two views one for the whole page and the other for individual items. But when I fetch the data they do not go between the button and pagination div, all the 100 rows go under that. How can I put them in proper place? These are my templates:
the list template:
<div class="message-list-actions">
<div class="action">
<select>
<option value="0">Bulk Actions</option>
<option value="1">Delete</option>
<option value="2">Mark As Read</option>
</select>
<button class="grey">OK</button>
</div>
<div class="action">
<select>
<option value="0">All</option>
<option value="1">Unread Messages</option>
<option value="2">Read Messages</option>
</select>
<button class="grey">OK</button>
</div>
<div class="results right">
<form>
<label for="results">Results pr. page</label>
<select name="results">
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
<option value="500">500</option>
</select>
</form>
</div>
</div> <!-- message-list-actions -->
<div class="message-list">
<div class="message-list-header row">
<div class="left check">
<input type="checkbox" name="type"/>
<label for="type">CHECK ALL</label>
</div>
<div class="left date" >
<span class="sorter">Date</span>
</div>
<div class="large-9 columns" >
<span class="sorter">Message</span>
</div>
</div>
<section class="message-item row">
<div class="message-list"></div>
<div class="left check" >
<input type="checkbox" class="type">
</div>
<div class="left date" >
<div class="icon"></div>
</div>
<div class="large-9 columns" >
</div>
</section>
<section>
<ul class="pagination">
<li class="arrow unavailable">Previous</li>
<li class="current">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li class="unavailable">…</li>
<li>12</li>
<li>13</li>
<li class="arrow">Next</li>
</ul>
</section>
other template:
<div class="message-list">
<section class="message-item row">
<div class="left check" >
<input type="checkbox" class="type">
</div>
<div class="left date" >
<p><%= created !== undefined ? created : "not available" %></p>
<div class="icon"></div>
<div class="severity normal"><%= name %></div>
</div>
<div class="large-9 columns" >
<h4><%= title %></h4>
<p><%= id %></p>
</div>
<!-- Delete -->
</section>
</div> <!-- .main -->
//view for message:
define([
"jquery",
"underscore",
"backbone",
"js/collections/messagesCollection",
"js/models/messagesModel",
"text!templates/messageView.html",
"text!templates/messageList.html",
"text!templates/messageDetails.html"
], function($, _ , Backbone,
MessagesCollection,
MessagesModel,
UserEditTemplate, UserViewTemplate, UserSelfEditTemplate, ResetPasswordTemplate, ChangePasswordTemplate){
MessageViewTemplate, MessageListTemplate, MessageDetailsTemplate){
var MessageView = Backbone.View.extend({
tagName : "div",
messageViewTemplate : _.template(MessageViewTemplate),
messageDetailsTemplate : _.template(MessageDetailsTemplate),
template : _.template(MessageDetailsTemplate),
collection : MessagesCollection,
initialize : function(){
this.model.on("change", this.render, this);
this.model.on("update", this.render, this);
},
render : function(){
//this.$el.html(this.userTemplate(this.model.toJSON()));
this.$el.html(this.messageViewTemplate(this.model.toJSON()));
return this;
}
});
return MessageView;
});
View for list of message:
define([
"jquery",
"underscore",
"backbone",
"js/models/loggedInUserModel",
"js/models/currentTabModel",
"js/models/messagesModel",
"js/collections/messagesCollection",
"js/views/messageView",
"text!templates/messageList.html",
"text!templates/messageDetails.html",
"text!templates/header.html",
"text!templates/breadcrumbs.html",
"text!templates/footer.html"
], function($, _, Backbone,
MessagesModel,
MessagesCollection,
MessageView,
MessageListTemplate, MessageDetailsTemplate, HeaderTemplate, BreadCrumbTemplate, FooterTemplate
){
var MessagesView = Backbone.View.extend({
el : $("#maincontent"),
messageListTemplate : MessageListTemplate,
messageDetailsTemplate : _.template(MessageDetailsTemplate),
collection : MessagesCollection,
initialize : function(){
console.log("initialize messages");
this.collection = new MessagesCollection();
this.collection.on("add", this.renderMessage, this);
this.collection.on("reset", this.render, this);
this.collection.on("update", this.render, this);
if(this.options.selfEdit === false || _.isUndefined(this.options.selfEdit)){
this.start();
}
else{
console.log("options", this.options);
this.currentUserModel.fetch();
}
},
start : function(){
this.collection.fetch();
this.currentUserModel.fetch();
this.renderFooter();
},
render : function(){
this.$el.html(this.messageListTemplate);
_.each(this.collection.models, function(item){
this.renderMessage(item);
}, this);
},
renderMessage : function(item){
var messageView = new MessageView({
model : item
});
this.$el.append(messageView.render().el);
},
renderMessageDetails : function(item){
var messageView = new MessagesView({
model : item
});
this.$el.append(messageView.renderSelfView().el);
}
});
return MessagesView;
});
//Model
define([
"jquery",
"underscore",
"backbone"
], function($, _ , Backbone){
var MessagesModel = Backbone.Model.extend({
defaults : {
id : null,
created : null,
timestamp : null,
severity : null
},
parse : function(response){
response.id = response._id.$oid;
response.created = response.created.$date;
response.timestamp = response.timestamp.$date;
response.severity = response.severity;
return response;
},
clear : function(){
this.destroy();
this.view.remove();
},
// Convert regular JSON into MongoDB extended one.
toExtendedJSON: function() {
var attrs = this.attributes;
attrs = _.omit(attrs, ["created", "timestamp"]);
if (_.isUndefined(attrs.created)) {
// console.log("this", this["this.created"]);
attrs.created = { $date: this.get("created") };
}
if (_.isUndefined(attrs.timestamp)) {
attrs.timestamp = { $date: this.get("timestamp") };
}
console.dir(attrs);
return attrs;
},
// Substute toJSON method when performing synchronization.
sync : function(method, model, options) {
/*
* If we are performing an update we need to call the extendedJSON method
* By calling this, we guarantee that we comply to the MongoDB model.
* After applying that model, we then call Backbone .sync protoryp and then set the model.toJSON method
* back to its original definition.
*/
if(method === "update" && !model.isNew()){
var toJSON = this.toJSON;
this.toJSON = this.toExtendedJSON;
var ret = Backbone.sync.apply(this, arguments);
this.toJSON = toJSON;
return ret;
}
else{
return Backbone.sync.call(this, method, this, options);
}
},
formatDate : function(dateString) {
return new Date(dateString).toUTCString();
}
});
return MessagesModel;
});
Collection
define([
"jquery",
"underscore",
"backbone",
"js/models/messagesModel"
],function($,_, Backbone, MessagesModel){
var MessagesCollection = Backbone.Collection.extend({
model : MessagesModel,
url : "/api/v1/message",
parse : function(response, xhr){
return response.list;
}
});
return MessagesCollection;
});
Try following for renderMessage():
renderMessage : function(item){
var messageView = new MessageView({
model : item
});
this.$el.find('div.message-list').append(messageView.render().el);
},
Also update the code in a similar way for renderMessageDetails().

Resources