Custom time increments for Kintone's time fields - javascript

In Kintone, the time field currently increments by 30 minutes, but is there a way with JavaScript to change this increment, say, by 10 minute increments?
I know this doesn't fit well with Kintone's JavaScript coding guidelines, but would changing the DOM structure of the time field to show 10 minute increments be the correct way to move forward?

Like you said, this is probably possible by editing the DOM, but not the best option since the customization may not work after any update.
As an alternative or a better choice, you can create two drop-down fields, "hour" on one of the them and "minute" on the other field.

Thanks Yuzo
I tried out your solution to see what it's like, and found out it was actually a good alternative.
I currently have it working with the 24 hour clock format, as below.
gif image of customization
(function() {
"use strict";
// "hours" -> field code of Hours field
// "minutes" -> field code of Minutes field
// "time" -> field code of Time field
kintone.events.on(['app.record.create.submit','app.record.edit.submit','app.record.index.edit.submit'], function (event) {
var hourvalue = event.record.hours.value;
var minutevalue = event.record.minutes.value;
event.record.time.value = hourvalue + ":" + minutevalue;
return event;
});
})();
My team prefers to work with 12 hour clock format though, so I added in a radio button field to represent AM and PM. I also changed the drop down to only include selections from 0 to 11.
I edited my code a bit more so that the selected hour number will get a +12 before being entered into the time field, but I keep getting an error, "event.record['time'].value is invalid.". Not really sure why this should be happening. This is my new code:
(function() {
"use strict";
// "hours" -> field code of Hours field
// "minutes" -> field code of Minutes field
// "time" -> field code of Time field
// "ampm" -> field code of radio button field that has selections of AM and PM
kintone.events.on(['app.record.create.submit','app.record.edit.submit','app.record.index.edit.submit'], function (event) {
var hourvalue = event.record.hours.value;
var minutevalue = event.record.minutes.value;
if (event.record.ampm.value == "PM"){
hourvalue = hourvalue + 12;
}
event.record.time.value = hourvalue + ":" + minutevalue;
return event;
});
})();

I did some test regarding what you are doing.
It seems like the error you are seeing appears only when the field type that you are returning
to in the script does not match the actual field type that you have placed in the form.
So I assume when you changed your form to make it as the 12 o'clock format,
you might have changed the field that you put the value into to a time field,
which before it was a text field.
Can you check into it?
I will put a link below regarding the field types just for your reference
kintone developer network - Field Types https://developer.kintone.io/hc/en-us/articles/212494818-Field-Types

I think the drop-down field returns a string value.
Therefore, you need to convert it to a number by using parseInt function before hourvalue like hourvalue(hourvalue + 12). Thanks.

Related

Using Javascript to calculate a derived column in a tabular form

