Jump to content

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


horst
 Share

Recommended Posts

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?

Link to comment
Share on other sites

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
Link to comment
Share on other sites

@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
Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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