Skip to content

Instantly share code, notes, and snippets.

@spivurno
Last active April 30, 2020 04:48
Show Gist options
  • Save spivurno/2df0d9789b38e771c398 to your computer and use it in GitHub Desktop.
Save spivurno/2df0d9789b38e771c398 to your computer and use it in GitHub Desktop.
Gravity Wiz // Gravity Forms // Date Range Display
<?php
/**
* Gravity Wiz // Gravity Forms // Date Range Display
*
* Display a group of color-coded date ranges on a calendar based on a GF selected date.
*
* @version 1.0
* @author David Smith <david@gravitywiz.com>
* @license GPL-2.0+
* @link http://gravitywiz.com/...
*/
class GW_Date_Range_Display {
protected static $is_script_output = false;
public function __construct( $args = array() ) {
// set our default arguments, parse against the provided arguments, and store for use throughout the class
$this->_args = wp_parse_args( $args, array(
'selected_date' => false, // '1987-01-13'
'target_id' => false, // '#date-range-display'
'form_id' => false, // 123
'source_field_id' => false, // 12,
'sequential' => false,
'start_from_last' => false,
'ranges' => array()
) );
// do version check in the init to make sure if GF is going to be loaded, it is already loaded
add_action( 'init', array( $this, 'init' ) );
}
function init() {
// make sure we're running the required minimum version of Gravity Forms
if( ! property_exists( 'GFCommon', 'version' ) || ! version_compare( GFCommon::$version, '1.8', '>=' ) ) {
return;
}
// time for hooks
add_action( 'gform_enqueue_scripts', array( $this, 'enqueue_form_scripts' ) );
add_filter( 'gform_pre_render', array( $this, 'load_form_script' ) );
add_filter( 'gform_register_init_scripts', array( $this, 'add_init_script' ) );
}
function enqueue_form_scripts( $form ) {
if( $this->is_applicable_form( $form ) ) {
wp_enqueue_script( 'gform_conditional_logic' );
}
}
function load_form_script( $form ) {
if( $this->is_applicable_form( $form ) && ! self::$is_script_output ) {
$this->output_script();
}
return $form;
}
function output_script() {
?>
<script type="text/javascript">
( function( $ ) {
window.GWDateRangeDisplay = function( args ) {
var self = this;
// copy all args to current object: (list expected props)
for( prop in args ) {
if( args.hasOwnProperty( prop ) )
self[prop] = args[prop];
}
self.init = function() {
self.$dateField = $( '#input_' + self.formId + '_' + self.sourceFieldId );
self.$calendarElem = $( self.targetId );
self.$calendarElem.datepicker( {
numberOfMonths: 1,
dayNamesMin: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
beforeShowDay: function( date ) {
var cssClass = '';
for( var i = 0; i < self.ranges.length; i++ ) {
if( ! self.isRangeActive( self.ranges[i] ) ) {
continue;
}
var baseDate = self.sequential && endDate ? endDate : self.getSelectedDate(),
startDate = self.addDaysToDate( new Date( baseDate ), self.ranges[i].start ),
endDate = self.addDaysToDate( new Date( baseDate ), self.ranges[i].end ),
inRange = date >= startDate && date <= endDate;
if( inRange && ! self.isWeekend( date ) ) {
cssClass = 'range' + ( i + 1 );
}
}
return [ true, cssClass, '' ];
}
} ).addClass( 'gw-date-range-display' );
self.$dateField.on( 'change', function() {
GWDateRangeDisplay.refresh();
} );
self.bindConditionalLogic();
GWDateRangeDisplay.refresh();
};
GWDateRangeDisplay.refresh = function( date ) {
if( typeof date == 'undefined' ) {
date = self.getSelectedDate();
}
self.$calendarElem.datepicker( 'setDate', date );
self.$calendarElem.datepicker( 'option', 'numberOfMonths', self.getMonthDisplayCount( date ) );
self.buildCalendarKey();
};
self.getSelectedDate = function() {
var dateValue = self.$dateField.val(),
selectedDate = dateValue ? new Date( dateValue ) : new Date(),
maxRange = self.getMaxRange( selectedDate ),
startingDate = selectedDate,
dayCount = 0;
if( self.startFromLast ) {
while( maxRange.end > maxRange.start ) {
if( ! self.isWeekend( maxRange.end ) ) {
dayCount++;
}
maxRange.end.setDate( maxRange.end.getDate() - 1 );
}
startingDate = self.subtractDaysFromDate( startingDate, dayCount );
} else {
if( self.isWeekend( startingDate ) ) {
startingDate = self.addDaysToDate( startingDate, 1 );
}
}
startingDate.setHours( 0, 0, 0, 0 );
return startingDate;
};
self.addDaysToDate = function( fromDate, days ) {
var count = 0;
while( count < days ) {
fromDate.setDate( fromDate.getDate() + 1 );
if ( ! self.isWeekend( fromDate ) ) {
count++;
}
}
return fromDate;
};
self.subtractDaysFromDate = function( fromDate, days ) {
while( days > 0 ) {
fromDate.setDate( fromDate.getDate() - 1 );
if ( ! self.isWeekend( fromDate ) ) {
days--;
}
}
return fromDate;
};
self.isWeekend = function( date ) {
return date.getDay() === 0 || date.getDay() === 6;
};
self.getMaxRange = function( selectedDate ) {
var earliestDate, latestDate, maxRange;
for( var i = 0; i < self.ranges.length; i++ ) {
if( ! self.isRangeActive( self.ranges[i] ) ) {
continue;
}
var baseDate = self.sequential && endDate ? endDate : selectedDate,
startDate = self.addDaysToDate( new Date( baseDate ), self.ranges[i].start ),
endDate = self.addDaysToDate( new Date( baseDate ), self.ranges[i].end );
if( ! earliestDate || earliestDate >= startDate ) {
earliestDate = startDate;
}
if( ! latestDate || latestDate <= endDate ) {
latestDate = endDate;
}
}
maxRange = {
start: earliestDate,
end: latestDate
};
return maxRange;
};
self.getMonthDisplayCount = function( selectedDate ) {
var maxRange = self.getMaxRange( selectedDate ),
startMonth = maxRange.start.getMonth(),
endMonth = maxRange.end.getMonth();
if( endMonth < startMonth ) {
endMonth += 11;
}
return ( endMonth - startMonth ) + 1;
};
self.buildCalendarKey = function() {
var markup = '',
styles = '';
for( var i = 0; i < self.ranges.length; i++ ) {
var properIndex = i + 1;
// always add style
styles += '.gw-date-range-display td.range' + properIndex + ', .gw-date-range-display .gwdrd-range-key.range' + properIndex + ':before { background-color: ' + self.ranges[i].color + ' !important; }';
// only add markup for active ranges
if( self.isRangeActive( self.ranges[i] ) ) {
markup += '<li class="gwdrd-range-key range' + properIndex + '">' + self.ranges[i].label + '</li>';
}
}
var $keyElem = $( '.gwdrd-range-keys' ),
$styleElem = $( '#gwdrd-styles' );
if( $keyElem.length <= 0 ) {
$keyElem = $( '<ul class="gwdrd-range-keys"></ul>' );
self.$calendarElem.prepend( $keyElem );
}
$keyElem.html( markup );
if( $styleElem.length <= 0 ) {
$styleElem = $( '<style type="text/css">' + styles + '</style>' );
$( 'head' ).append( $styleElem );
}
};
self.isRangeActive = function( range ) {
var hasConditionalLogic = typeof range.conditionalLogic != 'undefined';
return ( hasConditionalLogic && gf_get_field_action( self.formId, range.conditionalLogic ) == 'show' ) || ! hasConditionalLogic;
};
self.bindConditionalLogic = function() {
var boundFields = [];
for( var i = 0; i < self.ranges.length; i++ ) {
var range = self.ranges[i];
if( ! range['conditionalLogic'] ) {
continue;
}
for( var j = 0; j < range.conditionalLogic.rules.length; j++ ) {
var rule = range.conditionalLogic.rules[j];
if( $.inArray( rule.fieldId, boundFields ) == -1 ) {
$( 'li#field_' + self.formId + '_' + rule.fieldId ).find( 'input, select, textarea' ).change( function() {
GWDateRangeDisplay.refresh();
} );
boundFields.push( rule.fieldId );
}
}
}
};
self.init();
}
} )( jQuery );
</script>
<style type="text/css">
.gw-date-range-display .ui-datepicker {
width: 100% !important;
border: 0;
box-shadow: 0 0 0;
}
.gw-date-range-display .ui-datepicker-prev,
.gw-date-range-display .ui-datepicker-next {
display: none;
}
.gw-date-range-display .ui-datepicker-multi .ui-datepicker-group {
float: none;
margin: 0 0 1rem;
width: 100%;
}
.gw-date-range-display .ui-datepicker .ui-datepicker-header {
border: 0;
padding: 0;
background: transparent;
color: #000;
text-shadow: none;
filter: none;
}
.gw-date-range-display .ui-datepicker .ui-datepicker-title {
margin: 0;
text-align: left;
font-size: 12px;
text-shadow: none !important;
background: transparent;
filter: none;
}
.gw-date-range-display .ui-datepicker-multi .ui-datepicker-group table {
width: 100%;
margin: 0;
}
.gw-date-range-display .ui-datepicker thead {
background: transparent;
}
.gw-date-range-display .ui-datepicker th {
border: 1px solid #919191;
font-size: 10px;
text-transform: uppercase;
font-weight: normal;
border-bottom: 1px solid #000;
text-shadow: none;
color: #FFF;
background: rgba(0,0,0,.5);
filter: none !important;
}
.gw-date-range-display .ui-datepicker-calendar tbody td,
.gw-date-range-display .ui-state-disabled {
border: 1px solid #919191;
border-width: 0 1px 1px 0;
background: rgba(255,255,255,.35);
font-size: 12px;
height: 34px;
width: 14%;
padding-top:4px !important;
padding-bottom:4px !important;
text-align: center;
}
.gw-date-range-display .ui-datepicker-calendar tbody td:first-child {
border-left: 1px solid #919191;;
}
.gw-date-range-display .ui-state-default,
.gw-date-range-display .ui-widget-content .ui-state-default,
.gw-date-range-display .ui-widget-header .ui-state-default {
background: transparent;
border: 0;
text-align: center;
box-shadow: 0 0 0;
color: #000;
text-shadow: none;
cursor: default;
filter: none !important;
}
body .gform_wrapper form div.gform_body ul.gform_fields li.gfield.gfield_html ul li.gwdrd-range-key {
list-style: none !important;
line-height: 22px;
margin: 0 0 12px;
text-transform: uppercase;
font-size: 11px;
}
body .gform_wrapper form div.gform_body ul.gform_fields li.gfield.gfield_html ul li.gwdrd-range-key:before {
content: '';
display: block;
float: left;
width: 20px;
height: 20px;
border: 1px solid #000;
margin-right: 8px;
}
.ui-datepicker-title {
font-size:1.75em !important;
line-height: 1.35em;
color: #adcfdf;
padding-top:10px;
padding-left:3px;
padding-bottom:5px;
border: 0px !important;
}
.gwdrd-range-keys {
background:rgba(255,255,255,.15);
padding:15px 15px 10px 15px !important;
}
.gw-date-range-display .ui-datepicker .ui-datepicker-header {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
text-shadow: none;
filter: none;
}
</style>
<?php
self::$is_script_output = true;
}
function add_init_script( $form ) {
if( ! $this->is_applicable_form( $form ) ) {
return;
}
$args = array(
'formId' => $this->_args['form_id'],
'sourceFieldId' => $this->_args['source_field_id'],
'targetId' => $this->_args['target_id'],
'sequential' => $this->_args['sequential'],
'startFromLast' => $this->_args['start_from_last'],
'ranges' => $this->_args['ranges']
);
$script = 'new GWDateRangeDisplay( ' . json_encode( $args ) . ' );';
$slug = implode( '_', array( 'gw_date_range_display', $this->_args['form_id'], $this->_args['source_field_id'] ) );
GFFormDisplay::add_init_script( $this->_args['form_id'], $slug, GFFormDisplay::ON_PAGE_RENDER, $script );
}
function is_applicable_form( $form ) {
$form_id = isset( $form['id'] ) ? $form['id'] : $form;
return $form_id == $this->_args['form_id'];
}
}
# Configuration
new GW_Date_Range_Display( array(
'target_id' => '#gw-display-calendar',
'form_id' => 812,
'source_field_id' => 12,
'sequential' => true,
'start_from_last' => true,
'ranges' => array(
array(
'label' => 'Final Approvals Due',
'color' => '#ED1D24',
'start' => 0,
'end' => 0
),
array(
'label' => __( 'Translating' ),
'color' => '#b4f1fa',
'start' => 1,
'end' => 10,
'conditionalLogic' => array(
'actionType' => 'show',
'logicType' => 'all',
'rules' => array(
array(
'fieldId' => 14,
'operator' => 'is',
'value' => 'Yes'
)
)
)
),
array(
'start' => 1,
'end' => 5,
'color' => '#b2df97',
'label' => __( 'Printing' ),
'conditionalLogic' => array(
'actionType' => 'show',
'logicType' => 'all',
'rules' => array(
array(
'fieldId' => 13,
'operator' => 'is',
'value' => 'Yes'
)
)
)
),
array(
'start' => 1,
'end' => 5,
'color' => '#d1edbf',
'label' => __( 'Shipping' ),
'conditionalLogic' => array(
'actionType' => 'show',
'logicType' => 'all',
'rules' => array(
array(
'fieldId' => 13,
'operator' => 'is',
'value' => 'Yes'
)
)
)
),
array(
'start' => 1,
'end' => 1,
'color' => '#ffdf2e',
'label' => __( 'In-Hand Due Date' )
)
)
) );
# Configuration
new GW_Date_Range_Display( array(
'target_id' => '#gw-guess-calendar',
'form_id' => 5,
'source_field_id' => 1,
'sequential' => true,
'start_from_last' => true,
'ranges' => array(
array(
'label' => 'Final Approvals Due',
'color' => '#ED1D24',
'start' => 0,
'end' => 0
),
array(
'label' => __( 'Translating' ),
'color' => '#b4f1fa',
'start' => 1,
'end' => 10,
'conditionalLogic' => array(
'actionType' => 'show',
'logicType' => 'all',
'rules' => array(
array(
'fieldId' => 8,
'operator' => 'is',
'value' => 'Yes'
)
)
)
),
array(
'start' => 1,
'end' => 5,
'color' => '#b2df97',
'label' => __( 'Printing' ),
'conditionalLogic' => array(
'actionType' => 'show',
'logicType' => 'all',
'rules' => array(
array(
'fieldId' => 7,
'operator' => 'is',
'value' => 'Yes'
)
)
)
),
array(
'start' => 1,
'end' => 5,
'color' => '#d1edbf',
'label' => __( 'Shipping' ),
'conditionalLogic' => array(
'actionType' => 'show',
'logicType' => 'all',
'rules' => array(
array(
'fieldId' => 7,
'operator' => 'is',
'value' => 'Yes'
)
)
)
),
array(
'start' => 1,
'end' => 1,
'color' => '#ffdf2e',
'label' => __( 'In-Hand Due Date' )
)
)
) );
new GW_Date_Range_Display( array(
'target_id' => '#gw-guess-calendar',
'form_id' => 10,
'source_field_id' => 1,
'sequential' => true,
'start_from_last' => true,
'ranges' => array(
array(
'label' => 'Final Approvals Due',
'color' => '#ED1D24',
'start' => 0,
'end' => 0
),
array(
'label' => __( 'Translating' ),
'color' => '#b4f1fa',
'start' => 1,
'end' => 10,
'conditionalLogic' => array(
'actionType' => 'show',
'logicType' => 'all',
'rules' => array(
array(
'fieldId' => 8,
'operator' => 'is',
'value' => 'Yes'
)
)
)
),
array(
'start' => 1,
'end' => 5,
'color' => '#b2df97',
'label' => __( 'Printing' ),
'conditionalLogic' => array(
'actionType' => 'show',
'logicType' => 'all',
'rules' => array(
array(
'fieldId' => 7,
'operator' => 'is',
'value' => 'Yes'
)
)
)
),
array(
'start' => 1,
'end' => 5,
'color' => '#d1edbf',
'label' => __( 'Shipping' ),
'conditionalLogic' => array(
'actionType' => 'show',
'logicType' => 'all',
'rules' => array(
array(
'fieldId' => 7,
'operator' => 'is',
'value' => 'Yes'
)
)
)
),
array(
'start' => 1,
'end' => 1,
'color' => '#ffdf2e',
'label' => __( 'In-Hand Due Date' )
)
)
) );
@tareqhi
Copy link

tareqhi commented Apr 18, 2015

Lots of work done.... Huh? Awesome writing abilities

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment