I'm using the excellent (but large) DateJS library to handle dates and times in my webapp. I just came across something that I'm not sure how to handle.
I want my users to be able to enter Time strings only, without a date, but they should be able to enter it in any manner they please. For instance:
5:00 pm
17:00
5:00pm
5:00p
5p
etc.
Using Date.parse(value) converts these strings into a full date, which is exactly what I want. However, it also allows the user to enter any other part of a date string, such as:
sat 5pm
1/1/2010 5pm
etc.
I'm trying to use DateJS to validate an input field for a time value. Something like:
function validateTime(value) {
return Date.parse(value) !== null;
}
Is there a way to use DateJS features to solve this? There are other SO questions that provide solutions, but if DateJS has a way to do this, I don't really want to add more custom code to my app to do this.
Shortly after asking my question, I discovered that Date.parseExact() can take an array of format strings. Somehow I'm missed that. I managed to get something working with the following code:
function validateTime(input) {
return Date.parseExact(input, [
"H:m",
"h:mt",
"h:m t",
"ht","h t"]) != null ||
Date.parseExact(input, [
"h:mtt",
"h:m tt",
"htt","h tt"]) != null;
};
Note that some formats don't seem to be able to be included together at the same time, which is why I split them into two separate parseExact() calls. In this case, I couldn't include any string that contained a single t in it with format strings that contained a double tt in it.
The additive approach seems cumbersome. Takes away the beauty of DateJS in my opinion. I needed the same solution and decided to just sneakily append the date in front of my input string before parsing with DateJS:
var parsed = Date.parse(Date.today().toString('M/d/yyyy') + ' ' + this.value);
if (parsed) {
alert(parsed.toString('h:mm tt'));
}
Now DateJS will not be sniffing around for any of its date-part parsing patterns, as you have already subbed it in.
Hope this helps someone!
Related
I am new to salesforce and I know my question sounds silly. But I need someone to tell me the direction I should go.
My question is how can I convert string or object like this
{Start_time__C:"2014-07-24T20:55:00.000+0000"}
and this
{perDiem: true}
into salesforce object. And then I can use create function in remoteTK.
I am currently building custom app on salesforce1. In my visualforce page, I need to create new record, which has datetime, and boolean as its fields.
Thank you in advance!
I don't know much about the remoteTK but before you deep dive into it you might want to look into the "Remote Objects" from Spring'14. This seems to be the new hip / official way of doing remoting (which doesn't mean I'm saying rTK is bad!) and slightly easier to use.
https://salesforce.stackexchange.com/questions/33072/visualforce-remote-objects
https://developer.salesforce.com/blogs/developer-relations/2014/03/spring-14-using-visualforce-remote-objects-with-canjs.html
http://andyinthecloud.com/2014/01/22/spring14-visualforce-remote-objects-introduction/
http://www.salesforce.com/us/developer/docs/pages/Content/pages_remote_objects_example_extended.htm
The main difference between them seems to be that you could use rTK in a non-visualforce page as underneath it just relies on REST callouts. The remote objects use a special VF tag so it's VF-only.
In the end I think it won't matter much which library you'll use. Sample remote object code:
// Create work order line item
var workOrderLineItem = new SObjectModel.WorkOrderLineItem__c();
workOrderLineItem.set('Description__c', 'Answering the question');
workOrderLineItem.set('Hours__c', answer);
workOrderLineItem.set('WorkOrder__c', result[0]);
workOrderLineItem.create(function(error, result, event)
{
// Errors?
if(error!=null)
alert(error);
else
alert('Success');
});
vs. the sample from remoteTK:
var objectType = 'Account';
var fields = {'Name': 'salesforce.com', 'Description':'CRM'};
client.create(objectType , fields,
function(response) {
getAccounts(function() {
$j.mobile.pageLoading(true);
$j.mobile.changePage('#mainpage', "slide", true, true);
});
}, errorCallback);
So a JavaScript object with fields is being created in both cases. For Booleans you should be good sending 'true' or 'false' strings.
For dates you might have to experiment a bit. Generally I've been passing Unix timestamp (miliseconds since Jan 1 1970), this seemed to work OK for me in REST calls or Visualforce Remoting (by which I mean #RemoteAction stuff, yet another tool).
The RemoteTKController.writeFields() seems to be using Date.valueOf(someString) when casting. This means the format should be 'yyyy-MM-dd HH:mm:ss' which is close enough - check if it will work out of the box and remove the timezone part from your string if it causes problems? You could simplify your examples a lot by skipping the remote part and directly check in Developer Console or Execute Anonymous how the parser reacts to different dates you'll feed it.
There's another function that seems to use REST API instead of the controller. This one will just pass the payload to REST API's POST request. Looking at how it's built you should be fine just passing a real JavaScript Date object as value, the JSON.stringify call should figure out how to serialize that. If you really want to craft the string yourself - check the REST API guide. The dates should look like that and all remoteTK'create call does is make a request similar to this one
This is an old thread, but in case it helps someone I was able to get this working. The yyyy-MM-dd HH:mm:ss format was very close. All it needed was a 'T' between the date and time to be acceptable. From there is was just making sure that all components came through as two digits, and converting the date to UTC time. Here's my final Javascript function:
function ConvertDate(dtin){
var d = new Date(dtin);
var convertdate = d.getUTCFullYear() + '-' + ('0' + (d.getUTCMonth()+1)).slice(-2) + '-' + ('0' + d.getUTCDate()).slice(-2) +'T' + ('0' + d.getUTCHours()).slice(-2)+':'+('0' + d.getUTCMinutes()).slice(-2)+':'+d.getUTCSeconds()+'0';
return convertdate;
}
From there I could pass the converted date to the sObject function without error.
The question is; there are 2 fields in my application, one is date (Field1) and second is a label (Field2). So, I want that when user selects a date in field 1, then field 2 should be automatically populated (current date - date from field 1).
Can anyone help on how to implement it.
I'm using jQuery to display date:
// This displays the date dialog when user clicks on Field1
$('#Field1').click(function () {
$('#Field1').simpleDatepicker();
});
// Tried following code but it didn't worked
$('#Field1').click(function () {
$('#Field1').simpleDatepicker({
onSelect: function () {
$('#Field2').value(calculateDays($('#Field1').toString))
}
});
});
function calculateDays(dateString) {
var today = new Date();
var inputDate = new Date(dateString);
var days = today - inputDate;
return days;
};
This may look like pathetic code to some folks but I'm just a beginner, so any suggestions/comments are welcome.
Also please tell me if this can be done using html only and no need to go to jQuery. It is my understanding that the calculating days (difference between dates) code will go in jQuery since this needs to be fired after selecting date ('onSelect' event). Please correct if wrong.
I'm assuming that you're trying to use Karl Seguin's jquery.simpleDatePicker (it came top when searching for "simpledatepicker" on Google).
As Jimbo remarks in the comments, it's hard to advise on an MVC approach here — you say you want to do this purely with HTML, but HTML alone can't dictate behaviour (I'd say that's extremely un-MVC). HTML5 forms do allow some limited behavioural control (validation etc), and they also offer <input type="date"/>, but none of these help your situation.
So for this answer I'm just going to fix the mistakes in your code:
The plugin is initialised with the simpleDatePicker jQuery method — you forgot to capitalise the 'P';
The plugin itself caters for the click event. You should initialise it directly without waiting for user input;
There was no onSelect initialisation option in the source code: I chose to use a change event listener on the input to capture this;
You use the jQuery method value — that's native DOM Javascript — you should be using val instead;
toString won't work on DOM elements or jQuery objects — again, use the val method;
The native Date object can't parse dates in arbitrary formats — nor would your code produce a number of days if it did (it would just produce the difference in milliseconds). For this kind of functionality you should use a good date library: I've opted for Moment.
Resulting code (as demonstrated here):
$('#Field1')
.simpleDatePicker()
.on('change', function passValue(){
$('#Field2').val(calculateDaysFromNow($('#Field1').val()))
});
function calculateDaysFromNow(dateString){
return moment.duration(moment(dateString,'MMM DD YYYY').diff()).days();
}
A bit of elaboration on how I've used moment:
First of all, we want to parse #Field1's formatted date for an actual quantifiable date object:
moment(dateString,'MMM DD YYYY')
Next, we want to differentiate that from now. Like Date, moment assumes now if we pass no argument:
moment(dateString,'MMM DD YYYY').diff()
We don't want this as a date, but as a duration, so we'll pass it to moment's duration method:
moment.duration(moment(dateString,'MMM DD YYYY').diff())
…and finally, we want this expressed in days:
moment.duration(moment(dateString,'MMM DD YYYY').diff()).days()
I'm not sure but this:
$('#Field2').value(calculateDays($('#Field1').toString)) should be like this:
$('#Field2').value(calculateDays($('#Field1').val())) or $('#Field2').value(calculateDays($('#Field1').text()))
Here is solution for setting same date in second field.
Link:jquery: using two datepicker with two fields ( field 1 , field2 + 1 day ) like booking.com
Change the format according to your need.
The below answer to another thread seems to make a start on what I think I need, but I am having difficulties in implementing it.
The best library for that purpose would probably be Globalize. It
allows you to specify the locale (it is called culture but it is
actually the same), the format (built-in or your own) and actually
parse string to given date:
var dateString = "lunes, 29 de agosto de 2011"; // seems like long
date format in Spanish var date = Globalize.parseDate( dateString,
"D", "es" );
You would need to attach appropriate culture file as well as reference
to Globalize to make it work. Please mind that cultures are already
defined in the library, so don't be afraid of the message on the web
page, you actually don't need .Net.
If someone could turn this into a working example I could then take this and adjust to what I need.
However ... does anyone know of an alternative method?
My string for example is:
"Set 24, 2012 20:40:20" which has the month in Romanian.
I need it to be
"Sep 24, 2012 20:40:20" which has the month in English.
I need a solution that can take the language code (ie en, es, pl, ru, ro etc) and convert the month in the string (needs to be able to handle all 12 months, not just the one in the above string) from the foreign language to English.
Any speedy help would be most appreciated so that I can get my site back up and running at full speed again.
If you require any further information from me please ask :)
Regards
Ross
#Jukka K. Korpela
I have this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Testing Globalize</title>
<meta name="keywords" content="Globalize, Testing">
<meta name="description" content="Trying to get globalize to work.">
<script src="https://github.com/jquery/globalize/blob/master/lib/globalize.js"></script>
<script src="https://github.com/jquery/globalize/blob/master/lib/cultures/globalize.cultures.js"></script>
<script>
var monthString = 'sep'; // replace by code that extracts the string
var lang = 'ro'; // replace by code that picks up the right language
var month = Globalize.parseDate(monthString, 'MMM', lang);
if(month) {
document.write(Globalize.format(month, 'MMM', 'en'));
} else {
alert('Unrecognized month: ' + monthString);
}
</script>
</head>
But it doesnt work when I test in "http://htmledit.squarefree.com/" please help :)
I think u could use datejs for your purpose.
It is capable of parsing your date data in any language available (150+ as the state) via a culturefile and then save it in english or any other language you desire.
Have a look : http://code.google.com/p/datejs/
The way to do such things in Globalize.js is to read the string using one locale, write it using another locale. You need to check the success of reading by some test that checks against null value (since this value signals an error). Like this:
<script src="globalize.js"></script>
<script src="globalize.cultures.js"></script>
<script>
var monthString = 'sep.'; // replace by code that extracts the string
var lang = 'ro'; // replace by code that picks up the right language
var month = Globalize.parseDate(monthString, 'MMM', lang);
if(month) {
document.write(Globalize.format(month, 'MMM', 'en'));
} else {
alert('Unrecognized month: ' + monthString);
}
This parses just the month abbreviation, or “short name” of month.
The problem is with the variation inside cultures. For example, for Romanian language, the short name of September is “sep.” in Globalize.js data (mainly based on .NET data; Datejs is probably based on the same data here) but “sept.” in CLDR data, and your example mentions “Set”!
Globalize.js reads names case-insensitively, but otherwise it uses the exact string in its locale definitions (e.g., “sep” won’t do if the definition says “sep.”). There are various ways around this. At the simplest, edit the locale definitions in Globalize.js to match those used in your data. Alternatively, you can create an alternate locale (a variant) with different month names and parse the name using it if it does not parse according to the basic locale. So this is a way to allow, on input, different sets of month names for a language.
Of course, if it’s only a matter of mapping short month names from different languages into English, you could simply write the code for it directly. But you would still need to get the names into your objects from somewhere – from .NET, from CLDR, or from your actual data.
I've stumble upon this difficulty back in 2013, and did work on a small utility to address the problem.
I published my v3 yesterday : https://framagit.org/Siltaar/month_nb
It supports 69 languages, and you don't have to know the language of your month name to get it's number. It's based on a re-usable standalone JSON tree structure for the data and a small tree-walking loop to find the results.
To use it, simply include both the data and the tree-walker files in a web page :
<script src="month_nb_json.js" type="text/javascript"></script>
<script src="month_nb.js" type="text/javascript"></script>
Then you'll be able to use it :
>> month_nb('août');
8
It's part of my Meta-Press.es project, which got some funding and that I'll continue to work on for at least the next 6 years (started in 2013…).
Else, it exists https://github.com/datejs/Datejs which is a human contributed translation approach.
I am querying facebook graph api. It returns date in following format: 2012-01-23T23:52:29+0000.
I need to find difference of dates of this type in javascript. It's not a valid date in javascript ( by Date.parse() or new Date() )
I am thinking of replacing 'T' with ' ' (a space), '-' with '/' and '+0000' with '' (empty string). Is this the only way? Or am I missing something here?
Also, if this is the only way, can someone give me a regex to replace all in one go?
Execution speed is my main concern.
I'd say yes to replacing - with /, since that's that the ISO-whatever standard dictates (Facebook likes to screw things around, like <meta> tags with property attributes instead of name like they should be).
Keep the timezone part, since JS understands that and will handle it accordingly.
Overall, you want new Date(input.replace(/-/g,'/'));.
In response to comments, a better (more complete) solution would be:
new Date(input.replace(/-/g,'/').replace("T"," ").replace(/\+[0-9]+$/,''));
I came across Datejs recently and found it very useful. However I could not figure out if there is a way to parse a string and extract only date part from it using the same.
For example, if there is a string >> "I will start exercise from next Monday."
Then it should parse the string, extract 'next monday' from it and convert it into date and give me the result.
How can it be implemented?
Thanks :)
You can write some RegEx for that. That would be the easiest way. 'next' will be a keyword in that case. A simple function can lookup the current weekday and return the date of the next monday. Should not that complicated.
Edit:
You can do something like this:
var pattern = /^([\w\W.]*)(next){1}([\sa-zA-Z]*)/;
while (result = pattern.exec(yourTextVariable) != null){
// read the data as you need from the result array
}
The Pattern above expecting a white space then the keyword next and will red the next word if it only has alpha-letters. (please note that the RegEx is untested and may need some refactoring to fit your needs. You may take a look at this page to do this: javascriptkit.com)