I would like to have two date field in my Wordpress contact form 7. A start-date and an end-date. The fields will be datepickers from the "Contact Form 7 Datepicker" plugin.
When visitor has selected a start-date he should only be able to select an end date that is 4 days later then the start-date.
How can I achieve this by only using the "contact form 7" form creator?
This is the syntax I put in the "contact form 7".
Start date charter*:
[date* date-start date-format:MM_d_yy]
End date charter*:
[date* date-end date-format:MM_d_yy]
And I added this code to the end of the functions file of the Wordpress theme.
function calendar_js(){
?>
<script>
jQuery(function($){
var start = $('.date-start input').first();
var end = $('.date-end input').first();
start.on('change', function() {
var start_date = $(this).datepicker('getDate');
start_date.setDate(start_date.getDate() + 3);
end.datepicker('option', 'minDate', start_date);
});
});
</script>
<?php
}
add_action('wp_footer', 'calendar_js');
Now the second date picker must be at least 4 days later then the first date picker.
May be this plugin will help you. This plugin works along with CF 7
http://wordpress.org/plugins/contact-form-7-datepicker/
And you can add your own javascript for date manipulation after adding datepicker in CF 7.
Example:
jQuery(document).ready(function($) {
$( ".from" ).datepicker({
onClose: function( selectedDate ) {
$( "#to" ).datepicker( "option", "minDate", selectedDate );
}
});
$( ".to" ).datepicker({
onClose: function( selectedDate ) {
$( "#from" ).datepicker( "option", "maxDate", selectedDate );
}
});
});
2021 Update: Contact form 7 datepicker was removed from wordpress repository due to security reasons
https://blog.cf7skins.com/contact-form-7-datepicker-removed-security-vulnerability/
You can try the WP-Datepicker by Fahad Mahmood
This is my solution without the use of plugins,
this is the code of the CF7 fields:
Start date charter *:
[date* date-start]
End date charter *:
[date* date-end]
this is the code added in the functions.php file:
add_action('wp_footer', 'calendar_js');
function calendar_js()
{
?>
<script>
jQuery(function($)
{
var start = $('.date-start input').first();
var end = $('.date-end input').first();
start.datepicker ({dateFormat: 'yy-mm-dd', beforeShow: function() { $(this).datepicker('option','maxDate',end.datepicker('getDate')); } });
end.datepicker ({dateFormat: 'yy-mm-dd', beforeShow: function() { $(this).datepicker('option','minDate',start.datepicker('getDate')); } });
});
</script>
<?php
}
There is no way to achieve it with the form builder directly, but with a bit of JavaScript you can validate the second input field to get your desired behaviour.
Here is an example, that falls back to the earliest date possible once a date is selected, that is out of scope.
<input type=date class=c-date-start>
<input type=date class=c-date-end>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Add the below code to the page your form is located -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>
<script>
jQuery(($) => {
const dateStart = $('.c-date-start')
const dateEnd = $('.c-date-end')
const minBuffer = 4
// Only allow dates in date end field that are after the date start field plus the minimum buffer
dateEnd.on('change', () => {
const startDate = dateStart.val()
const endDate = dateEnd.val()
if (startDate && endDate) {
const startDateMoment = moment(startDate)
const endDateMoment = moment(endDate)
const minDate = startDateMoment.clone().add(minBuffer, 'days')
if (endDateMoment.isBefore(minDate)) {
dateEnd.val(minDate.format('YYYY-MM-DD'))
}
}
})
})
</script>
On WordPress, you probably do not need to load jQuery extra and for the form markup you can add the classes in the CF7 builder like so:
[date date-427 class:c-date-start]
[date date-427 class:c-date-end]
Change the selectors and the minimum timespan according to your needs by adjusting the following declarations inside the source:
const dateStart = $('.c-date-start')
const dateEnd = $('.c-date-end')
const minBuffer = 4
Related
I'm trying to get the field data from form textarea so i can store it when a user filling the textarea if he reload page or open an other page in same tab and come back to write data his previous work will be there
My code is
session_start();
$_SESSION['textarea-133'] = $_POST["textarea-133"];
?>
<script>
var a="<php echo $_SESSION['textarea-133']";
document.getElementById("business_a6").value =a ;
</script>
You could use window.sessionStorage to save a variable and check if it's there each time the page is loaded.
window.onload = function(){
var userText = sessionStorage.getItem('the_user_text');
if( userText ){
document.getElementById('the-text-area').innerHTML = userText;
}
};
It's up to you if you want to re-save the variable with each keypress or maybe after a setInterval
document.addEventListener('keypress', (event) => {
var newText = document.getElementById('the-text-area');
sessionStorage.setItem('the_user_text', newText);
});
I'm hoping to find some help retrieving the Google Calendar attachment fileId through FullCalendar v2.9.0.
The Google calendar is dedicated to this project and is public as is the Drive folder containing image files which are the attachments - one image per event. I am new to the details of Javascript, but I've searched and researched quite a bit. I have not been able to find an example or tutorial that is close enough to what I'm trying to do that I can understand.
My project involves a month view FullCalendar where a user clicks an event, the event background highlights and a sidebar div populates with title, dateTime, description, location, and attachment image file. The user would browse through multiple events with the sidebar updating accordingly.
Here's what I've done so far:
The Google calendar elements are populating and updating correctly except for the image attachment.
I can hard code the HTML in gcal.html with a URL appended with the attachment fileId and get the image in the sidebar. The image, of course, is static though.
Using Google API Explorer calendar.events.get and entering calendarId, eventId, and simple API key, all of which are retrievable from FullCalendar, API Explorer returns the attachment fileId,
(Note that the fileUrl below works in a browser pulling up a viewer, but does not work in my HTML. This one does though: "https://drive.google.com/uc?export=view&id=0B5Nk_tOCzCISaWdqYy1DYnF6SzA")
From API Explorer
Execute without OAuth
calendar.events.get executed 16 minutes ago time to execute: 282 ms
Request
GET https://www.googleapis.com/calendar/v3/calendars/c6kag4dlhqs7m160s3t3lfggak%40group.calendar.google.com/events/u9a5fuoqkfmkm2c20vpn75krf4?fields=attachments(fileId%2CfileUrl)&key={YOUR_API_KEY}
Response
200
- Show headers -
{
"attachments": [
{
"fileUrl": "https://drive.google.com/file/d/0B5Nk_tOCzCISaWdqYy1DYnF6SzA/view?usp=drive_web",
"fileId": "0B5Nk_tOCzCISaWdqYy1DYnF6SzA"
}
]
}
I've tried what seems like endless combinations of statements, basically guessing, at the right syntax in a gcal.html eventClick function. I've also been trying to add code to events.push in gcal.js. This is the only place where I can find other event elements referenced.
My current setup with "alert(event.fileid);" under eventClick ingcal.html and "attachments: entry.fileid" under events.push in gcal.js returns an alert "undefined". In gcal.js a few lines down I notice "successArgs = [ events ].concat(Array.prototype.slice.call(arguments, 1)); // forward other jq args". I'm wondering if FullCalendar returns all fields for an event?
gcal.html (head)
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<link href='../fullcalendar.css' rel='stylesheet' />
<link href='../fullcalendar.print.css' rel='stylesheet' media='print' />
<script src='../lib/moment.min.js'></script>
<script src='../lib/jquery.min.js'></script>
<script src='../fullcalendar.min.js'></script>
<script src='../gcal.js'></script>
<script>
$(document).ready(function() {
$('#calendar').fullCalendar({
eventLimit: 4,
googleCalendarApiKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
events: {
googleCalendarId: 'c6kag4dlhqs7m160s3t3lfggak#group.calendar.google.com'
},
//$('#calendar'.fullCalendar( 'clientEvents' [, filter ] )
// Need to highlight next upcoming event on page load
// var filter = (events, event.start > getdate(new))
eventClick: function(event, events ) {
alert(event.fileid);
//eventRender: function(event, element, view) {
// Need to reset highlight on prevoiusly clicked event
// element.css('background-color', '#5777c8');
//}
//$('#calendar').fullCalendar( 'updateEvents' );
$( "#sidebar2" ).html(event.title);
$( "#sidebar3" ).html(event.start.format('dddd MMM. Do'));
$( "#sidebar4" ).html(event.start.format('h:mm a'));
$( "#sidebar5" ).html(event.description);
$( "#sidebar6" ).html(
'<a style= color:#a2cadc; href=http://' +
event.location + ' target="_blank">' +
"More Band Info" + '</a>'
);
$(this).css('background-color', '#5777c8');
return false;
console.log
},
loading: function(bool) {
$('#loading').toggle(bool);
}
});
});
</script>
gcal.js (line 122 to end)
return $.extend({}, sourceOptions, {
googleCalendarId: null, // prevents source-normalizing from happening again
url: url,
data: data,
startParam: false, // `false` omits this parameter. we already included it above
endParam: false, // same
timezoneParam: false, // same
success: function(data) {
var events = [];
var successArgs;
var successRes;
if (data.error) {
reportError('Google Calendar API: ' + data.error.message, data.error.errors);
}
else if (data.items) {
$.each(data.items, function(i, entry) {
var url = entry.htmlLink || null;
// make the URLs for each event show times in the correct timezone
if (timezoneArg && url !== null) {
url = injectQsComponent(url, 'ctz=' + timezoneArg);
}
events.push({
id: entry.id,
title: entry.summary,
start: entry.start.dateTime || entry.start.date,
// try timed. will fall back to all-day
end: entry.end.dateTime || entry.end.date, // same
url: url,
location: entry.location,
description: entry.description,
attachments: entry.fileid // tryiing to find the attachment reference
});
});
// call the success handler(s) and allow it to return a new events array
successArgs = [ events ].concat(Array.prototype.slice.call(arguments, 1));
// forward other jq args
successRes = applyAll(success, this, successArgs);
if ($.isArray(successRes)) {
return successRes;
}
}
return events;
}
});
}
// Injects a string like "arg=value" into the querystring of a URL
function injectQsComponent(url, component) {
// inject it after the querystring but before the fragment
return url.replace(/(\?.*?)?(#|$)/, function(whole, qs, hash) {
return (qs ? qs + '&' : '?') + component + hash;
});
}
});
Any help to get this working would be greatly appreciated.
I have created an event post type in Wordpress. For that I have put starting date and ending date from ACF datepicker.
I want admin can select Ending date greater than Starting Date.
Is there any way for restricting Starting Date and Ending Date?
For example, if Admin choose 1st Jan 2016 as starting date, then he can only select the ending date 1st Jan or greater then the selected date.
I think we can do it with java script and use this code to set the limit of the end date :
$( ".selector" ).datepicker({
minDate: new Date( )
});
I think there is no possibilities for date restriction in acf in admin area.
I may be done in acf's newer version.
You can request from here...
http://support.advancedcustomfields.com/forums/forum/feature-requests/
I had similar problem with regular date fields, Hope this JS code (with the moment JS library) with some adjustments will help you.
$(document).ready(function() {
$("input[name='Arrival']").change(function() {
var date_picked = $("input[name='Arrival']").val();
var SpecialTo = moment(date_picked, "YYYY-MM-DD");
var today = new Date();
today.setDate(today.getDate() - 240);
var selectedDate = new Date(date_picked);
if (today <= selectedDate) {
//alert('Date is today or in future');
} else {
alert('Date is in the past');
$("input[name='Arrival']").val('');
}
});
})
If you could post the source HTML of the date input with a value, I could change it probably to what you looking for.
This works just fine. Just get the name fields with inspect element. Add this code in the functions.php file.
add_action('acf/validate_save_post', 'my_acf_validate_save_post', 10, 0);
/**
* #throws Exception
*/
function my_acf_validate_save_post() {
$start = $_POST['acf']['field_61a7519a57d99'];
$end = $_POST['acf']['field_61a751d957d9a'];
// check custom $_POST data
if ($start > $end) {
acf_add_validation_error('acf[field_61a751d957d9a]', 'End date should be greater than or equal to start date.');
}
}
When you open inspect element the input field should look like this:
<div class="acf-date-picker acf-input-wrap" data-date_format="dd. MM yy" data-first_day="1">
<input type="hidden" id="acf-field_61a751d957d9a" name="acf[field_61a751d957d9a]" value="20211201">
<input type="text" class="input hasDatepicker" value="16. January 2022" id="dp1638477022818">
</div>
More information you can find here:
https://www.advancedcustomfields.com/resources/acf-validate_save_post/
I have FullCalendar installed and working great, pulling in courses from my database.
You can view different courses based on clicking a button that submits the page again but passes different criteria.
The Issue is that on reloading of the page and the new content it skips back to the current date which is rather annoying when when you are looking at courses 3 months into the future!!
Does anybody know how to make the calendar go back to the page you where on after you have refreshed the page???
I have a feeling it might be something to do with getdate as I got the following code to work but can't seem to pass the result back through the URL and into the calendar setup.
$('#my-button').click(function() {
var d = $('#calendar').fullCalendar('getDate');
alert("The current date of the calendar is " + d);
});
If you use jquery.cookie you can store the currently viewed date in a cookie for the page being viewed and use that value to set the defaultDate when the page reloads. Pass these in as options when you initialise your calendar:
defaultView: Cookies.get('fullCalendarCurrentView') || 'month',
defaultDate: Cookies.get('fullCalendarCurrentDate') || null,
viewRender: function(view) {
Cookies.set('fullCalendarCurrentView', view.name, {path: ''});
Cookies.set('fullCalendarCurrentDate', view.intervalStart.format(), {path: ''});
}
This code also saves the current view (e.g. month, day etc...)
I used a combination of the two above. I set the localStorage value for the start date when creating, moving, or resizing an event as well as viewRender and then assigned that value to the defaultDate.
defaultDate: localStorage.getItem('Default_FullCalendar_Date'),
viewRender: function(view) {
localStorage.setItem('Default_FullCalendar_View', view.name);
...
},
select: function(start, due){
localStorage.setItem('Default_FullCalendar_View', start);
...
},
eventDrop: function(event, delta, revertFunc, jsEvent, ui, view){
localStorage.setItem('Default_FullCalendar_View', event._start._d);
...
},
eventResize: function(event, delta, revertFunc, jsEvent, ui, view){
localStorage.setItem('Default_FullCalendar_View', event._start._d);
...
}
Works like a charm.
You can use gotoDate method:
var d = $('#calendar').fullCalendar('getDate');
$('#calencar').fullCalendar( 'gotoDate', d.getFullYear(), d.getMonth(), d.getDate() )
Here is an updated answer for version 4 and 5 of fullcalendar.
since viewRender is no longer an option in these versions. I came up with a different approach using the loading option.
The loading option will give you a boolean argument stating whether the calendar is done loading or not. Inside that function I check if the calendar is done loading and if so, I set the calendar date to localStorage. Next I created an if else statement before the fullcalendar object to check if the localstorage item exists, and if so I set the defaultDate option in the calendar object to to localStorage date; if not, I just set it to today's date.
Example:
let viewDate;
const savedDate = localStorage.getItem("calDate");
if (savedDate !== null) {
viewDate = new Date(savedDate);
} else {
viewDate = today();
}
const calendarElement = document.getElementById('your_calendar');
const calendar = new FullCalendar.Calendar(calendarElement, {
defaultDate: viewDate,
loading: function(stillLoading) {
if (stillLoading === false) {
// When Calendar is done loading....
localStorage.setItem("calDate", calendar.getDate());
}
},
});
I have 2 input boxes for inputing start date and end date.I need to verify that the start date is earlier than the end date.I have the following code to verify that but the code doesn't seem to be firing when I attach to the onselect event of the datepicker control.Can someone please tell what I'm doing wrong?
<script language="javascript" type="text/javascript">
$(document).ready(function() {
$(".date").datepicker({
onSelect:function(dateText,inst){
var startDate=new Date($("#_createDateFromInput").val());
var endDate=new Date($("#_createDateToInput").val());
if(startDate!=""&&endDate!="")
{
if(startDate>endDate)
{
alert("End date cannot be earlier than start date");
}
}
}
});});
</script>
thanks!!
The markup for the above is(this is in asp.net):
<label>Date From</label>
<input class="date" runat="server" id="_createDateFromInput" />
<label id="to">To</label>
<input class="date" runat="server" id="_createDateToInput" />
El Ronnoco had I believe has latched onto something...I notice when I remove the runat="server" tag I am able to fire the even...however now I am faced with another
issue to retrieve the value during post back(i.e when user finally submits)..any one have an idea?
A simpler way to achieve this is to prevent that the user can select an earlier date for the endDate.
This can be simply done by using the minDate option of Datepicker plugin
$("#startDate").datepicker({
onSelect:function(dateText,inst){
$( "#endDate" ).datepicker( "option", "minDate", new Date(dateText) );
}
});
I use this code, from the jQuery UI example page: http://jqueryui.com/demos/datepicker/#event-search
Basically it takes 2 inputs, makes them datepickers then onselect limits both the mindate and max date. It's a very clever piece of code.
$(function() {
var dates = $( "#from, #to" ).datepicker({
defaultDate: "+1w",
changeMonth: true,
numberOfMonths: 3,
onSelect: function( selectedDate ) {
var option = this.id == "from" ? "minDate" : "maxDate",
instance = $( this ).data( "datepicker" );
date = $.datepicker.parseDate(
instance.settings.dateFormat ||
$.datepicker._defaults.dateFormat,
selectedDate, instance.settings );
dates.not( this ).datepicker( "option", option, date );
}
});
});
thanks guys for all your input.I used a lot of what you had written down.I was able to make that work for some reason having the attribute runat="server" causes all kinds of problems for jquery.I had to remove the tag and access it using the request object that is inherent in the page.For those interested in the syntax:
request.form["startDate"].tostring();
where startdate is the attribute name value for that field.