So after doing some reading (and not quite understanding a few things) I'm wanting to find out more about derived columns in APEX reports.
The page has a tabular form which shows the tasks they have selected and they can select the time in hours (1-12) and minutes (15min intervals). What they input displays on a report which summarises the time they've allocated to a task from Monday to Friday and also gives a total down the bottom.
A request has been made to be able to not only see the totals for the day down the bottom but also the weekly total for each task on right so I've inserted a derived column.
In the page attributes under Javascript - Function and Global Variable Declaration, I have the following simple function:
var htmldb_delete_message = '"DELETE_CONFIRM_MSG"';
function sum_values(mon, tues, wed, thurs, fri, sat) {
// pass page item names into the function
// $v will get the value from the item name
result = $v(mon) + $v(tues) + $v(wed) + $v(thurs) + $v(fri) + $v(sat);
return result;
}
and then in the derived column HTML attributes I have:
<script>
sum_values(#MONDAY#, #TUESDAY#, #WEDNESDAY#, #THURSDAY#, #FRIDAY#, #SATURDAY#)
</script>
This is not displaying anything and I'm not sure what I'm doing wrong.

CRM 2011 - Set field's 'requiredlevel' to REQUIRED based on another field's value

I am working on the Opportunity form in CRM 2011.
I have 2 fields I am working with: azdb_payment1type & new_payment1cclast4orcheckgc
azdb_payment1type has option set values:
Visa = 807,370,000
Mastercard = 807,370,001
American Express = 807,370,002
Discover = 807,370,003
Check = 807,370,004
Cash = 807,370,005
Credit Rollover = 807,370,006
IF the value of this field (azdb_payment1type) is 807,370,004 or less, I'd like to REQUIRE that the new_paymentcclast4orcheckgc field is filled out.
I created a function for the azdb_payment1type field called "requireCClast_onchange", then added the below code to the form's main library:
function requireCClast_onchange() {
var payment1type = Xrm.Page.getAttribute('azdb_payment1type').getValue();
alert(payment1type);
if (payment1type <= '807,370,004') {
Xrm.Page.getAttribute("new_payment1cclast4orcheckgc").setRequiredLevel("required");
}
}
With the code inserted as onchange, nothing happens when I select a CC, then tab off the field. If I change the function to onsave, then edit the library with the changes, it DOES return the alert I set up in the code, but it doesn't change the Requirement Level from "Business Recommended" to "Required".
Is this even possible with Javascript?
I would have a look at this line. payment1type <= '807,370,004'
You are comparing a number to a string, I'm not sure have JavaScript will resolve that but I can't imagine its the way you would want.
I believe you should be doing, payment1type <= 807370004

Add certain number of days to the already selected date (the date that is in the datepicker textbox currently)

I have already looked on several questions on stackoveflow but no one seems to be answering my question.
In my application, users often need to go to +1 or -1 day from the current selected date. For this, I want to make this process more quick by adding two image buttons for +1 and -1 operation on the right side and the left side respectively.
I have tried this:
$('#date').datepicker('setDate', '-1');
But it always set the +1 date from the current date (that is today -1, not the -1 from the selected date).
How can I achieve this..??
Any help would be appreciable.
Tried Later:
function AddDays(arg) {
var d = $('#date').datepicker('getDate');
var d = new Date(d.getYear(), d.getMonth(), d.getDay() + arg);
$('#date').datepicker('setDate', d);
}
And Calling this function as AddDays(1) and AddDays(-1) on onclick event of image but It produces very strage result.
For Example if I set the current date to 25-03-13 that is in dd-mm-y format then clicking on -1 button is setting the date to 28-02-0-87. Clicking it on again will result in no change. And clicking it third time will result 01-02-0-87.
I can't get the point. What kind of behavior is this..??
Finally I have written my solution. Here is the code
function AddDays(arg) {
var d = $('#date').datepicker('getDate');
d.setDate(d.getDate() + arg);
$('#date').datepicker('setDate', d);
}
Where date is the id of my jquery-ui datepicker.
I am still looking for any inline code (single line) that I can put directly in onclick event of my next and previous buttons.

Multiple javascript timeouts - problem with live data fetching

I am building a real-time system which (with a use of websockets) updates a table with live data of different frequencies (can be 3 times per second, can be once every 2 seconds - dependant on the type of data).
I am currently struggling to find a way of letting the user know when a particular field has not been updated in the last 5 seconds. That is, if no new data is fetched, I shouldn't keep the old value there, but rather change it to '--' or something similar.
After a long way to the javascript, final function which updates fields looks like that (extremely simplified):
function changeValue(data){
var fieldId= data.fieldId;
var value = Math.round(data.value);
$('span#'+fieldId).text(value);
}
This function gets called each time a field needs to be changed. I've got between 2 and 40 different fields (dependant on the user) that are changed.
What is the best way of setting timers in order to change the values of the fields to '--' every 5 seconds, if no update has been made?
I would be really grateful for some tips,
Thanks,
Karol.
Since you want to indicate timeout on a per-field basis, you have two obvious options:
Have a global interval timer that ticks over fairly frequently and looks through all of your fields for a timeout.
Have independent timers for each field which just deal with that field.
I think on balance I prefer (1) to (2), because we're only dealing with one interval timer then and it makes the housekeeping simpler.
Since IDs in documents must be unique, we can use your field ID values as a key in a hash (an object) to store last updated times. This is kind of a spin on the previous answer but works on a per-field basis. So here's how we'd set those last updated times:
var lastUpdatedTimes = {};
function changeValue(data){
var fieldId= data.fieldId;
var value = Math.round(data.value);
$('span#'+fieldId).text(value);
lastUpdatedTimes[fieldId] = new Date().getTime();
}
Then you set up an interval timer to check each of them.
function checkFieldsForTimeout(){
var now = new Date.getTime();
// For each ID in lastUpdatedTimes, see if 'now minus
// last updated' is > 5000 and is so, set the field
// text to '--' and remove that entry from the last
// updated list with "delete lastUpdatedTimes[itemId]".
}
Should a timed-out field spring back to life, the "--" will be replaced by some real text again.
By deleting the last updated time from "lastUpdatedTimes" whenever we put "--" into a field, we make sure that the interval timer isn't wasting time processing fields that have already been timed out.
This answer was extended to handling multiple fields after the comment by #Andrew (please see also his answer).
Introduce a property updatedTime, which holds the last time the data was updated, in each data. A periodic timer checks updatedTime for all data and updates the text field if appropriate. The check has to be twice as often as the detection period. Your function changeValue() updates updatedTime and the text field.
function checkData() {
var now = new Date.getTime();
for "each data" {
if (now - data.updatedTime >= 5000) {
var fieldId = data.fieldId;
$('span#'+fieldId).text('--');
}
}
}
function changeValue(data) {
var fieldId = data.fieldId;
var value = Math.round(data.value);
$('span#'+fieldId).text(value);
data.updatedTime = new Date.getTime();
}
// Install periodic timer to check last updates:
setInterval(checkData, 5000 / 2); // interval = half the required detection period

Javascript time helper? -Interesting problem!

I am new to the world of javascript and even trying google search has not really helped me find what I am looking for.
So I have come here in the hope you can point me in the right direction.
RULE= It must not be click! Can be done by tabbing!
I have many text fields which the user will input times that have been recorded.
E.g. Event 1 happened at 11:31am
Event 2 happened at 11:59am
I want to make this process as easy as possible for the user by having the textbox formatted in hours and seconds in 24hr format:
So the textbox value= 00:00 and when the user selects the text box they can enter the hours part. Then it will jump to the seconds part.
Any idea if there is something that can do that if so could you link me. If not could you give me an idea of what the coding will be like and if there are easier alternatives.
I have made some pseudo code to help you understand my implementation goal:
for count = 0 , while count is less than 20, count++
{
create a texbox with name time+count, set the value to ="00:00"
}
when the user enters numbers they go into the hour segment until that is completed
the script then jumps the cursor to the minutes segment
if time+count+1 is lesser thatn time+count message user that time error "An event cannot occur before the previous event"
Thankyou for hearing me out!
I don't really know of any time pickers that would suit your needs, but here's a basic idea of how one would be implemented:
You have two textboxes, or multiple pairs of textboxes
In each textbox, you put an event handler to handle "onkeyup" event
In onkeyup handler, check if lenght of text in box is 2
If length is 2 -> focus the next textbox
This way the user can simply keep on typing the numbers.
You may need to add some additional checks into the event listener, for example to make sure that if the user comes back to the field, they can edit it easily (eg. if they press shift-tab, it won't focus an incorrect field)
If you wanted to be really fancy, you could have a single textbox for times. Then, each time user presses a key, you'd check if it's a number. If user first types two numbers, it would then insert a : as the separator if the third key is a number, and so on.
This might be a beginning. Using jQuery this is not such a painful task.
http://jsfiddle.net/sArjQ/
for(var i = 0; i < 20; i++) {
var input = $("<input>", { name: 'time' + i, // create input element
val: '00:00' });
input.click(function() {
$(this).prop({ selectionStart: 0, // move caret to beginning on click
selectionEnd: 0 });
}).keydown(function() {
var sel = $(this).prop('selectionStart'),
val = $(this).val(),
newsel = sel === 2 ? 3 : sel; // so that it moves two positions for :
$(this).val(val.substring(0, newsel) // automatically set value
+ val.substring(newsel + 1))
.prop({ selectionStart: newsel, // move caret along
selectionEnd: newsel });
});
$('body').append(input);
}

Categories

Resources