Jump to content

2 date fields, how to ensure the second date is higher?


Recommended Posts

Posted

Hi,

I'm not sure if we have something built in or common known, maybe I have a blockade. ?

I have two date fields and need to ensure that the second date is higher than the first. 

Is this possible while a user fills out a page?

Or is it only possible after a page save via hooking?

Posted

via page save hook would be the only reliable way.

via some javascript would be the more user-friendly way.

$(document).on('change', '#Inputfield_yourdatefield', function(e) {
  var yourdate = $(e.target).val();
  var yourotherdate = ...;
  if(yourdate < yourotherdate) {
    alert('yourdate must be higher than ...');
    // reset field
    $(e.target).val('');
  }
});

doing both would be the best ;)

don't think there's a built in way...

  • Like 5
Posted
1 hour ago, bernhard said:

via some javascript would be the more user-friendly way.

Maybe a silly question, but how do you get this to run in the admin? Where do you put the code?

Posted

Several options. Admin custom files module. AdminOnSteroids has this option too I think. And finally my favourite way: via hook (several possibilities here again) :)

  • Like 2
Posted

@SamC it's really as simple as that: https://processwire.com/blog/posts/new-ajax-driven-inputs-conditional-hooks-template-family-settings-and-more/#new-conditional-hooks

Update 2022: 

 

$wire->addHookAfter('Pages::saved', function(HookEvent $event) {
  $page = $event->arguments('page');
  bd('page saved');
  bd($event, 'event');
  bd($event->object, 'event->object');
  bd($event->arguments(), 'event->arguments');
});

in the beginning it can be a little confusing when to use event->object, event->arguments and event->return but with the help of tracy you can quickly bring light into the dark: add the code above to the tracy console, set the radio on the right to load it on "ready" (same as placing the code in the site/ready.php file) and save any page:

5a3805ee6bf35_2017-12-1819_14_44-EditPage_test0datatables_to.png.6ecfb6a6ba3e1162479f4c4481044d7a.png

$event->arguments('page') is the same as using $event->arguments(0) that you will see very often and in the tracy dump you see that 0 is simply the key for the first argument in that hookevent. you can also collapse the "data" property of the hookevent and you would see the same:

5a380699e033d_2017-12-1819_18_37-EditPage_test0datatables_to.png.6a30a5f111604b3edb9cbd4f7c0c166a.png

You can also use your IDE to quickly find what the HookEvent is returning/containing in which hook. Let's take the common saveReady hook as an example:

  1. We know that the hook is attached as Pages::saveReady (eg because we have read that somewhere)
  2. That means that the hook is part of the "Pages" class, which is located at "/wire/core/Pages.php" - that's easy to find out using CTRL+P in VSCode:
    dPHVlOE.png
  3. Searching for "___saveReady" lets us find the corresponding method:
    lJSv4kn.png
  4. Now we see, that we have ONE "arguments", being Page $page - this means $event->arguments(0) would return the page being ready for saving
  5. $event->object would be the class, here "Pages"
  6. $event->return is the return value of that method, here $data (line 1739)

Edit: There's some additional explanations in this post: https://processwire.com/talk/topic/27248-pagestrashtemplatefoo-vs-pagestemplatefootrash/?do=findComment&comment=224659

#search afraid of hooks

  • Like 16
  • Thanks 3
Posted

So I could hook a page with an image field and use it to create a page with that image on it? Like creating a centralized media library as you add images to various pages. Maybe not the best example, but this would be a candidate for hooks?

Posted
13 hours ago, SamC said:

So I could hook a page with an image field and use it to create a page with that image on it? Like creating a centralized media library as you add images to various pages. Maybe not the best example, but this would be a candidate for hooks?

yes, you can do anything you want...

https://processwire.com/api/hooks/

https://processwire.com/api/hooks/captain-hook/

send an email when a field changed, modify the description of an inputfield, inject custom javascript into your page... anything.

  • Thanks 1
Posted

To point it down: For everything you want to do, but can't do with built in functionality, you need to find the appropriate hook and then use it! :)

  • Like 3
Posted
On 12/18/2017 at 10:27 AM, horst said:

I have two date fields and need to ensure that the second date is higher than the first. 

I've done quite a number of forms with this type of setup, not sure if any of this js would help but just in case... (using custom timepicker init and callbacks)

Spoiler

$(document).ready(function() {
    $('#Inputfield_start_time').timepicker({
    	hours: { starts: 9, ends: 20 },
        showPeriod: true,
        defaultTime: '16:00', 
        //onHourShow: earliestHour,
        //onMinuteShow: earliestMinute
        onHourShow: tpStartOnHourShowCallback,
		onMinuteShow: tpStartOnMinuteShowCallback
    });

    $('#Inputfield_end_time').timepicker({
        showPeriod: true,
        hours: { starts: 9, ends: 21 },
        defaultTime: '22:00', 
        // onHourShow: latestHour,
        // onMinuteShow: latestMinute,
        onHourShow: tpEndOnHourShowCallback,
		onMinuteShow: tpEndOnMinuteShowCallback
    });

});


function tpStartOnHourShowCallback(hour) {
    var tpEndHour = $('#Inputfield_end_time').timepicker('getHour');
    // all valid if no end time selected
    if ($('#timepicker_end').val() == '') { return true; }
    // Check if proposed hour is prior or equal to selected end time hour
    //if (hour <= tpEndHour) { return true; }
    if ( (tpEndHour - hour) >= 2) { return true; }
    // if hour did not match, it can not be selected
    return false;
}

function tpStartOnMinuteShowCallback(hour, minute) {
    var tpEndHour = $('#Inputfield_end_time').timepicker('getHour');
    var tpEndMinute = $('#Inputfield_end_time').timepicker('getMinute');
    // all valid if no end time selected
    if ($('#Inputfield_end_time').val() == '') { return true; }
    if ( (tpEndHour - hour) >= 2  && (minute <= tpEndMinute) ) { return true; }
    // if minute did not match, it can not be selected
    return false;
}

function tpEndOnHourShowCallback(hour) {
    var tpStartHour = $('#Inputfield_start_time').timepicker('getHour');
    // all valid if no start time selected
    if ($('#timepicker_start').val() == '') { return true; }
    // Check if proposed hour is 2 hours after selected start time hour
    if ( (tpStartHour >= 20) && ( (hour - tpStartHour) >= 1) ) { return true; }
    if ( (hour - tpStartHour) >= 2) { return true; }
    // if hour did not match, it can not be selected
    return false;
}

function tpEndOnMinuteShowCallback(hour, minute) {
	if ((hour == 21) && (minute >= 30)) { return false; }
    var tpStartHour = $('#Inputfield_start_time').timepicker('getHour');
    var tpStartMinute = $('#Inputfield_start_time').timepicker('getMinute');
    // all valid if no start time selected
    if ($('#Inputfield_start_time').val() == '') { return true; }
    // Check if proposed hour is equal to selected start time hour and minutes is after
    if ( ( (hour - tpStartHour) >= 2) && (minute >= tpStartMinute) ) { return true; }
    // if minute did not match, it can not be selected
    return false;

}

 

 

  • Like 5

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...