I wanted reload a core-list element to show new data, but it´s not refreshing.
I re-call the JS function thats generate the data but doesn t work... and reload like a 'normal' div doesn t work either! The list only shows the new data if i reload the entire page...
function values(sender, textomsg, datacriacao, senderfoto){
var sender2 = sender.split(",");
var textomsg2 = textomsg.split(",");
var datacriacao2 = datacriacao.split(",");
var senderfoto2 = senderfoto.split(",");
var namegen = {
generateString: function (inLength) {
var s = '';
for (var i = 0; i < inLength; i++) {
s += String.fromCharCode(Math.floor(Math.random() * 26) + 97);
}
return s;
},
generateName: function (inMin, inMax) {
return this.generateString(Math.floor(Math.random() * (inMax - inMin + 1) + inMin));
}
};
Polymer('list-test', {
count: sender.length,
ready: function () {
this.data = this.generateData();
},
generateData: function () {
var names = [], data = [];
for (var i = 0; i < this.count; i++) {
names.push(namegen.generateName(4, 8));
}
names.sort();
for (var i = 0; i < this.count; i++) {
data.push({
index: i,
sender: sender2[i],
textomsg: textomsg2[i],
datacriacao: datacriacao2[i],
senderfoto: senderfoto2[i]
});
}
return data;
},
tapAction: function (e) {
console.log('tap', e);
}
});
}
<%----%>
<template id="templateConversas" runat="server">
<div id="item" class="item {{ {selected: selected} | tokenList }}" ><%--onClick="conversa('{{name}}');"--%>
<div class="message" style="background-image: url({{senderfoto}});">
<span class="from"><br/>{{sender}}</span>
<span class="timestamp">{{datacriacao}}</span>
<div class="subject"><br/>{{textomsg}} </div><%--------Infinite List. {{index}}--%>
<%--<div class="body"><br/>Mensagem de teste...........</div>--%>
</div>
</div>
</template>
The problem is also reload the 'list-test'. if i call the js function after the list is loaded it doesn't apply the new data...
Your code isn't complete so it is hard to understand but I think that the problem is that you don't assign the result of the generateData() function to the template's model. Try following script for your component
Polymer('list-test', {
created: function () {
this.data = [];
},
refresh: function () {
this.data = this.generateData();
},
generateData: function () {
// your original code here
}
});
Now the list content should be updated with newly generated data when you call refresh() of the list-test element. To fill the list when element is created add
ready: function () {
this.refresh();
},
Related
I add infinite scroll in my angularjs project.
I have an issue i want to keep visible few last elements of my infinite scroll list till I reach them. I guess I need to have a variable with the last elements but after that I don't know what I have to do. Do you know how can I achieve that ?
this is my infinite scroll service
tabs.factory('chat', function ($http, $timeout, $q) {
return {
data: [],
dataScroll: [],
init: function (data) {
if (this.data.length == 0) {
for (var i = 0; i < data.length; i++) {
this.data[i] = data[i]
}
} else {
var tailleDataSaved = this.data.length
var dataAAjouter = data.slice(tailleDataSaved)
for (var i = 0; i < dataAAjouter.length; i++) {
this.data.push(dataAAjouter[i])
}
}
},
request: function (showAll) {
var self = this;
var deferred = $q.defer();
var index = this.dataScroll.length
var start = index;
var end = index + 6;
$timeout(function () {
if (!showAll) {
var item = []
if (start < end) {
for (var i = start; i < end; i++) {
console.log(start)
console.log(end)
console.log(self.data[i])
if (item = self.data[i]) {
self.dataScroll.push(item);
}
}
}
} else {
self.dataScroll = self.data
}
deferred.resolve(self.dataScroll);
}, 0);
return deferred.promise;
}
}
})
my js file with my list and the trigger of the scroll
$scope.listChat= function () {
$scope.isActionLoaded = false;
$http.get(apiurl).then(function (response) {
chat.init(response.data)
$scope.isActionLoaded = true
})
}
$scope.listChatInfiniteScroll = function () {
$scope.isScrollDataLoaded = false
ticketListeActionScroll.request(false).then(function (response) {
$scope.actionsInfiniteScroll = response
$scope.isScrollDataLoaded = true
})
}
my html file
<div ng-if="isActionLoaded" infinite-scroll='listChatInfiniteScroll ()' infinite-scroll-distance='1'>
<div ng-repeat="chat in actionsInfiniteScroll">
{{chat.text}}
</div>
</div>
I've been working on my drop down list, and while I know the HTML is working fine, I can't seem to be getting the values to populate within the list correctly. I can't even seem to get into the for loop in the provided code, am I missing something?
AngularJS:
$scope.vendorUserList = [];
SpringDataRestService.get(
{
"collection": "user"
},
function (response) {
var users = response;
for (var i = 0, len = users.length; i < len; i++) {
if (users[i].type === "VENDOR") {
if (users[i].status !== "PENDING_DEACTIVATION") {
var newUser = {id: users[i].id, name: users[i].name};
$scope.vendorUserList.push(newUser);
}
}
}
},
}
);
JSON:
http://localhost:8080/api/users
{
"status": "ACTIVE",
"userName": "CLIENT 2"
}
I used AngularJS $http.get to first return the entire list of users and then I filtered out the users living in the city of Wisokyburgh that also have a zip-code, using your code (slightly modified).
var root = 'https://jsonplaceholder.typicode.com';
// Create an Angular module named "usersApp"
var app = angular.module("usersApp", []);
// Create controller for the "usersApp" module
app.controller("usersCtrl", ["$scope", "$http", function($scope, $http) {
$scope.vendorUserList = [];
var url = root + "/users"
$http.get(url)
.then(function(data) {
var users = data.data;
console.log(users);
for (var i = 0; i < users.length; i++) {
if (users[i].address.city === "Wisokyburgh") {
if (users[i].address.zipcode !== "") {
var newUser = {
id: users[i].id,
name: users[i].name
};
$scope.vendorUserList.push(newUser);
}
}
}
console.log($scope.vendorUserList);
});
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.2/angular.min.js"></script>
<div class="container" data-ng-app="usersApp">
<div data-ng-controller="usersCtrl">
<select>
<option value="0">Choose from the list</option>
<option ng-repeat="user in vendorUserList" value="user.id">{{user.name}}</option>
</select>
</div>
</div>
The case is similar to yours, but the url is public (it needs to be, so that the snippet works). Hope it helps.
Want to call a controller function from a directive tag.
Demo : https://jsfiddle.net/6qqfv61k/
when clicked on 'Export to Excel' i want to call dataToExport() from appCtrl as data is available to export.Any inputs?
html:
<div ng-controller="appCtrl">
</div>
<div excel-export export-data="exportData" file-name="{{fileName}}"></div>
js code:
var app = angular.module('myApp', []);
app.controller('appCtrl', ['$scope', function($scope) {
$scope.dataToExport = function(){
$scope.jsonToExport = [
{
"col1data": "1",
"col2data": "Fight Club",
"col3data": "Brad Pitt"
},
{
"col1data": "2",
"col2data": "Matrix (Series)",
"col3data": "Keanu Reeves"
},
{
"col1data": "3",
"col2data": "V for Vendetta",
"col3data": "Hugo Weaving"
}
];
// Prepare Excel data:
$scope.fileName = "report";
$scope.exportData = [];
// Headers:
$scope.exportData.push(["#", "Movie", "Actor"]);
// Data:
angular.forEach($scope.jsonToExport, function(value, key) {
$scope.exportData.push([value.col1data, value.col2data, value.col3data]);
});
}
}]);
//directive
Use & in the scope option of the directive. & bindings are ideal for binding callback functions to directive. Pass function to the directive as callback
Move the directive inside controller scope
<div ng-controller="appCtrl">
<div excel-export export-data="exportData" file-name="{{fileName}}" call-back="dataToExport()"></div>
</div>
Directive
.directive('excelExport',
function () {
return {
restrict: 'A',
scope: {
fileName: "#",
data: "&exportData",
callBack: "&"
},..
invoke callBack() in the click method of the directive
scope.download = function() {
scope.callBack();
....
}
you can define dataToExport into directives scope function. please take a look
<div ng-controller="appCtrl">
<div excel-export export-data="exportData" export="dataToExport()" file-name="{{fileName}}"></div>
</div>
app
.directive('excelExport',
function () {
return {
restrict: 'A',
scope: {
fileName: "#",
data: "&exportData",
dataToExport: '&export'
},
replace: true,
template: '<button class="btn btn-primary btn-ef btn-ef-3 btn-ef-3c mb-10" ng-click="download()">Export to Excel <i class="fa fa-download"></i></button>',
link: function (scope, element) {
scope.download = function() {
scope.dataToExport();
function datenum(v, date1904) {
if(date1904) v+=1462;
var epoch = Date.parse(v);
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
};
function getSheet(data, opts) {
var ws = {};
var range = {s: {c:10000000, r:10000000}, e: {c:0, r:0 }};
for(var R = 0; R != data.length; ++R) {
for(var C = 0; C != data[R].length; ++C) {
if(range.s.r > R) range.s.r = R;
if(range.s.c > C) range.s.c = C;
if(range.e.r < R) range.e.r = R;
if(range.e.c < C) range.e.c = C;
var cell = {v: data[R][C] };
if(cell.v == null) continue;
var cell_ref = XLSX.utils.encode_cell({c:C,r:R});
if(typeof cell.v === 'number') cell.t = 'n';
else if(typeof cell.v === 'boolean') cell.t = 'b';
else if(cell.v instanceof Date) {
cell.t = 'n'; cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
}
else cell.t = 's';
ws[cell_ref] = cell;
}
}
if(range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
return ws;
};
function Workbook() {
if(!(this instanceof Workbook)) return new Workbook();
this.SheetNames = [];
this.Sheets = {};
}
var wb = new Workbook(), ws = getSheet(scope.data());
/* add worksheet to workbook */
wb.SheetNames.push(scope.fileName);
wb.Sheets[scope.fileName] = ws;
var wbout = XLSX.write(wb, {bookType:'xlsx', bookSST:true, type: 'binary'});
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), scope.fileName+'.xlsx');
};
}
};
}
);
I am trying to filter elements based on the range. I am using two controllers & $rootScope broadcast-on approach to retrieve the min-max range of a slider & sharing it with the other controller.
HTML-
<body ng-app="myApp">
<div ng-controller="RangeController as vm">
<rzslider rz-slider-model="vm.slider.minValue" rz-slider-high="vm.slider.maxValue" rz-slider-options="vm.slider.options"></rzslider>
</div>
<div ng-controller="SampleController">
<div ng-repeat="x in elements | inRange:min:max">
{{x}}
</div>
</div>
</body>
AngularJS-
var app = angular.module('myApp', ['rzModule']);
app.controller('SampleController', function($scope,$rootScope) {
$scope.min = 1500;
$scope.max = 5500;
$scope.elements = [1530,2100,2780,3323,3420,4680,5020,5300,5402];
$scope.$on('MIN_PRICE', function(response) {
$scope.min = minPrice;
})
$scope.$on('MAX_PRICE', function(response) {
$scope.max = maxPrice;
})
});
app.value('minPrice',1500);
app.value('maxPrice',5500);
app.controller('RangeController', RangeController);
function RangeController($scope,$rootScope) {
var vm = this;
vm.changeListener = function() {
minPrice = vm.slider.minValue;
maxPrice = vm.slider.maxValue;
console.log(minPrice + " " +maxPrice);
$rootScope.$broadcast('MIN_PRICE', minPrice);
$rootScope.$broadcast('MAX_PRICE', maxPrice);
};
vm.slider = {
minValue: 1500,
maxValue: 5500,
options: {
floor: 1500,
ceil: 5500,
step: 500,
translate: function(value) {
return '₹' + value;
},
onChange:vm.changeListener
}
}
}
app.filter('inRange', function() {
return function(array, min, max) {
array = array.filter(function(element) {
return (element >= min && element <= max);
});
console.log(array);
};
});
I tried debugging, the filter works fine but it won't reflect in the template.
The self-assignment to array inside your filter (array = array.filter(…);) seems slightly suspicious to me. Have you tried simply returning array.filter(…); directly?
app.filter('inRange', function() {
return function(array, min, max) {
return array.filter(function(element) {
return (element >= min && element <= max);
});
};
});
I have a directive that validates text to be in a specific format:
angular.module('app')
.directive('validNumber', validNumber);
function validNumber() {
var directive = {
restrict: 'A',
require: '?ngModel',
link: linkFunc
};
return directive;
function linkFunc(scope, element, attrs, ngModelCtrl) {
if (!ngModelCtrl) {
return;
}
ngModelCtrl.$parsers.push(function (val) {
if (angular.isUndefined(val)) {
var val = '';
}
var clean = val.replace(/[^0-9\.]/g, '');
var decimalCheck = clean.split('.');
if (!angular.isUndefined(decimalCheck[1])) {
decimalCheck[1] = decimalCheck[1].slice(0, 2);
clean = decimalCheck[0] + '.' + decimalCheck[1];
}
if (val !== clean) {
ngModelCtrl.$setViewValue(clean);
ngModelCtrl.$render();
}
return clean;
});
element.bind('keypress', function (event) {
if (event.keyCode === 32) {
event.preventDefault();
}
});
}
}
Now I want to test the inner parser function I added and I just can't do it. How can I invoke a call to that function? How can I test the result? My very unsuccessful tests are:
describe('validNumber directive specs', function () {
var scope, compile;
var validHtml = '<form name="testForm"><input name="test" type="text" valid-number ng-model="str" /></form>';
beforeEach(function () {
angular.mock.module('dashboardApp');
module(bootstrapperMock);
inject(function (_$rootScope_, _$compile_) {
scope = _$rootScope_.$new();
compile = _$compile_;
});
});
describe('When a key press occures', function () {
it('should :( ', function () {
scope.str = 0;
var element = compile(validHtml)(scope);
var viewValue = 2, input = element.find('input');
scope.str = viewValue;
scope.$digest();
var e = angular.element.Event('keypress keydown');
e.which = 50;
element.trigger(e);
scope.$digest();
});
});
});
I tried both changing the model and triggering a keypress.
Thanks!
The following works:
describe('When a key press occures', function () {
it('when a key press', function () {
var expected = '';
var element = compile(validHtml)(scope);
element.val('asda');
element.trigger('input');
var actual = element.val();
expect(expected).toBe(actual);
});
});
I also updated the html in this spec:
var validHtml = '<input name="test" type="text" valid-number ng-model="str" />';
The magic here is to trigger 'input' for the element.