Updating angular date by repeating event - javascript

I have an end date that a user can enter a date to end an scheduled event. However, I want a user to be able to type in a number of times an event can repeat before it ends. For example, if they say they want it to repeat weekly, for 4 weeks, then I want to be able to calculate the end date, and update that value. I'm actually not quite sure how I should even approach this being relatively new to angular.
http://jsfiddle.net/rXHzc/
I was thinking something like this?
function EventEditCtrl($scope) {
init();
function init() {
$scope.event = {
ActiveEndTimeDate: '',
Occurrences: '',
Repeated: ''
}
}
$scope.updateEndDate = function () {
//update event?
};
}

You just need to calculate the end date and assign it to the model. The hard part is doing date math in JavaScript. You can use a library like momentjs to simplify things...
$scope.updateEndDate = function () {
var endDate = moment().add($scope.event.Repeated, parseInt($scope.event.Occurrences));
$scope.event.ActiveEndTimeDate = endDate.format('YYYY/MM/DD');
};
Fiddle: http://jsfiddle.net/cxtNp/
This approach requires the use of ngChange to monitor changes to form values and trigger the update. It relies on having ngChange applied to all the places a change can be triggered and leaks a bit too much logic into the markup. A cleaner approach would be to trigger the change when the model changes.
One way to do this is using a watch...
$scope.$watch('[event.Repeated, event.Occurrences]', function () {
var endDate = moment().add($scope.event.Repeated, parseInt($scope.event.Occurrences));
$scope.event.ActiveEndTimeDate = endDate.format('YYYY/MM/DD');
});
Fiddle: http://jsfiddle.net/c92ud/

Related

how to stop array.filter() function

