VueJs: To Disable all dates up to specific date based on condition - vue.js

I have datepicker below :
import Datepicker from 'vuejs-datepicker';
<datepicker :disabled-dates="disabledDates" v-model="dateTime" :format="customFormatter" width="100%" name="Date"></datepicker>
If CurrentDay == "Monday" then, disable all dates up to last friday of previous week. Otherwise, disable all dates up to last friday of current week.
export default {
created: function() {
var currentDate = new Date().toJSON().slice(0,10).replace(/-/g,'-');
var CurrentDay = moment().format('dddd'); //new Date().getDay();
if (CurrentDay == "Monday"){
this.disabledDates= {
to: new Date(2020, 2, 5) // Here disable all dates up to last friday of the previous week.
};
}
else{
this.disabledDates= {
to: new Date(2020, 2, 5) //Here disable all dates up to last friday of the current week.
};
}
}
}

sandbox
<template>
<div id="app">
Current date: {{ date }}
<Datepicker v-if="date" :value="today" :disabled-dates="disabledDates"/>
</div>
</template>
<script>
import Datepicker from "vuejs-datepicker/dist/vuejs-datepicker.esm.js";
export default {
data() {
return {
today: new Date(),
date: null,
disabledDates: {}
};
},
components: {
Datepicker
},
methods: {
// Utility: To get date by day
// In our case to get last week friday & this week friday
// first param: current date / any select date as reference
// second param: day, in our case friday ie. 5
// third param: week, in our case last week ie. -7 (7 days from now) & current week ie. 0
getDateByDay(currDate, day, week = 0) {
var reqDate = currDate;
var reqDay = day - currDate.getDay() + week;
reqDate.setDate(reqDate.getDate() + reqDay);
return {
day: reqDate.getDate(),
month: reqDate.getMonth(),
year: reqDate.getFullYear()
};
},
// Strategy / logic to block on basis of monday / other days
strategy({ year, month, day }) {
this.date = new Date(year, month, day);
let getDay = this.date.getDay();
console.log({ getDay });
// Check if monday ie. 0
if (getDay === 1) {
let { day, month, year } = this.getDateByDay(this.date, 6, -7 * 2);
// Get last friday date & block upto last friday
this.disabledDates.to = new Date(year, month, day);
}
// OTHER THAN MODAY
else {
let { day, month, year } = this.getDateByDay(this.date, 6, -7);
// Get current friday & block uptp current friday
this.disabledDates.to = new Date(year, month, day);
}
}
},
mounted() {
// invoke blocking function with any date
this.strategy({ year: 2020, month: 2, day: 25 });
}
};
</script>
PS: You can modify logic as per your use case by passing desired params.

Related

Youtrack Workflow to set issue due date based on issue start date + estimate

I am trying to set up a workflow on youtrack where it sets automatically the end date based on the start date + estimates.
For example, my issue start date is 2022/10/01 and it has an estimate of 10d (10 days, for example). I want that the end date to be set of 2022/10/10.
I couldn't figure out how to set this rule as I couldn't user the workflow constructor for it.
Thanks
Here is an example of a similar workflow that automatically adds the Planned time value to Start date field and writes the result in the Due date field:
const entities = require('#jetbrains/youtrack-scripting-api/entities');
exports.rule = entities.Issue.onChange({
title: 'End date',
guard: (ctx) => {
return (ctx.issue.fields.isChanged(ctx.Plan) || ctx.issue.fields.isChanged(ctx.StartDate)) && ctx.issue.fields.Plan != null && ctx.issue.fields.StartDate != null;
},
action: (ctx) => {
const issue = ctx.issue;
var periodestimate = issue.fields.Plan;
var minutesestimate = !periodestimate ? 0 : (periodestimate.getMinutes() + 60 * (periodestimate.getHours() + 24 * (periodestimate.getDays() + 7 * periodestimate.getWeeks())));
ctx.issue.fields.EndDate = issue.fields.StartDate + (minutesestimate * 60000);
},
requirements: {
Plan: {
name: "Planned time",
type: entities.Field.periodType
},
EndDate: {
name: "Due Date",
type: entities.Field.dateType
},
StartDate: {
name: "Start Date",
type: entities.Field.dateType
}
}
});

Vuejs: how to loop start time to multiply end time with var x

