Ihave datepicker using Vue2-Datepicker this is my component looks like
<date-picker
v-model="closingRange"
range
valueType="format"
:default-value="new Date()"
:disabled-date="disabledBefore"
></date-picker>
and called Methods disbaledBefore
disabledBefore(date) {
let dayBefore = this.$moment(this.firstDateIfNull).format(
"YYYY-MM-DD"
);
const beforeToday = new Date(dayBefore);
beforeToday.setHours(0, 0, 0, 0);
return date < beforeToday; // Assume < 25 May Not Selected
}
how to auto select 26 May on start date of data range and cannot change. so user just can change end date.
just like this:
<date-picker
v-model="closingRange"
range
valueType="format"
:default-value="new Date()"
:disabled-date="disabledBefore"
:min-date="minDate"
></date-picker>
<script>
import { formatDate } from "#/utils/date";
export default {
name: "index",
props: {
label: String,
value: [String, Object, Date, Number],
minDate: {
type: [String, Date, Number],
default: () => {
return new Date(1970, 1, 1);
},
},
},
data() {
return {};
},
methods: {},
};
</script>
Related
I would like to prevent a new slot being created when already occupied. For example, if the dates selected overlap e.g. Slot one has 10am to 11am and potential added slot is 10:15 to 11:15, I want to block this as some of the time is already taken.
Currently, I am trying to use the dateEvent option in Vue but it still creates the slot. I wanted to get the current slot data but can't find a way of doing this and eventOverlap and slotEventOverlap seem to do nothing in this context.
Has anyone run into this problem before?
Code Example:
export default {
components: {
FullCalendar
},
mounted() {
console.log('Component mounted.')
},
data() {
return {
allEvents: [],
calendarOptions: {
plugins: [timeGridPlugin, dayGridPlugin, interactionPlugin],
initialView: 'timeGridDay',
selectable: true,
selectMirror: true,
allDaySlot: false,
slotDuration: "00:15:00",
slotMinTime: '09:00:00',
slotMaxTime: '19:00:00',
editable: false,
eventLimit: true,
eventOverlap: false,
slotEventOverlap: false,
dateClick: this.handleDateClick,
events: function (fetchInfo, successCallback, failureCallback) {
//...
},
}
}
},
methods: {
handleDateClick: function (arg) {
console.log(arg, arg.view.getCurrentData())
let startDateTime = new Date(arg.dateStr)
let endDateTime = new Date(arg.dateStr)
const calendar = this.$refs.fullCalendar.getApi()
var event = calendar.getEventById('my-event')
if (event) {
event.remove()
}
calendar.addEvent({
id: 'my-event',
title: 'Selected Slot',
start: startDateTime,
end: new Date(endDateTime.setHours(endDateTime.getHours() + 1))
})
calendar.unselect()
}
},
}
im newbie here. I want control the datepicker to be disabled automatically based on the existing api. I using the vuejs-datepicker library. I've seen the documentation and managed to implement it statically, but having problems when implementing it reactively.
This is my previous view:
<datepicker
:disabled-dates="state.disabledDates">
</datepicker>
And, my previous static value of datepicker, especially for the day:
data() {
var year = (new Date()).getFullYear()
var month = (new Date()).getMonth()
var dDate = (new Date()).getDate()
var state = {
disabledDates: {
to: new Date(year, month, dDate), // Disable all dates up to specific date
// from: new Date(2020, 0, 26), // Disable all dates after specific date
days: [0,1], // Disable Saturday's and Sunday's
}
}
return {
state: state,
day: '',
}
},
For now, here my view:
<datepicker
:disabled-dates="disabledDates">
</datepicker>
Console output:
My script:
<script>
data() {
return {
day: '',
year : (new Date()).getFullYear(),
month : (new Date()).getMonth(),
dDate : (new Date()).getDate(),
}
},
computed:{
// reactive
disabledDates: {
to: new Date(year, month, dDate), // Disable all dates up to specific date, 2020,8,8
days: [day], // Disable day, 0,1
}
},
watch: {
'day': function(day){
console.log('day: '+day)
return this.day
},
},
</script>
Thank you.
I'm pretty sure your only problem is that your syntax for computed properties is wrong. They should be functions, since they need to be run. Their dependencies are automatically determined by Vue, and when those change, the function is re-run. So, try this:
data: function() {
return {
day: '',
year: (new Date()).getFullYear(),
month: (new Date()).getMonth(),
dDate: (new Date()).getDate()
};
},
computed: {
// Here. This should be a function.
disabledDates: function() {
return {
// Make sure to use 'this.' when in a component
to: new Date(this.year, this.month, this.dDate),
days: [ this.day ]
};
}
},
watch: {
day: function(day) {
console.log(`Day: ${day}`);
return value;
}
}
I am using https://www.npmjs.com/package/vue-multi-date-picker in my vuejs code
I want to know when I edit the form How to show selected dates in datepicker text.
for example I am using
<m-date-picker
v-model="date"
:lang="lang"
:multi="multi"
:always-display="false"
:format="formatDate"
data-parsley-required="true"
:class="{
'is-invalid':
submitted &&
$v.date.$error
}"
>
</m-date-picker>
export default {
name: "newspaper-result",
components: {
editor: Editor // <- Important part
},
data() {
return {
multi: true,
lang: "en",
date: [],
notClassified: true,
submitted: false
};
},
methods: {
formatDate(date) {
return date.toLocaleDateString();
},
}
Now when I insert the date in
this.date = date come from db gives error that date.toLocaleDateString(); is not a function
You are calling toLocaleDateString() function on a string, but strings don't have such function, this is why you are getting the error.
This function needs a properly constructed date object, not a string, so convert it using new Date():
formatDate(date) {
return new Date(date).toLocaleDateString()
}
I need to check whether my input field is empty or not.
Logic
if form.name has value, use increase function
if form.name is empty, use decrease function
do not use increase, decrease functions on each character that user inputs or removes
Code
<el-form-item label="Product name *">
<el-input v-model="form.name"></el-input>
</el-form-item>
methods: {
increase() {
this.percentage += 8.3;
if (this.percentage > 100) {
this.percentage = 100;
}
},
decrease() {
this.percentage -= 8.3;
if (this.percentage < 0) {
this.percentage = 0;
}
},
}
any idea?
Update
Script
data() {
return {
form: {
name: '', // require
slug: '',
price: '', // require
supplier_id: '', // require
new_price: '',
base_price: '',
sku: '',
qty: 1, // require
active: '', // require
photo: '',
photos: [],
shortDesc: '',
longDesc: '',
origin: '',
tags: [],
brand_id: '', // require
categories: [],
user_id: '',
seoTitle: '',
seoTags: '',
seoPhoto: '',
seoDescription: '',
variations: [],
options: [],
condition: '', // require
isbn: '',
ean: '',
upc: '',
height: '',
weight: '',
lenght: '',
width: '', // require
},
}
},
methods: {
onSubmit(e) {
e.preventDefault();
axios.post('/api/admin/products/store', this.form)
.then(res => {
// do my things
})
.catch(function (error) {
console.log('error', error);
});
},
}
HTML
<el-form ref="form" :model="form" label-width="120px" enctype="multipart/form-data">
// my inputs (listed in form part in script above)
<el-button type="primary" #click="onSubmit" native-type="submit">Create</el-button>
</el-form>
One possible solution would be to use #focus and #blur events to check if form.name has a value before increasing or decreasing, this would be fired on focus or on blur events, so you will not have the methods fired on each character input or deletion.
for example:
<el-form-item label="Product name *">
<el-input #focus="checkName" #blur="checkName" v-model="form.name"></el-input>
</el-form-item>
methods: {
checkName() {
//If form.name has a value then run increase method, otherwise run decrease method
!!this.form.name ? this.increase() : this.decrease()
},
increase() {
this.percentage += 8.3;
if (this.percentage > 100) {
this.percentage = 100;
}
},
decrease() {
this.percentage -= 8.3;
if (this.percentage < 0) {
this.percentage = 0;
}
},
}
You can see a working fiddle HERE
UPDATE
Alright so i did follow the rules you state on your question, and i didn't know you wanted to get the percentage of completion of the form, so in order to do that, i would suggest to use a computed property, you can read more about computed properties in the VueJS Documentation, this way the percentage is calculated based on the criteria we can give it, and only if the form has values.
computed: {
formProgress: function () {
let totalInputs = Object.keys(this.form).length;
let filledInputs = 0;
Object.values(this.form).forEach(val => {
if (!!val){
filledInputs++;
}
});
return (filledInputs/totalInputs)*100
}
},
As you can see in one single computed property you can handle the complex logic and return the value reactively, to explain it better, i'm counting the lenght of the form object, to get total number of inputs in your form, so it's important to have all your form data inside the form data object, then i convert that object to an array to iterate it, and i check if each property has a value on it, if does it, i add 1 to the filledInputs counter, and finally just return a simple math to get the percentage. please check the new Fiddle here to see it in action:
FORM PROGRESS FIDDLE
If you have any other doubt just let me know.
UPDATE 2:
All right in order to only count for specific inputs for the form progress, i have modified the code to work based on an array that contains the names of the properties that are required. here is the full code:
data() {
return {
form: {
name: '',
lastName: null,
categories: [{}],
},
requiredFields: ['name', 'categories']
};
},
computed: {
formProgress: function () {
let totalInputs = this.requiredFields.length;
let filledInputs = 0;
Object.entries(this.form).forEach(entry => {
const [key, val] = entry;
if (this.requiredFields.includes(key)){
switch (val.constructor.name) {
case "Array":
if (val.length !== 0){
if (Object.keys(val[0]).length !== 0){
filledInputs++;
}
}
break
case "Object":
if (Object.keys(val).length !== 0){
filledInputs++;
}
break
default:
if (!!val){
filledInputs++;
}
}
}
});
return Number((filledInputs/totalInputs)*100).toFixed(1)
}
},
And here is the updated FIDDLE
As you can see now i'm using Object.entries to get the key and value of the form object, so you can have a single form object to send to your backend, this way i'm checking first if the key is in the required fields, and if has a value, so all you need to do is update the requiredFields data array with the same names as your inputs data property to make the validation work, also there is a validation depending if is array, array of objects, or object, that way it will validate input on each data type.
Hope this works for you.
While using Vue Rangedate Picker I hit a roadblock trying to configure the prop Initial Range (the initial range that the component spits before the user even select any other range).
Have managed to setup other props like "caption" and "preset ranges" but the initRange is complaining about it not being an Object and being a function.
On my template:
<date-picker v-bind="datePicker" initRange="datePicker.presetRanges.last7Days" #selected="onDateSelected" i18n="EN" ></date-picker>
On my data:
datePicker: {
initRange: {
start: '1505862000000',
end: '1505872000000'
},
captions: {
title: 'Choose Date/Period',
ok_button: 'Apply'
},
presetRanges: {
today: function () {
const n = new Date()
const startToday = new Date(n.getFullYear(), n.getMonth(), n.getDate() + 1, 0, 0)
const endToday = new Date(n.getFullYear(), n.getMonth(), n.getDate() + 1, 23, 59)
return {
label: 'Today',
active: false,
dateRange: {
start: startToday,
end: endToday
}
}
},
last7Days: function () {
const n = new Date()
const weekAgo = new Date(n.getFullYear(), n.getMonth(), n.getDate() - 7, 24, 0)
const endToday = new Date(n.getFullYear(), n.getMonth(), n.getDate() + 1, 0, 0)
return {
label: 'Last 7 Days',
active: 'false',
dateRange: {start: weekAgo, end: endToday}
}
},
On my methods:
methods: {
onDateSelected: function (daterange) {
let that = this;
that.selectedDate = daterange;
let UnixStart = Math.round((Date.parse(that.selectedDate.start)));
let UnixEnd = Math.round((Date.parse(that.selectedDate.end)));
},
How can I solve this?
https://github.com/bliblidotcom/vue-rangedate-picker/issues/71
I leave the comments with this link. you will find it. should work for you.