problems in filter in angularjs - javascript

i have a problems in my filter , i explain you, when my program start , i initiaze the table(ng repeat)
but
first
in console log () When I initialize the first time it puts me "item undifined" and then it returns in directly in the filter "myfilter" and it shows me the object,
i don't uderstand why i have "items undifined"
And I would like it to do it all at once and the second problem is to link to the first problem, when I press a datepicker field it makes me 2 alert so it calls twice the filter
this is my filter code
routeAppControllers.filter("myfilter", function($filter) {
return function(items, from, to) {
const testFrom = Date.parse(from);
const testTo = Date.parse(to);
if (!testFrom){
// console.log('Not valid');
from = moment();
}
if (!testTo){
to = moment('2500-01-01');
}
const valids = items.reduce((acc,val) => {
var st = val.DATE_AGENDA;
// alert(val.DATE_AGENDA);
/*
var res = st.substring(0, 10);
var res = res.split("-");
var res1= res[2]+'-'+res[1]+'-'+res[0];
alert(res);
var dt = new Date(res1);
*/
const date = moment(val.DATE_AGENDA);
if(date.isSameOrAfter(from) && date.isSameOrBefore(to))
acc.push(val)
return acc;
},[]);
return valids;
};
});
this is my 2 inputs
<input type="text" placeholder="Date debut" class="form-control" ng-click="open1()" uib-datepicker-popup ng-model="startDate" show-button-bar="false" is-open="popup1.opened" datepicker-options="dateOptions" ng-change="filter()" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open1()"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
<input type="text" placeholder="Date fin" class="form-control" ng-click="open2()" uib-datepicker-popup ng-model="endDate" show-button-bar="false" is-open="popup2.opened" datepicker-options="dateOptions" ng-change="filter()" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open2()"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
and this is my ng-repeat
<tr ng-repeat="data in filtered = (myData | filter:search | orderBy : predicate :reverse | myfilter: startDate: endDate) | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">
and i make i plunker for more help
http://plnkr.co/edit/6RuUjkON4HaXE3EHg7bn?p=preview
if somenone can help me
thanks in advance

Related

Angular JS datepicker doesn't update model

I'm trying to filter a table using a daterange, but can't get the model to update so it doesn't know what date I picked.
This is the HTML for the datepicker popup:
<label>From:</label>
<p class="input-group" style="width:200px">
<input type="text" class="form-control" uib-datepicker-popup = "{{format}}" ng-model="dt" is-open="status.opened"
min-date="minDate" max-date="maxDate" datepicker-options="dateOptions" date-disabled="disabled(date, mode)"
ng-required="true" close-text="Close"/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
The JS code in my controller:
(function ()
{
'use strict';
angular.module('aml-tech-dashboard.successful-emails').controller('datepickerController', function ($scope) {
$scope.dt = '';
$scope.status = {
opened: false
};
$scope.format = "yyyy-MM-dd"
$scope.minDate = new Date();
$scope.dateOptions = {
//formatYear: 'yy',
startingDay: 1
};
$scope.open = function ($event) {
$scope.status.opened = true;
};
});
})();
Table:
<tr ng-repeat = 'file in files | startFrom: dt'>
Your tr element is wrong. It should look like this:
<tr ng-repeat="file in files | startFrom: dt"></tr>
You also have a mistake in the uib-datepicker-popup directive. It should look like this:
uib-datepicker-popup="{{format}}"
This is assuming you have defined the startFrom filter elsewhere in your module, as it is not a built-in Angular filter.
try this:
$scope.dt = new Date();
and make sure that the controller is invoked when the view render.

Vue js button freezes dom

