Finds out a start of the year for the given date.
CREATE FUNCTION [dbo].[StartOfYear] ( @DATE DATETIME ) RETURNS DATETIME AS BEGIN RETURN DATEADD(yy, DATEDIFF(yy,0,@DATE),0) END
Finds out a start of the year for the given date.
CREATE FUNCTION [dbo].[StartOfYear] ( @DATE DATETIME ) RETURNS DATETIME AS BEGIN RETURN DATEADD(yy, DATEDIFF(yy,0,@DATE),0) END
Finds Start of the month with given date
CREATE FUNCTION [dbo].[StartOfMonth] ( @date datetime ) RETURNS datetime AS BEGIN return DATEADD(M,-1,DATEADD(mm, DATEDIFF(m,0,@date)+1,0)) END
Finds end of the month with given date
Create FUNCTION [dbo].[EndOfMonth] ( @date datetime ) RETURNS datetime AS BEGIN return DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@date)+1,0)) END
Function to find latest second of the year for the given date
Create FUNCTION [dbo].[EndOfYear] ( @DATE DATETIME ) RETURNS DATETIME AS BEGIN RETURN DATEADD(s, -1, DATEADD(yy, DATEDIFF(yy,0,@DATE)+1,0) ) END
What I have been talking about the past few days can be seen on the screen-shots:
One of the screens has “Internal” option selected and loads less details requested. The other screen-shot shows “External” option and with loads more fields on the screen. This is the same screen, only bits hidden via Custom Script in HR.Net.
Notice how on the bottom part of the screen most of the tabs are not displayed for internal candidate? There is no standard function for this, so I had to do a bit of research.
It turned out that these buttons do not have proper names, so there would be a little game of guess a name. Good thing, tab headers are named after the tab area: “TabAreaName0”, “TabAreaName1”, “TabAreaName3”, etc. And the numbers seemed like in the proper order.
I had to hide a few tabs, so my function works with array of names:
var tabs = ["DetailsPage1", "DetailsPage2", "DetailsPage8"]; //Use this to hide tabs display_tabs(tabs, 'none'); // use this to display hidden tabs display_tabs(tabs, 'inline'); /** * This function shows or hides tabs on tabulated area. * @param tabsArray array with strings - names of tabs. * @param style - string with style to apply. Can be 'none' or 'inline' */ function display_tabs(tabsArray, style){ var tab for (var i = 0; i < tabsArray.length; i++){ tab = document.getElementById(tabsArray[i]); if (tab != null) tab.style.display = style; } }
Convert HRNET string with date into JS date format
function getLocalizedDate(sDateStr) { var oDate = new Date(); //Parse the date according to your string var oDateARR = sDateStr.split("/"); oDate.setDate(oDateARR[0]); oDate.setMonth(oDateARR[1]-1,oDateARR[0]); oDate.setFullYear(oDateARR[2]); return oDate; }
Standard HR.Net Java Script tools does not allow to hide data grids, but this is sometimes required.
Here is a JS function to hide data grids.
function hideDataGrid(gridName){ var grid = document.getElementById(name); var openButton = document.getElementById(name+"Grid_ImgOpen"); var insertButton = document.getElementById(name+"Grid_ImgInsert"); var deleteButton = document.getElementById(name+"Grid_ImgDelete"); if (grid != null) grid.style.display = 'none'; if (openButton != null) openButton.style.display = 'none'; if (insertButton != null) insertButton.style.display = 'none'; if (deleteButton != null) deleteButton.style.display = 'none'; }
With version 3 of HR.Net (Yes, I know, there is version 4 out ages ago) Vizual gave ability to insert JavaScript into Screens and Workflows. And I have been using this ability rather a lot on screen.
Very often you need to prompt for different fields, depending on previous user selection. For example you can have group of radio-buttons for Internal or External candidate. So I’ve developed a JavaScript that hides groups of fields depending on the selection.
Please have a look on this code. I’m sure this can be improved, but it is good enough for this case. If you know JavaScript, you’ll be able to reuse some of the code from here.
// initially checks what fields to display, when the screen opens up check_internalExternal(); // set onclick events for all the members of radio-buttons trigger_radio_change("InternalExternal", "check_internalExternal") function check_internalExternal(){ // This is an array with names of all the elements needs to be hidden, including label names. var external = ["Title", "TitleLabel", "Firstname", "lblFirstname", "Lastname", "lblLastname", "DrivingLicence", "lblDrivingLicence", "ExternalApplicatnLabel"]; var internal = ["PEOPLEID1", "PeopleIDLabel"]; var type = $HRnet("InternalExternal").getDisplayValue(); //Checking what radio-button is selected if (type =='Internal'){ visible_ElementsArray(external, false); visible_ElementsArray(internal, true); }else { //internal visible_ElementsArray(external, true); visible_ElementsArray(internal, false); } } /** * HR.Net functon called when save button is clicked. Useful for validation purposes. * This function overrides native HR.Net function, where HR.Net does it's own validation for data, * like required fields and dates greater than other dates. * So you need to be careful with all the validation - make sure all the required fields are catered for. */ function Page_ClientValidate() { var ErrMsg =''; var validate = true; var type = $HRnet("InternalExternal").getDisplayValue(); // event is selected, but the field is empty if ((type =='External') && ( ($HRnet("FirstName").getDisplayValue()=='') || ($HRnet("LastName").getDisplayValue()==''))) { ErrMsg += 'First and Last Names for External Candidate must not be empty\n'; validate = false; } if ((type =='Internal') && ($HRnet("PEOPLEID1").getDisplayValue()=='')) { ErrMsg += 'Associated Employee record must not be empty for Internal Candidate\n'; validate = false; } if (!validate){ alert(ErrMsg); } return validate; } /** * Function to go through array of strings and change readOnly state of the named element. * @param array of strings with names of elements that need to be disabled/enabled * @param lock boolean. True to make the fields read-only, false to make them editable. */ function visible_ElementsArray(array, lock){ for (var i = 0; i < array.length; i++) { $HRnet(array[i]).visible(lock); } } /** * Find all elements of radio buttons group and assign them onclick event. * In HRNET radio buttons are called "name_0", "name_1", "name_2", etc, so we need to find all these elements. * @param element_name - string with name of element. Same as it goes in HRNET screen builder. * @param function_name - string with name of function you want to assign for onclick event. */ function trigger_radio_change(element_name, function_name){ // before proceeding with anything else, check that passed function exists if( eval("typeof " + function_name) != 'function') { return; // if function does not exist, return } var element; //loop to go from zero, until we no longer can find an element for (var i = 0; i != -1; i++){ element = document.getElementById(element_name + "_" + i.toString()); //get element by ID if (element == null) { //check if element exists i=-1; return; // if no element, we exit the function } // if element there, we assign onlick event as function element.onclick= function(){ eval(function_name+"()"); //function is dinamically calculated. } }//end of for-loop } //end of trigger_radio_change_function
Finally I managed to upgrade WordPress to the latest version, so it is much more pleasant to work with. Also change the way site looks – used new cool theme from WordPress.
Hopefully I’ll post loads more stuff here.
Right.. Anther silly discovery for today.
When you create a triggered workflow, even if you create it in the subfolder for “Trigger based”, you still have an option to have it Form Based. If you in rush and did not supply data source for the trigger, it will not come up on the list of available triggered workflow, when you create actual trigger.
This did catch me and my coleage: we created a few “test” workflows, presumed they are trigger based workflows.. and tried to create actual triggers for them. No wonder, these “test” workflows did not come up on the list of available triggered workflows.. as we created them as form-based. DUH!