I have data start_time, end_time, x, and result. I want to display it in the select option, the first option is the initial data start_time, and continues to loop multiples of variable x and ends until the value is equal to end_time. here are the expectations.
Here my view:
<select class="form-control">
<option>08:00:00</option>
<option>08:15:00</option>
<option>08:30:00</option>
<option>08:45:00</option>
<option>09:00:00</option>
<option>...</option>
<option>19:00:00</option>
</select>
This is my code:
data: function () {
return {
start_time: '08:00:00',
end_time: '19:00:00',
x: 15,
result:'',
}
},
computed:{
}
What you can do is create a computed property which returns an array of all the available time options given the start_time and the end_time constraints. Then loop it to your <option/> element using v-for.
<select class="form-control">
<option v-for="(time, index) in times" :key="index">{{time}}</option>
</select>
computed: {
times() {
// transform the start_time and end_time to Date for easier comparison.
let startTime = new Date(`1/1/1970 ${this.start_time}`);
const endTime = new Date(`1/1/1970 ${this.end_time}`);
// This interval is in Minutes.
const interval = this.x * 60000;
// The result array where we will store the time
const results = [];
while (startTime.getTime() <= endTime.getTime()) {
results.push(`${this.formatTime(startTime)}`);
startTime = new Date(startTime.getTime() + interval);
}
return results;
}
},
methods: {
formatTime(date) {
// format the date here...
return '00:00:00';
}
}
For formatting date, you can either use third-party library to do the job, or you can use vanilla javascript.
formatTime(date) {
const hours = date.getHours().toString().padStart(2, "0");
const minutes = date.getMinutes().toString().padStart(2, "0");
const seconds = date.getSeconds().toString().padStart(2, "0");
return `${hours}:${minutes}:${seconds}`;
}
Here is a working demo.

React Native birthday picker - componentWillREceiveProps

I need to build a birthday picker for a react naive application. I found the following https://github.com/ericmorgan1/react-native-birthday-picker but it has the deprecated method componentWillREceiveProps
Im not that experienced yet, so i don't know how to change this to the new methods to make it work. Can anyone help?
//
// DatePicker with an optional year.
//
// code from https://github.com/ericmorgan1/react-native-birthdaypicker/blob/master/BirthdayPicker.js
import React from 'react';
import { StyleSheet, View, Picker, } from 'react-native';
export default class BirthdayPicker extends React.Component {
static defaultProps= {
selectedYear: (new Date()).getFullYear(), // Year to initialize the picker to (set to 0 to not have a year)
selectedMonth: (new Date()).getMonth(), // Month to initialize the picker to
selectedDay: (new Date()).getDate(), // Day to initailize the picker to
yearsBack: 100, // How many years backwards (from starting year) you want to show
onYearValueChange: function(year, idx) { }, // Function called when year changes
onMonthValueChange: function(month, idx) { }, // Function called when month changes
onDayValueChange: function(day, idx) { }, // Function called when day changes
}
constructor(props) {
super(props);
this.startingYear = this.props.selectedYear;
this.state = {
year: this.props.selectedYear,
month: this.props.selectedMonth,
day: this.props.selectedDay,
}
}
componentWillReceiveProps(nextProps) {
this.setState({
year: nextProps.selectedYear, month: nextProps.selectedMonth, day: nextProps.selectedDay
});
}
// Tries to get the browser locale...
getLocale() {
if (navigator.language) { return navigator.language; }
if (navigator.languages && navigator.languages.length > 0) { return navigator.languages[0]; }
return "en-us"; // Default to English
}
// Loops through the months and gets the long name string...
getMonthNames() {
var locale = this.getLocale();
var monthNames = [];
for (var i = 0; i < 12; i++) {
var date = new Date(2000, i, 15);
monthNames.push(date.toLocaleString(locale, { month: "long" }));
}
return monthNames;
}
// Returns the number of days in the given month...
getNumDaysInMonth(year, month) {
// February is the only month that can change, so if there's no year, assume it has the maximum (29) days...
return (year == 0 && month == 1) ? 29 : (new Date(year, month + 1, 0).getDate());
}
// Returns the <Picker.Item> values for the years...
renderYearPickerItems() {
// If year was 0, change it to current...
var currentYear = (new Date()).getFullYear();
var centerYear = this.startingYear;
if (centerYear === 0) { centerYear = currentYear; }
// Set starting and ending years...
var startYear = centerYear - this.props.yearsBack;
var endYear = currentYear;
var years = [];
for (var i = startYear; i <= endYear; i++) {
years.push(<Picker.Item label={i.toString()} value={i} key={i} />);
}
years.push(<Picker.Item label="----" value={0} key={0} />);
return years;
}
// Returns the <Picker.Item> values for the months...
renderMonthPickerItems() {
var months = this.getMonthNames();
return months.map(function(month, index) {
return <Picker.Item label={month} value={index} key={index} />;
});
}
// Returns the <Picker.Item> values for the days (based on current month/year)...
renderDayPickerItems() {
// February is the only day that can change, so if there's no year, assume it has the maximum (29) days...
var numDays = this.getNumDaysInMonth(this.state.year, this.state.month);
var days = [];
for (var i = 1; i <= numDays; i++) {
days.push(<Picker.Item label={i.toString()} value={i} key={i} />);
}
return days;
}
// Occurs when year value changes...
onYearChange = (value, index) => {
// Check if days are valid...
var maxDays = this.getNumDaysInMonth(value, this.state.month);
var day = (this.state.day > maxDays) ? maxDays : this.state.day;
this.setState({ year: value, day: day });
this.props.onYearValueChange(value, index);
}
// Occurs when month value changes...
onMonthChange = (value, index) => {
// Check if days are valid...
var maxDays = this.getNumDaysInMonth(this.state.year, value);
var day = (this.state.day > maxDays) ? maxDays : this.state.day;
this.setState({ month: value, day: day });
this.props.onMonthValueChange(value, index);
}
// Occurs when day value changes...
onDayChange = (value, index) => {
this.setState({ day: value });
this.props.onDayValueChange(value, index);
}
render() {
return (
<View style={styles.container}>
<Picker style={styles.monthPicker} selectedValue={this.state.month} onValueChange={this.onMonthChange}>
{this.renderMonthPickerItems()}
</Picker>
<Picker style={styles.dayPicker} selectedValue={this.state.day} onValueChange={this.onDayChange}>
{this.renderDayPickerItems()}
</Picker>
<Picker style={styles.yearPicker} selectedValue={this.state.year} onValueChange={this.onYearChange}>
{this.renderYearPickerItems()}
</Picker>
</View>
);
}
}
const styles = StyleSheet.create({
container: { flexDirection: "row", },
monthPicker: { flex: 3, },
dayPicker: { flex: 1, },
yearPicker: { flex: 2, },
});

