horst Posted December 18, 2017 Share Posted December 18, 2017 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 More sharing options...
bernhard Posted December 18, 2017 Share Posted December 18, 2017 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... 5 Link to comment Share on other sites More sharing options...
SamC Posted December 18, 2017 Share Posted December 18, 2017 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? Link to comment Share on other sites More sharing options...
bernhard Posted December 18, 2017 Share Posted December 18, 2017 Several options. Admin custom files module. AdminOnSteroids has this option too I think. And finally my favourite way: via hook (several possibilities here again) 2 Link to comment Share on other sites More sharing options...
SamC Posted December 18, 2017 Share Posted December 18, 2017 Thanks @bernhard it's those hooks again! Thinking it may be prudent for me to learn about those before starting a module. Link to comment Share on other sites More sharing options...
bernhard Posted December 18, 2017 Share Posted December 18, 2017 @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: $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: 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: We know that the hook is attached as Pages::saveReady (eg because we have read that somewhere) 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: Searching for "___saveReady" lets us find the corresponding method: Now we see, that we have ONE "arguments", being Page $page - this means $event->arguments(0) would return the page being ready for saving $event->object would be the class, here "Pages" $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 16 3 Link to comment Share on other sites More sharing options...
adrian Posted December 18, 2017 Share Posted December 18, 2017 An extra +1 for using the the Console panel's code injection feature for testing hooks 3 1 Link to comment Share on other sites More sharing options...
rick Posted December 18, 2017 Share Posted December 18, 2017 Sorry @bernhard, the forum won't let me like your reply more than once. I learned a couple of new things from your response. Kudos sir! 3 Link to comment Share on other sites More sharing options...
horst Posted December 18, 2017 Author Share Posted December 18, 2017 15 minutes ago, rick said: Sorry @bernhard, the forum won't let me like your reply more than once. HINT: 2 2 Link to comment Share on other sites More sharing options...
SamC Posted December 18, 2017 Share Posted December 18, 2017 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 More sharing options...
bernhard Posted December 19, 2017 Share Posted December 19, 2017 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. 1 Link to comment Share on other sites More sharing options...
horst Posted December 19, 2017 Author Share Posted December 19, 2017 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! 3 Link to comment Share on other sites More sharing options...
Macrura Posted December 19, 2017 Share Posted December 19, 2017 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; } 5 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now