Am using custom search filter
HtML
<input type="text" pInputText class="ui-widget ui-text" [(ngModel)]
="gloablFilterValue" (ngModelChange)="splitCustomFilter()" placeholder="Find" />
I am using ngModelChange() event on search box
globalSearch(realData, searchText, columns) {
searchText = searchText.toLowerCase();
return realData.filter(function (o) {
return columns.some(function (k) {
return o[k].toString().toLowerCase().indexOf(searchText) !== -1;
});
});
}
splitCustomFilter() {
let columns =
['PartNoCompleteWheel', 'DescriptionCompleteWheel', 'PartNoTyre', 'DescriptionTyre', 'PartNoRim', 'DescriptionRim','DeletedDateFromKDPStr', 'DateFromKDPStr', 'Status'];
this.tyreAndRimList = this.globalSearch(this.tyreAndRimList, this.gloablFilterValue, columns);
}
The this.tyreAndRimList list of values for the columns which is mentioned in a column variable.
Problem
The filter is working good! But the main problem is filter performance is very poor while the record count is huge(more than 100 rows per every column)
When
The filter is working good if am entering a single character (like a). But when I was typing the character continuously the browser is hanging. the reason is the filter has been firing every typing on the filter box(because of am using ngModelChange()// onchange() event)
What I want
I want to stop filtering if the user typing continuously on the search box. Once the user has stop the typing then only I need to start filtering.
What I did
I have tried to handle this by using setTimeout(). But it just wait the filter call for a second. It is working if the user entered just 2 or 3 character's continuously. But if the user typing more than 7 or 8 or above character's, it continues to hang the browser. because of many filter callbacks are processing on the same time.
setTimeout(() => //code of filtering ,1000);
Question
How to stop filtering while user continuously entering value and start the filtering once the user has been stop the typing?
I am working in angular-2 and typescript. But this question is not related with only for angularjs or angular or JavaScript or typescript because of I want an idea not a solution. So I'll add those all tags for this question. Don't remove it. Thanks
Debounce the function. See how underscore does it here: Function Debouncing with Underscore.js.
You would then generate a debounced version of your function like this:
var globalSearchDebounced = _.debounce(globalSearch, 100, false);
It will only call after the user has stopped typing for at least one second.
It's not possible to interrupt the Array.filter method. Based on what you need you could handle this like this:
let timerId = null
function handleChange() {
if(timerId) {
clearTimeout(timerId)
}
timerId = setTimeout(() => /* Array.filter(...) */, 1000)
}
Explanation
Have a variable which will contain the timerId returned from the setTimeout function. Every time the model get changed the handleChange function will be called (in this example). The function checks if the variable which contains the timerId is set and contains a timerId, when the variable contains the timerId the clearTimeout function will be called to clear the previous timeout after that the handleChange creates a new timeout and assigns the timerId (returned from the setTimeout function) to the variable.
Documentation for setTimeout
Documentation for clearTimeout
Without underscore, and without a Timeout (that will trigger the whole Angular lifecycle by the way), you can use an Observable with the async pipe and a debounce.
In your global search function :
return Observable.of(/* filter here and return the filtered array */).debounceTime(1000)
In your list (that has to be somewhere I guess)
<list-item *ngFor="let x of myFilteredResults | async">...</list-item>
I have complete it by using Subject to debounceTime.
private subject = new Subject<string>()
ngOnInit() {
this.subject.debounceTime(300).subscribe(inputText => {
this.gloablFilterValue = inputText;
this.splitCustomFilter(); // filter method
});
}
Now when I change the value in this.gloablFilterValue object by using change event. It just waiting for the end of event completion.

How to add separator between time and meridiem(AM?PM) in clockpicker?

I am using clockpicker for time selection and in that I have used twelvehour:true parameter which displays time with AM/PM. Now the time display using it is like
11:55AM ==> 11:55 AM
whereas I want separator in between time and meridiem
So, there is an event beforeDone/afterDone but no example given so not getting how to use that event to change the value?
How can I separator between time and meridiem(AM?PM) in clockpicker? Thanks
Using afterDone looks like the easiest way to add the separator. It looks like afterDone is just a property you set when you make the input field a clockpicker (in the same place you tell it twelvehour:true). I found this page which was helpful in showing the events: https://weareoutman.github.io/clockpicker/jquery.html
I made this jsfiddle for you http://jsfiddle.net/1e71occs/4/. The JavaScript code is:
$('.container').each(function(){
var clockpicker = $(this).find('input').clockpicker({
autoclose: true,
twelvehour:true,
afterDone: function() {
console.log("after done");
clockpicker.val(clockpicker.val().slice(0,-2)+' '+clockpicker.val().slice(-2));
}
});
// Manual operations
$(this).find('.button-a').click(function(e){
// Have to stop propagation here
e.stopPropagation();
clockpicker.clockpicker('show').clockpicker('toggleView', 'minutes');
});
$(this).find('.button-b').click(function(e){
// Have to stop propagation here
e.stopPropagation();
clockpicker.clockpicker('show').clockpicker('toggleView', 'hours');
});
});
I had to do the var clockpicker = bit to get a reference to the clockpicker so I could change its value to include the seperator. I tried using $(this).val() but it seems to refer to the $(window).
I added this as an option, along with several more involving twelve hour time here: https://github.com/diracleo/bootstrap-clockpicker

Angular data-bs-datepicker directive + on date change

So I have a list of tasks.
Each task has a planned start date and a planned end date (plannedStartDate / plannedEndDate). I use ng-repeat to create my table.
I need a simple anchor which on click triggers a datepicker AND:
has the start date set to the plannedStartDate of the task (it is never null)
is bound to the plannedEndDate of the task, as in, whenever a value is selected, I have to somehow catch this event so I can update the DB value (plannedEndDate) of the task.
I have to show the date in format: dd/mm/yyyy
BUT:
both the plannedStartDate and plannedEndDate have this format: 2015-01-01T00:00:00.000
Currently, my datepicker looks like:
<a href="#" data-bs-datepicker
data-date-startDate="task.plannedStartDate" data-ng-model="task.plannedEndDate"
data-date-format="dd/mm/yyyy"
data-date-type="string">
{{task | dateIndication}}
</a>
I've tried with and without the date-format and date-type, but neither seem to help me. Also, the start date is automatically set to TODAY if I use this, even though the plannedStartDate of the task is not today. (I'm guessing it's a date formatting issue?)
I have tried putting a watch on the tasks array:
$scope.$watch('tasks', function (newVal) { /*...*/ }, true);
(and with a few more variations like using watch collection etc), but nothing!
The change is simply not caught.
(also, the dateIndication filter looks like:
.filter('dateIndication', function () {
return function (task) {
if (task.plannedEndDate) {
var plannedEndDate = moment(task.plannedEndDate);
return plannedEndDate.format('L');
} else {
return messages.dashboard.todosAndTasks.noDueDate();
}
}
})
I would very much need some help. Thank you!
var change;
change = function(date) {
var r;
r = date.match(/^\s*([0-9]+)\s*-\s*([0-9]+)\s*-\s*([0-9]+)(.*)$/);
return r[2] + "-" + r[3] + "-" + r[1] + r[4];
};
use this function and pass the date when function is call it will return the perfect format for datepicker and it shows perfectly fine and one more thing u need to split the date before passing the date then it works fine check it out and tell me what is diffrent

Find the lapse of time

I'm trying to get the time lapse between 2 diferent hours....
function time()
{
var startime=(document.getElementById("horaentrada").value);
var endtime=(document.getElementById("horasaida").value);
document.getElementById("total_horas").value = (endtime-startime);
}
the idea is to fill a html input "total_horas" with the result. The function is triggered by an onchange event. The entry format is "HH:mm:ss", by instance 9:35:22.
I've tried a lot of things, but, no one works I get NaN.
Try this:
function time()
{
var startime=(document.getElementById("horaentrada").value);
var endtime=(document.getElementById("horasaida").value);
document.getElementById("total_horas").value= (parseFloat(endtime,10)-parseFloat(startime, 10));
}
Also, make sure to run the function after the dom is loaded.
Fiddle: http://jsfiddle.net/LnLdB/2/ . Just be gentle with the stuff you input in the boxes.
EDIT: Here is an updated fiddle, using moment.js. It subtracts hours in the format "HH:mm:ss": http://jsfiddle.net/LnLdB/13/

Changewheel functionality How it works?

First of all I want share my appreciation for the amazing work done with this snippet (it's really really a cool tool).
I am trying to use mobiscroll in an app that I am currently developing. I love how easy is to use and customize the mobiscroll tool.
What I really find just obscure, is how use the functionality changeWheel. I tried many things but never with success.
What I am trying to accomplish is to change the values of the first wheel (change completely and regenerate the first wheel), when in my second wheel I select (actually what I want is an on change event) one of the two parameters present.
I build up a function that create the arrays for the two wheels, and that change array of the first wheel relatively to the index of the second wheel returned. (I can see that the function works, and that it generate the exact values for the wheels).
How then I can implement this with the onchange event on the inst, using the function changewheel???
Is this function changewheel suppose to do what I am looking for?
To be very clear, think as an example:
first wheel weight of a person
second wheel unit of measurement (kg or Lbs)
If I change on the spot Lbs to Kg, I want that the first wheel reflect the changes (updating the values available) - if for example i set the limit weight between 0 and 80kg the correspondent value in lbs need to be between 0 and 177lbs (the whole conversion is handled separately with another customized function, and it works exactly as I want).
I can't figure out how instead implement the changewheel event....an example or some more deep explanation will be really useful.
Thank you so much
Best
Dinuz
here goes a simple explanation, if you want to update the values of a diferent whell you need to pass the instance of the mobiscroll and call the method options
$(function(){
var filtersMetrics = [{}];
var wheelPosMetrics = []
var wheelPosFunc1 = [];
var wheelPosFunc = [];
wheelPosMetrics[0] = "Connection";
wheelPosMetrics[1] = "Shared";
wheelPosMetrics[2] = "Deleted";
filtersMetrics[0]['Metrics']=wheelPosMetrics;
wheelPosFunc1[0] = "Count";
wheelPosFunc[0] = "Count";
wheelPosFunc[1] = "Sum";
wheelPosFunc[2] = "Avg";
filtersMetrics[0]['Func']=wheelPosFunc1;
var metricsScroller = $("#select").mobiscroll().scroller({
theme : 'android',
display : 'inline',
mode: 'scroller',
wheels: filtersMetrics,
rows: 3,
'onChange' : function(v, i , e){
if(v[0]==1){
filtersMetrics[0]['Func']=wheelPosFunc;
metricsScroller.mobiscroll('option', 'wheels', filtersMetrics);
}else{
filtersMetrics[0]['Func']=wheelPosFunc1;
metricsScroller.mobiscroll('option', 'wheels', filtersMetrics);
}
}
});
});
I have used the 2.5 version
I also wasn't able to get changeWheel to work, but I found a workaround (I'm using Mobiscroll v2.15.1).
In the onChange–Handler you can set the default values dynamicaly:
.
.
.
onChange: function (values) {
// here your logic for the current values
if (/*here your condition*/) {
// Example for three wheels:
var curWheel = ["1", "2", "3"];
// set the default values
$(/*your element*/).mobiscroll("setArrayVal", curWheel, true);
}
},
.
.
.

Categories

Resources