I am trying to toggle a span containing a loading animation on a button press until the function completes using v-if. But when I press the button the DOM freezes and the span element is unchanged until the function call ends. How can I make the DOM not freeze and the loading icon to show? Non blocking button press might be a solution?
HTML
<form class="form-inline">
<div class="form-group">
<div style="display: inline-flex" class='input-group date' id='datetimepicker1'>
<input placeholder="Start Date" id="pick1" type='text' class="form-control"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class="form-group">
<div style="display: inline-flex" class='input-group date' id='datetimepicker2'>
<input placeholder="End Date" id="pick2" type='text' class="form-control"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class="form-group">
<input class="form-control" type="text" v-model="Keyword" placeholder="keyword">
</div>
#*Start Date<input type="text" v-model="StartDate" placeholder="Start Date" style="width: 177px" />
End Date <input type="text" v-model="EndDate" placeholder="End Date" style="width: 177px" />*#
<button type="button" v-show="resetShow" class="btn btn-primary btn-lg " v-on:click="reset" id="reset-btn">Reset filters</button>
<button type="button" v-show="GetShow" type="button" class="btn btn-primary btn-lg " v-on:click="getEdges">Get Edges</button>
<button v-show="GetShow" type="button" class="btn btn-primary btn-lg " v-on:click="getNodes">Get Nodes</button>
<button v-on:click="send" type="button" class="btn btn-default" id="load" >Submit</button>
<span v-if="loading" id="loader" style="display:none"> <i style="font-size: 197%; color: purple" class='fa fa-circle-o-notch fa-spin'></i> <span style="font-size: 190%"> Processing </span> </span>
Javascript
var vm = new Vue({
el: '#main',
data: {
resetShow: false,
Keyword: '',
StartDate: '2016-06-08T17:03:36.000Z',
EndDate: '2016-06-16T17:03:36.000Z',
Dialog: [],
EdgeList: [],
NodeList: [],
loading: false,
StartDate1: '',
GetShow: false
},
// define methods under the `methods` object
methods: {
getById: function(event) {
},
send: function(event) {
this.loading = true;
console.log(this.StartDate1);
var StartDate = $('#datetimepicker1').data("DateTimePicker").date().utc().format().split('+')[0]+".000Z";
var EndDate = $('#datetimepicker2').data("DateTimePicker").date().utc().format().split('+')[0]+".000Z";
if (this.Keyword != null) {
var g = GetElasticSearch(this.Keyword, StartDate, EndDate);
s.graph.clear();
s.graph.read(g);
sigma.canvas.edges.autoCurve(s);
s.refresh();
// Start the ForceLink algorithm:
sigma.layouts.startForceLink();
//Louv
var louvainInstance = sigma.plugins.louvain(s.graph,
{
setter: function(communityId) { this.my_community = communityId; }
});
var nbLevels = louvainInstance.countLevels();
console.log(nbLevels);
var partitions = louvainInstance.getPartitions();
var nbPartitions = louvainInstance.countPartitions(partitions);
// Color nodes based on their community
s.graph.nodes()
.forEach(function(node) {
//console.log(node.my_community);
node.color = colors[node.my_community];
});
s.refresh({ skipIndexation: true });
s.graph.nodes()
.forEach(function(node) {
node.color = colors[node.my_community];
});
s.refresh({ skipIndexation: true });
this.loading = true;
}
}
}
});
Vue updates the DOM asynchronously, when the method is finished, so to speak.
So you have to make the part of the function that takes a long tim async, so it does not block the event loop.
You can use setTimeout(callback, 0) to run the function async.
Example: https://jsfiddle.net/Linusborg/tn8q4sub/
(Edit: The example does not always work for me though I don't quite get why that is - give it a try with your situation)
For your code, this should look something like this:
send: function(event) {
this.loading = true;
setTimeout(function () {
//rest of the send code.
// and at the end:
this.loading = false
}.bind(this),0) // the `bind(this)` is important!
}

TypeError: Undefined on module pattern of object instances

This is kind of a follow-up to this question:
How to have at least two datepickers of ui-bootstrap on a single page?
It does a great job of having an elegant way to handle multiple instances of angular bootstrap datepicker elements on the same view/page. At least it appears to... I get the following error.
TypeError: Cannot set property 'BeginDate' of undefined
This occurs when I click to attempt to open the date dialog. It happens on the line below, which you can see in the code sample below that. The instances object is undefined.
method.instances[instance] = true;
From what I can tell, my code and the example in the other question are nearly identical.
Example controller code:
$scope.datePicker = (function() {
var method = {};
var instances = [];
method.open = function ($event, instance) {
$event.preventDefault();
$event.stopPropagation();
method.instances[instance] = true;
};
method.minDate = new Date();
method.maxDate = new Date(2023, 12, 24);
method.options = {
formatYear: "yyyy",
startingDay: 1
};
method.format = "dd-MM-yyyy";
return method;
}());
Example element code:
<div class="form-group">
<label for="beginDate" class="col-md-5">Begin Date</label>
<input type="text" name="beginDate" ng-model="codeCamp.BeginDate" datepicker-popup="{{datePicker.format}}" min-date="datePicker.minDate" max-date="datePicker.maxDate" datepicker-options="datePicker.options" is-open="datePicker.instances['BeginDate']" ng-required="true" close-text="Close" class="form-control" required />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="datePicker.open($event, 'BeginDate')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
<div class="form-group">
<label for="endDate" class="col-md-5">End Date</label>
<input type="text" name="endDate" ng-model="codeCamp.EndDate" datepicker-popup="{{datePicker.format}}" min-date="datePicker.minDate" max-date="datePicker.maxDate" datepicker-options="datePicker.options" is-open="datePicker.instances['EndDate']" ng-required="true" close-text="Close" class="form-control" required />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="datePicker.open($event, 'EndDate')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
Have you tried to create the instances array in the method object?
Instead of this:
var method = {};
var instances = [];
Use this:
var method = {};
method.instances = [];
Let me know!

Using datepicker on more than one input

I have following two input fields that use datepicker.
<div class="row">
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt" is-open="opened" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
<div>
<div class="row">
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt2" is-open="opened" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
The controller code is
angular.module('plunker', ['ui.bootstrap']);
var DatepickerDemoCtrl = function ($scope) {
$scope.today = function() {
$scope.dt = new Date();
};
$scope.today();
$scope.showWeeks = true;
$scope.toggleWeeks = function () {
$scope.showWeeks = ! $scope.showWeeks;
};
$scope.clear = function () {
$scope.dt = null;
};
// Disable weekend selection
$scope.disabled = function(date, mode) {
return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
};
$scope.toggleMin = function() {
$scope.minDate = ( $scope.minDate ) ? null : new Date();
};
$scope.toggleMin();
$scope.open = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened = true;
};
$scope.dateOptions = {
'year-format': "'yy'",
'starting-day': 1
};
$scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'shortDate'];
$scope.format = $scope.formats[0];
};
Problem is whenever I click any button both datepicker calenders pop up. Here is the plunker for it
http://plnkr.co/edit/hcLogY0SPsFzewcCt0xh?p=preview
Please let me know how to fix it. Thanks
You can split your code with 2 ng-controllers.
http://plnkr.co/edit/Cp7ZlWl8Ee8TCAOnfxv2?p=preview

