UPDATE:
I have added additional code for clarification, which is annotated with * NEW *.
I was asked to clarify what this code is doing. A series of data is inputted into a collection called posts. On the postsList template the code is outputted when the timeToEnable field is less than the current time, which allows us to delay posts based on a specified date using this javascript time picker. The issue I have resides in /client/posts/post_edit.js where I am trying to set the value of one of the pickers from data in the collection which I don't know how to retrieve in javascript but I do in html simply using {{fieldHere}} and using the postsList template helper.
Hopefully this new code and info helps.
ORIGINAL QIUESTION.
I have a form that submits 5 fields in a posts collection. I have a edit page that, auto populates the tile, and content. However I have two separate Date/Time pickers. There is a function available to me to properly set the Date/Time pickers with the specific posts data when I am on the edit page. I cant output Date/Time data the usual way using {{date}} because it is stored in a particular format 2015-05-25T17:50:00.000Z I have created separate fields in the collection that separates day, month, year for do so using datepicker function.
This function will allow me to set the Date picker.
picker.set('select', new Date(year, month, date));
My Issue resides in getting the year, month and date data, based on the id that the post I am editing is using. I can place them in html using {{title}}, however I don't know how I would identify the id, and grab that post in the collection, and allow me to use picker.set like above.
Here is my code that I think will explain best what I have so far.
client
/client/posts/post_submit.js
Template.postSubmit.events({
'submit form' : function(e){
e.preventDefault();
var post = {
title: $(e.target).find('[name=title]').val(),
postContent: $(e.target).find('[name="postContent"]').val(),
timeToEnable: new Date(year, month, day, hours, minutes),
timeDisplay : timeDisplay,
year : year,
month : month,
day : day,
hours : hours
};
////console.log(post.timeToEnable);
Meteor.call('postInsert', post, function(error, result) {
// display the error to the user and abort
if (error){
return alert(error.reason);
}
// show this result but route anyway
if (result.postExists){
alert('This link has already been posted');
}
Router.go('postPage', {_id: result._id});
});
}
});
/client/posts/posts_list.html * NEW *
<template name="postsList">
<div class="posts page">
{{#each posts}}
{{> postItem}}
{{/each}}
</div>
</template>
/client/posts/post_item.html * NEW *
<template name="postItem">
{{> dashboard}}
<article>
<div class="post">
<div class="post-content">
<h1>{{title}}</h1>
<h3>{{timeDisplay}}</h3>
<p>{{{postContent}}}</p>
View
{{#if ownPost}}<a class="editPost" href="{{pathFor 'postEdit'}}">Edit</a>{{/if}}
</div>
</div>
</article>
</template>
/client/posts/posts_list.js * NEW *
Template.postsList.helpers({
posts: function() {
//return Posts.find({}, {sort: {submitted: -1}});
//
var data = new ReactiveDict();
data.set("now", new Date());
return Posts.find({timeToEnable: {$lt: data.get("now")}});
}
});
/client/posts/post_edit.html
<template name="postEdit">
{{> dashboard}}
<div class="container">
<form id="editForm">
<div class="postTitle">
<label class="titleLabel">Press Release Title.</label>
<div class="input">
<input name="title" id="title" type="text" value="{{title}}" placeholder=""/>
</div>
</div>
<div class="postTime">
<label class="titleLabel">Pick A time to post</label>
<div class="input">
<input class="timepicker" name="" id="" type="text" value="Click for a Time to Post" placeholder=""/>
</div>
</div>
<div class="postDay">
<label class="">Pick A Date to post</label>
<div class="input">
<input class="datepicker" name="" id="" type="text" value="Click for a Date to Post" placeholder=""/>
</div>
</div>
<div>
<div class="textarea">
<label class="contentLabel">Press Release content.</label>
<!-- <input name="postContent" id="postContent" type="text" value="" placeholder="Enwave has released a..."/> -->
<textarea name="postContent" id="postContent" type="text"></textarea>
</div>
</div>
<div id="submit">
<input type="submit" value="Submit"/>
</div>
<div class="deletePost">
<a class="btn btn-danger delete" href="#">Delete post</a>
</div>
</form>
</div>
</template>
This is where I want to retrieve the post fields for year, month, date. So I can set the picker to that date, all based off the specific post ID.
/client/posts/post_edit.js
This is the crucial part I need to output the fields from the collection here based on its specified id
Template.postEdit.rendered = function(){
picker.set('select', new Date(year, month, day));
}
lib
This Route outputs code to the html when using {{title}}.
/lib/router.js
Router.route('/posts/:_id/edit', {
name: 'postEdit',
data: function() { return Posts.findOne(this.params._id); }
});
lib/collections/posts.js * NEW *
Posts = new Mongo.Collection('posts');
Posts.allow({
update: function(userId, post) { return ownsDocument(userId, post); },
remove: function(userId, post) { return ownsDocument(userId, post); },
});
Posts.deny({
update: function(userId, post, fieldNames) {
// may only edit the following two fields:
return (_.without(fieldNames, 'title', 'postContent','timeToEnable','timeDisplay','year','month','day','hours').length > 0);
}
});
Meteor.methods({
postInsert: function(postAttributes) {
check(Meteor.userId(), String);
check(postAttributes, {
title: String,
postContent: String,
timeToEnable: Date,
timeDisplay:String,
year: Number,
month: Number,
day: Number,
hours: Number
});
var user = Meteor.user();
var post = _.extend(postAttributes, {
userId: user._id,
author: user.username,
submitted: new Date()
});
var postId = Posts.insert(post);
return {
_id: postId
};
}
});
server
~/server/publications.js`
Meteor.publish('posts', function() {
return Posts.find();
});
So I would like to grab the collection fields for posts into postEdit when the template is rendered, which will set the value of day input picker.
Thanks for help in advance.
This is what ended up working for me in the end.
client
/posts/post_edit.js
Template.post_edit.rendered = function(){
var year = (postObject.year);
var month = (postObject.month) -1;
var day = (postObject.day);
var hours = (postObject.hours);
var $input = $('.datepicker').pickadate();
var $inputTime = $('.timepicker').pickatime();
// Use the picker object directly.
var picker = $input.pickadate('picker');
var pickerTime = $inputTime.pickatime('picker');
picker.set('select', new Date(year, month, day));// Get on screen image
pickerTime.set('select', [hours,0]);// Get on screen image
}
lib
/lib/router.js
Router.route('/posts/:_id/edit', {
name: 'postEdit',
data: function() {
postObject = Posts.findOne(this.params._id);
return postObject;
}
});
Related
In my VueJS application I have a component with a form.
In that form I have a field to pick the date.
My requirement is to show an error message if the selected date is older than the current date.
Basically the selected date need to be either today's date or future date.
I'm using Moment JS.
I have following custom rule in my Validator.vue
const dateIsToday = (value) => {
var todayDate = moment(new Date()).format("DD-MM-YYYY");
var selectedDate = value;
return selectedDate>=todayDate;
};
But this works only if I selected an old date from the current month... Assume if the user has picked an older date from this month like 10-04-2022, then it'll show the error message.
But if the user selected an old date from last month or a past month like 10-01-2022, this won't show me the error message....
In my form.vue I have
<div class="w-1/2 mr-2">
<p class="text-certstyle-titles font-bold text-sm mb-1">Start date</p>
<div class="h-12">
<cs-date-picker
id="startDate"
v-model="project.start_date"
:default-selection="true"
:name="`${identifier}-start_at`">
</cs-date-picker>
<validator
:identifier="`${identifier}-validate-project`"
:rules="validations.startDate"
:name="`${identifier}-start_at`"
/>
</div>
</div>
And under my validations I have,
startDate: {
required: {
message: 'Project Start date is required.'
},
dateIsToday: {
message: 'Date has to be today's date or a future date.'
},
},
It seems that you are comparing strings. Instead you should make real use of moment and compare moment dates:
const dateIsToday = (value) => {
let todayDate = moment();
let selectedDate = moment(value, "DD-MM-YYYY");
return selectedDate.isSameOrAfter(todayDate);
};
I have a problem with the comparison of my go dates with the return date. Since this morning I have tried several things but nothing works. I would like to display an error message if the person selects the same date as the return. But this doesn't work. Who can tell me what's wrong with my code? thanks in advance :)
<template>
<div >
<datepicker v-model="dateSelectAller" lang="fr" type="date" format="dd-MM-YYYY" :lowerLimit="Date.now()" ></datepicker>
</div>
<div v-show="!isSuccess">
<span class="error-text" v-if="errors.timeAllerErrors">{{ errors.timeAllerErrors }}</span>
</div>
<div >
<datepicker v-model="dateAnterieurRetour" lang="fr" type="date" format="dd-MM-YYYY" :lowerLimit="Date.now()"></datepicker>
</div>
<div v-show="!isSuccess">
<span class="error-text" v-if="errors.dateRetour">{{ errors.dateRetour }}</span>
</div>
</template>
<script>
data(){
return{
format,
dateSelectAller:new Date(),
dateAnterieurRetour: new Date(),
isSuccess:false,
errors:{}
}
}
beforeMount(){
this.dateAnterieurRetour = this.dateAnterieurRetour.setDate(this.dateAnterieurRetour.getDate() +1)
},
watch:{
dateSelectAller(newValue){
if(newValue >= this.dateAnterieurRetour){
this.errors['dateAller'] = 'Choisir une date inférieur à celle de retour'
}else{
this.errors['dateAller'] = ''
}
console.log(newValue)
if(this.date1 === this.date2){
return this.errors['timeRetourErrors'] = 'test erreur'
}else{
return this.errors['timeRetourErrors'] = ''
}
},
dateAnterieurRetour(newValue){
console.log(newValue)
if(newValue <= this.dateSelectAller){
this.errors['dateRetour'] = 'la date choisi n\' est pas valide!'
}else{
this.errors['dateRetour'] = ''
}
console.log(newValue)
},
},
methods:{
getFormat () {
return this.format(new Date(this.dateSelectAller) , 'dd-MM-yyyy', {locale: window.locale})
} ,
getFormatRetour () {
return this.format(new Date(this.dateAnterieurRetour) , 'dd-MM-yyyy', {locale: window.locale})
} ,
}
</script>
Where are you setting isSuccess? Right now it looks like the error divs will never appear since isSuccess isn't in your data or computed values
Thank you all for trying to help me. I have just found a solution, that when the outgoing date and the same as the return date, the return date will advance by one day more. The problem came from the date format since when I retrieved my date it arrived in this format: 12251511511 and the outgoing date: 12/04/2021 that's why. I therefore change the format of the return date so that it can be compared to the outgoing date. :)
When I click the Create new Ticket #1,
I'm able to automatically display the current year/month/day as show here: But I need the time aswell.
Here is how I've implemeted it:
My Java Pojo:
public class Ticket implements Serializable {
#Column(name = "jhi_date")
private LocalDate date;
//getters and setters
}
My ticket-popup.service.ts
setTimeout(() => {
// populate date with current date if new
const tickets = new Ticket();
const now = new Date();
tickets.date = {
year: now.getFullYear(), // works fine
month: now.getMonth() + 1, // works fine
day: now.getDate(), // works fine
time: now.getTime(), // doesnt return anything as shown in image
hour: now.getHours() // doesnt return anything as in image
};
this.ngbModalRef = this.ticketModalRef(component, tickets);
resolve(this.ngbModalRef);
}, 0);
It's most probably caused by the ngbDatepicker component. What could be it's equivalent to replace ?
<div class="form-group">
<label class="form-control-label" for="field_date">Date</label>
<div class="input-group">
<input id="field_date" type="text" class="form-control" name="date" ngbDatepicker #dateDp="ngbDatepicker" [(ngModel)]="ticket.date"
/>
<span class="input-group-append">
<button type="button" class="btn btn-secondary" (click)="dateDp.toggle()"><i class="fa fa-calendar"></i></button>
</span>
</div>
</div>
Github sample here
Here is how I managed to get the time:
public class Ticket implements Serializable {
//#Column(name = "jhi_date")
//private LocalDate date;
#Column(name = "jhi_timestamp")
private ZonedDateTime timestamp; // used ZonedDateTime instead of LocalDate
//getters and setters
}
Used Angular Date Pipe in My ticket-popup.service.ts
setTimeout(() => {
// populate date/time with current time if new
const ticket = new Ticket();
ticket.timestamp = this.datePipe // used Pipe date format
.transform(new Date(), 'yyyy-MM-ddThh:mm');
this.ngbModalRef = this.ticketModalRef(component, ticket);
resolve(this.ngbModalRef);
}, 0);
Got rid of ngbDatepicker from
ticket-dialog.component.html
<div class="form-group">
<label class="form-control-label" for="field_timestamp">Timestamp</label>
<div class="d-flex">
<input id="field_timestamp" type="datetime-local" class="form-control" name="timestamp" [(ngModel)]="ticket.timestamp"
/>
</div>
</div>
result:
When the user clicks the button I want it to copy the vm.checkin (unix date) to the angular type=date field.
<input type="date" ng-model="vm.receiptForm.paidDate" id="receiptPaidDate">
<button ng-click="vm.receiptForm.paidDate = (vm.checkin * 1000) | date:'yyyy-MM-dd HH:mm:ss Z'">
<span class="size-tiny">Copy Date</span>
</button>
Is that possible to do? I cant seem to make it work.
The model for input[type=date] must always be a Date object, but date filter formats date to a string based on the provided format. You just need to convert your timestamp to a date as described here and then assign it to vm.receiptForm.paidDate.
UPDATE: as an option you can create your custom filter to achieve the desired functionality, see the code snippet below:
var module = angular.module("demo", []);
module.filter('tsToDate', function () {
return function (timestamp) {
return new Date(timestamp);
};
});
module.controller('Demo', [function Demo() {
var vm = this;
vm.checkin = 1529442000000;
vm.receiptForm = {
paidDate: ''
};
}]);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="demo" ng-controller="Demo as vm">
<div>
<button ng-click="vm.receiptForm.paidDate = (vm.checkin | tsToDate)">Copy Date</button>
</div>
<input type="date" ng-model="vm.receiptForm.paidDate" />
<code>
{{ vm.receiptForm }}
</code>
</div>
I have an issue where the date fields being submitted are returning date with timestamp, rather than just the date with the timestamp set to 00:00:00. This code works for other instances where I am trying to achieve this process, but for some reason it is not working and I'm curious if the conversion has to happen within my form in my view or should happen on the back-end within my routes.
Route:
.post(function(req, res){
models.Creator.findAll({
order: 'createDate DESC',
where: {
dataDateStart: {
$gte: moment(req.body.startDate).utc().format("YYYY-MM-DD")
},
dataDateEnd: {
$lte: moment(req.body.endDate).utc().format("YYYY-MM-DD")
}
},
include: [{
model: models.User,
where: {
organizationId: req.user.organizationId,
},
attributes: ['organizationId', 'userId']
}],
limit: 10
}).then(function() {
res.redirect('/app');
}).catch(function(error){
res.send(error);
})
});
Outputted where clause:
WHERE `creator`.`data_date_start` >= '2016-06-07 04:00:00' AND `creator`.`data_date_end` <= '2016-06-11 04:00:00' ORDER BY createDate DESC LIMIT 10;
As you can see the issue is that 04:00:00 appears instead of 00:00:00
View:
<div class="row">
<div class="creator-search-form col-md-6 col-md-offset-3">
<h1 id="search-header">Filter Feed</h1>
<form action="/app" method="post" class="creator-filter-fields">
<p>Date Range:</p>
<input type="date" name="startDate">
<input type="date" name="endDate">
<button type="submit" id="creator-filter-submit">Submit</button>
</form>
</div>
</div>
I expect that what is going on in your situation is that somewhere downstream from Moment, your date without a time is being interpreted as local time, and then converted to UTC. I would guess that your server is set to UTC-4 (US Eastern Daylight?), and that is why you are seeing what you do.
When you change from using .format('YYYY-MM-DD') to just .format(), your resultant string includes all time parts and an offset, and look like this:
moment.utc('2016-01-01').format()
"2016-01-01T00:00:00Z"
Because the above date is completely unambiguous, your whatever is changing the time in your stack doesn't make any odd decisions about how to interpret it, and everything works fine.
Provided that the queried value from date elements are strings in the format YYYY-MM-DD, then you can get the result by
moment.utc(value).format("YYYY-MM-DD")
where the value is the date string.
I hope this helps.