Restrict date in jquery datetimepicker based on another datetimepicker

I have two text boxes with a datetimepicker hooked up to them. The text boxes are for start date and end date. The first datetimepicker is setup so that the user cannot choose a date before today, but can choose any date in the future.
How can I setup the second datetimepicker so that it cannot choose a date before the date chosen in the first date picker and whatever date is selected in first datetimepicker, the second datetimepicker date should be exactly 1 month from the first datetimepicker(User can then select the second datetimepicker to be 1 month or less than 1 month)?
Here's what I have so far:
Tried it via datetimepicker and onChangeDateTime function
<script src="~/Scripts/jquery.datetimepicker.js"></script>
<script>
$(document).ready(function () {
$('#ValidFrom').datetimepicker({
datepicker: true,
timepicker: false,
format: 'm/d/Y',
step: 30,
minDate: new Date(),
onChangeDateTime: function (dp, $input) {
var date = new Date($input.val());
$('#ValidTo').datetimepicker("option", "minDate", date);
//alert(date);
var date2 = new Date($input.val());
date2.setMonth(date.getMonth() + 1);
$('#ValidTo').datetimepicker("option", "maxDate", date2);
//alert(date2);
date2 = (date2.getMonth() + 1) + '/' + date2.getDate() + '/' + date2.getFullYear();
$('#ValidTo').val(date2);
}
});
$('#ValidTo').datetimepicker({
datepicker: true,
timepicker: false,
format: 'm/d/Y',
step: 30,
minDate: new Date()
});
});
</script>
If today is 1/16/2019 and I choose 1/28/2019 in the first datetimepicker, then the second date picker shouldn't be able to choose anything before 1/28/2019, second datetimepicker date should be 2/28/2019 or the user if wants, can select the date as less than 1 month.
You can use this function and use startdate id as date_timepicker_startend and enddate id as date_timepicker_end
<input type="text" class="form-control" id="date_timepicker_start">
<input type="text" class="form-control" id="date_timepicker_end">
These are the plugins you have to call
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.full.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.full.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.min.js"></script>
Date Logic with date and time validation
jQuery(function(){
var logic_start = function( currentDateTime ){
var d = new Date(currentDateTime); var date = d.getDate();
var month = d.getMonth(); var year = d.getYear();
var hours = d.getHours(); var minutes = d.getMinutes();
var dd = new Date($('#date_timepicker_end').val()); var end_date = dd.getDate();
var end_month = dd.getMonth(); var end_year = dd.getYear();
var end_hours = dd.getHours(); var end_minutes = dd.getMinutes();
var endtime= end_year+'/'+end_month+'/'+end_date;
var starttime= year+"/"+month+"/"+date;
if(starttime==endtime){
this.setOptions({
maxTime:end_hours+":00"
});
}else
this.setOptions({
maxTime:"23:00"
});
this.setOptions({
maxDate:jQuery('#date_timepicker_end').val()?jQuery('#date_timepicker_end').val():false
});
};
var logic_end = function( currentDateTime ){
var d = new Date(currentDateTime); var date = d.getDate();
var month = d.getMonth(); var year = d.getYear();
var hours = d.getHours(); var minutes = d.getMinutes();
var dd = new Date($('#date_timepicker_start').val()); var end_date = dd.getDate();
var end_month = dd.getMonth(); var end_year = dd.getYear();
var end_hours = dd.getHours(); var end_minutes = dd.getMinutes();
var starttime= end_year+'/'+end_month+'/'+end_date;
var endtime= year+"/"+month+"/"+date;
if(starttime==endtime){
this.setOptions({
minTime:end_hours+":00"
});
}else
this.setOptions({
minTime:"00:00"
});
this.setOptions({
minDate:jQuery('#date_timepicker_start').val()?jQuery('#date_timepicker_start').val():false
});
};
jQuery('#date_timepicker_start').datetimepicker({
format:'Y/m/d H:i:s',
onChangeDateTime:logic_start,
onShow:logic_start
});
jQuery('#date_timepicker_end').datetimepicker({
format:'Y/m/d H:i:s',
onChangeDateTime:logic_end,
onShow:logic_end
});
});
let DateInitial = $("#DateInitial");
let DateEnd = $("#DateEnd");
let dateNow = new Date();
/* click start clear end */
DateInitial.on("click", function(){
DateEnd.val(" ");
DateInitial.datetimepicker({
onShow:function( ct ){
this.setOptions({
format: 'd-m-Y H:i',
closeOnDateSelect : true,
validateOnBlur : true,
minDate: -0,
minTime: dateNow.getTime(),
onClose: function($input){
dateAllowPlusOne($input);
}
});
}
});
});
function dateAllowPlusOne(dateStart){
if(DateInitial.val()=="")
{
DateInitial.focus();
return false;
}
DateEnd.datetimepicker({
'format': 'd/m/Y H:i',
'minDate': -0,
startDate: dateStart,
'closeOnDateSelect' : true,
'validateOnBlur' : true,
'minDateTime': new Date()
});
DateEnd.attr("disabled", false);
}