How to usemultiple Angular UI Bootstrap Datepicker in single form?

I have a form where there is a need for me to have 2 or more date fields for different things. I tried the Angular UI Bootstrap which works fine when I have only 1 date field in the form. But it stops working if I have multiple date fields and I dont know the easier method to get this to work.
This is my HTML sample:
<label>First Date</label>
<div class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" name="dt" ng-model="formData.dt" is-open="opened" datepicker-options="dateOptions" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
<label>Second Date</label>
<div class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" name="dtSecond" ng-model="formData.dtSecond" is-open="opened" datepicker-options="dateOptions" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
My JS is:
myApp.controller('DatePickrCntrl', function ($scope) {
$scope.today = function() {
$scope.formData.dt = new Date();
};
$scope.today();
$scope.showWeeks = true;
$scope.toggleWeeks = function () {
$scope.showWeeks = ! $scope.showWeeks;
};
$scope.clear = function () {
$scope.dt = null;
};
// Disable weekend selection
$scope.disabled = function(date, mode) {
return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
};
$scope.toggleMin = function() {
$scope.minDate = ( $scope.minDate ) ? null : new Date();
};
$scope.toggleMin();
$scope.open = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened = true;
};
$scope.dateOptions = {
'year-format': "'yy'",
'starting-day': 1
};
$scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'shortDate'];
$scope.format = $scope.formats[0];
});
I implemented based on the sample here. The problem I have here is:
1) When one of the date field is clicked, the pop-up datepicker is messed up and seems to show 2 datepicker in 1.
2) When I remove is-open="opened" attribute, the pop-up window seems to work fine. But without is-open="opened", the ng-click="open($event) for the button doesnt work.
3) Since each of the date fields have different ng-models, I am unable to set default dates for any date fields except for the first one with ng-model="formData.dt"
The only long way to resolve this that I can think of is to separate the controller for each date field.
I would like to know how others implement multiple date fields in 1 form itself when using Angular UI Bootstrap.
I have 30 in one form one controller no problem. use the same concept if you need it on ng-repeat.
<label>First Date</label>
<div class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}"
name="dt" ng-model="formData.dt" is-open="datepickers.dt"
datepicker-options="dateOptions" ng-required="true"
close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event,'dt')">
<i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
<label>Second Date</label>
<div class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}"
name="dtSecond" ng-model="formData.dtSecond"
is-open="datepickers.dtSecond" datepicker-options="dateOptions"
ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event,'dtSecond')">
<i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
myApp.controller('DatePickrCntrl', function ($scope) {
$scope.datepickers = {
dt: false,
dtSecond: false
}
$scope.today = function() {
$scope.formData.dt = new Date();
// ***** Q1 *****
$scope.formData.dtSecond = new Date();
};
$scope.today();
$scope.showWeeks = true;
$scope.toggleWeeks = function () {
$scope.showWeeks = ! $scope.showWeeks;
};
$scope.clear = function () {
$scope.dt = null;
};
// Disable weekend selection
$scope.disabled = function(date, mode) {
return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
};
$scope.toggleMin = function() {
$scope.minDate = ( $scope.minDate ) ? null : new Date();
};
$scope.toggleMin();
$scope.open = function($event, which) {
$event.preventDefault();
$event.stopPropagation();
$scope.datepickers[which]= true;
};
$scope.dateOptions = {
'year-format': "'yy'",
'starting-day': 1
};
$scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'shortDate'];
$scope.format = $scope.formats[0];
});
// ***** Q2 ***** somemodel can be just an array [1,2,3,4,5]
<div ng-repeat="o in somemodel">
<label>Date Label</label>
<div class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}"
name="dt{{o}}" ng-model="datepickers.data[o]"
is-open="datepickers.isopen[o]" datepicker-options="datepickers.option"
ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event,o)">
<i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
</div>
myApp.controller('DatePickrCntrl', function ($scope) {
$scope.datepickers = {
data: {},
options: {
'year-format': "'yy'",
'starting-day': 1
},
isopen: {}
}
$http.get("get/data/for/some/model", function(result) {
$scope.somemodel = result;
for (var i = 0; i < result.length; i++) {
$scope.datepickers.isopen[result] = false;
$scope.datepickers.data[result] = new Date(); //set default date.
}
});
// fill in rest of the function
});
Simpler Solution. Requires only modding the HTML and can be used in a ng-repeat if you like. Just be creative with what you name the opened
Stick this in your Controller:
$scope.calendar = {
opened: {},
dateFormat: 'MM/dd/yyyy',
dateOptions: {},
open: function($event, which) {
$event.preventDefault();
$event.stopPropagation();
$scope.calendar.opened[which] = true;
}
};
HTML:
<div class="form-group row">
<div class="col-lg-6">
<label for="formDOB">Date of Birth</label>
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{calendar.dateFormat}}" ng-model="record.birthDate" is-open="calendar.opened.dob" datepicker-options="calendar.dateOptions" close-text="Close" placeholder="Date of Birth" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="calendar.open($event, 'dob')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
<div class="col-lg-6">
<label for="formWinDate">Win Date</label>
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{calendar.dateFormat}}" ng-model="record.winDate" is-open="calendar.opened.win" datepicker-options="calendar.dateOptions" close-text="Close" placeholder="Win DAte" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="calendar.open($event, 'win')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
wayne's answer is great. I would only add, that you can make the function 'open()' better:
$scope.open = function ($event, datePicker) {
$event.preventDefault();
$event.stopPropagation();
$scope.closeAll();
datePicker.opened = true;
};
And then you have to use it like that:
ng-click="open($event, dateFrom)"
Where dateFrom is your ng-model (i.e. you use $scope.dateFrom).
EDIT: $scope.closeAll(); is a function that closes all the datePickers. It can be written like that:
$scope.closeAll = function() {
$scope.dateFrom.opened = false;
$scope.dateTo.opened = false;
};
I'd prefer not to mix ng-model with UI info.For this purpose, is necessary to define an array to store the opening flags, as well as checking if the datePicker is opened or not.
Moreover, I have changes the 'open' behavior to 'toggle' instead, in order to allow closinf the datePicker with the button.
Here is my controller:
$scope.toggleOpenDatePicker = function($event,datePicker) {
$event.preventDefault();
$event.stopPropagation();
$scope[datePicker] = !$scope[datePicker];
};
Then it can be used as:
<input type="text" class="form-control" ng-model="model.date1" is-open="date1" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="toggleOpenDatePicker($event,'date1')"><i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
The $scope idea was borrowed from here:
I solved my problem by use this plunker with minor changes.
HTML
<div class="row">
<div class="col-md-6">
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt" is-open="openDatePickers[0]" min-date="minDate" max-date="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event, 0)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
<h4>Popup</h4>
<div class="row">
<div class="col-md-6">
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt" is-open="openDatePickers[1]" min-date="minDate" max-date="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event, 1)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
and in controller
$scope.openDatePickers = [];
$scope.open = function ($event, datePickerIndex) {
$event.preventDefault();
$event.stopPropagation();
if ($scope.openDatePickers[datePickerIndex] === true) {
$scope.openDatePickers.length = 0;
} else {
$scope.openDatePickers.length = 0;
$scope.openDatePickers[datePickerIndex] = true;
}
};
my changes
instead numbers (0 or 1) i use $index in angular ng-repeat.
like this:
is-open="openDatePickers[**$index**]"
ng-click="open($event, **$index**)"
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt" is-open="openDatePickers[$index]" min-date="minDate" max-date="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close">
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event, $index)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
i used it in a different way and it looks a bit easier to me. I was using one of the mentioned approaches, but i was to lazy to create tons of calendars since i was running i a loop without having any static identifier.
So this solution is just valid for you, if you want to create lots of calendars inside of a ng-repeat. Hope it helps!
That is the controller
$scope.datepickers = {
data: {},
isopen: {}
}
// setting the defaults once
for (var i = 0; i < $scope.array.length; i++) {
$scope.datepickers.isopen[i] = false;
$scope.datepickers.data[i] = new Date();
}
// aso..
$scope.valuationDatePickerOpen = function($event, index) {
if ($event) {
$event.preventDefault();
$event.stopPropagation();
}
$scope.datepickers.isopen[index] = true;
};
And this is the HTML snipped inside my loop
<!-- ng-repeat="entry in array track by $index" -->
<input type="text" class="form-control"
datepicker-popup="dd-MMMM-yyyy"
is-open="datepickers.isopen[$index]"
ng-click="valuationDatePickerOpen($event, $index)"
ng-model="entry.date" />

Categories