How to change xAxisTickFormatting in ngx-charts-line-chart based on timeline selection?

By default, ticks are formatted based on time range selection in timeline. If it pans across days it shows month and if it is with in a day, it shows only time. This is great!
Now I want to localize these ticks. I could provide xAxisTickFormatting to get this done but I want to have the formatting based on the time range selection. "MMM DD" or "HH:MM" based on the current time range selection.
For this I need to change the formatting function dynamically on time range selection event. Is there such an event? Or is there any other way to achieve this?
In your chart, among the other attributes, you can declare
<ngx-charts-bar-horizontal-normalized
...
[xAxis]="true"
[xAxisTickFormatting]='formatPercent'
...
</ngx-charts-bar-horizontal-normalized>
formatPercent is a function declared in your .ts file (I'm using Angular) written like
formatPercent(val) {
if (val <= 100) {
return val + '%';
}
}
For any reference check the documentation here
Hope this helps.
It looks like, date is formatted based on the d3 logic. It uses the precision available to that tick. So if date is 12/15/2020 11:30:00, precision is at minute level. Similarly if date is 12/15/2020 00:00:00, precision is at day level.
Now we can choose the format options accordingly.
var locale = 'fr-FR'; // 'en-US'
function formatDate(value) {
let formatOptions;
if (value.getSeconds() !== 0) {
formatOptions = { second: '2-digit' };
} else if (value.getMinutes() !== 0) {
formatOptions = { hour: '2-digit', minute: '2-digit' };
} else if (value.getHours() !== 0) {
formatOptions = { hour: '2-digit' };
} else if (value.getDate() !== 1) {
formatOptions = value.getDay() === 0 ? { month: 'short', day: '2-digit' } : { weekday: 'short', day: '2-digit' };
} else if (value.getMonth() !== 0) {
formatOptions = { month: 'long' };
} else {
formatOptions = { year: 'numeric' };
}
return new Intl.DateTimeFormat(locale, formatOptions).format(value);
}
var dates = ['12/15/2020 11:30:30', '12/15/2020 11:30:00', '12/15/2020 11:00:00', '12/15/2020 00:00:00', '12/13/2020 00:00:00', '12/01/2020 00:00:00', '01/01/2020 00:00:00'];
for (date of dates) {
console.log(date, '=>', formatDate(new Date(date)));
}
Now this function can be used as
<ngx-charts-line-chart
[xAxis]="true"
[xAxisTickFormatting]="formatDate">
</ngx-charts-line-chart>