MooTools Date Picker default format - javascript

I am using the datepicker from mootools and trying to have it localised format depending on the users location.
For example:
08/15/13 //American
15.08.13 //English
The documentation states that it should change by default format: (*string*, defaults to the default localized format)
But using this code:
window.addEvent('domready', function(){
new Picker.Date($$('input'), {
timePicker: true,
positionOffset: {x: 5, y: 0},
pickerClass: 'datepicker_bootstrap',
useFadeInOut: !Browser.ie
});
});
It always uses the American format 08/15/13 (Month first).
I am testing by changing my Time Zone set in windows 7 Date and Time

I don't think DatePicker does that "out of the box". I am not sure there is a water-proof way to get user location or language codes in client side scripts.
I just tried :
var language = window.navigator.userLanguage || window.navigator.language;
console.log(language);
and got "sv" in Chrome and "en-GB" in Firefox, in the same machine.
I got about the same using php / HTTP-request header. Thought about getting the info from server-side. This question points HTTP_ACCEPT_LANGUAGE as the best way, BUT:
$_SERVER["HTTP_ACCEPT_LANGUAGE"] // gives me:
sv-SE,sv;q=0.8,en-US;q=0.6,en;q=0.4 //in chrome
en-gb,en;q=0.5 //in firefox
If you look in the DatePicker.js file you have in the first lines:
---
name: Locale.en-US.DatePicker
description: English Language File for DatePicker
authors: Arian Stolwijk
requires: [More/Locale]
provides: Locale.en-US.DatePicker
...
This gives me a feeling that it is set to en-US. It will work if you set it manually though.
My suggestion is to follow Dimitar's suggestion and set it manually with Locale.use(). If you add for example Locale.use('sv-SE'); before you call DatePicker you will get date in format yyyy-mm-dd.
I did a script to read the client-side language to try to make it dynamical. It works but It's not tested. This assigns a language comparing the Mootools Locale.list() and the browser/javascript answer I posted above:
var language = window.navigator.userLanguage || window.navigator.language;
console.log(language); //gives the results I wrote above (sv/en-GB resp. Chrome/FF)
var list = Locale.list().length;
for (var i = 0; i < list; i++) {
if (Locale.list()[i] == language) { //check if it's a full match
Locale.use(language);
} else {
// go for the first part of the "sv-SE" and find a match
// this is a compromise, it gets the right language but might miss the right country
var langArray = language.split('-');
var locArray = Locale.list()[i].split('-');
for (var k = 0; k < list; k++) {
if (langArray[0] == locArray[0]) {
Locale.use(Locale.list()[i]);
}
}
}
}
console.log(Locale.getCurrent().name); // gives sv-SE/en-GB resp. Chrome/FF
new Picker.Date($$('input'), {
// etc...
If you thinks it's useful you can fine-tune it...
Fiddle here

Related

Moment Timezone returns correct timezone but with wrong spelling

I am using MomentJS Timezone. However, when I do moment.tz.guess(), it returns my timezone with wrong spelling.
const timezone = moment.tz.guess();
console.log(timezone); //returns Asia/Katmandu instead of Asia/Kathmandu
Yes, I could've just edited the js file and corrected the spelling but I'm afraid it's same for other countries too. Since I will be unaware of it, this might degrade the user experience!
Is this behavior expected or is there any way to fix it?
SEE THIS:
Correct Timezone List [Moment] [Javascript] [PHP] [Internationalization API]
I am using moment 2.2.22 and 0.5.17 data, here is the result I found.
var timezones = moment.tz.names();
console.log(moment.tz.guess());
for (var i = 0; i < timezones.length; i++) {
var node = document.createElement("LI");
var textnode = document.createTextNode(timezones[i]);
node.appendChild(textnode);
document.getElementById("mm").appendChild(node);
}
#mm span {
width: 100%;
}
<script src="https://momentjs.com/downloads/moment.min.js"></script>
<script src="http://momentjs.com/downloads/moment-timezone-with-data.min.js"></script>
<ul id='mm'></ul>
My result showed that there are two names coming for same timezone (Kathmandu and Katmandu), which has written like Asia/Kathmandu|Asia/Katmandu (one updated second obsolete). After researching slight a bit I found this is because obsolete timezone and chrome behaviour this issue will not occur on Firefox or any other browser.
This issue is also not going to be resolved by developers as this doesn't create any problem. This is a known Chrome behaviour that leads to Moment making an incorrect guess. The Moment development team is uninterested in developing a workaround. More info can be found here.
So I would suggest you use string and format it according to your need and suggested on the previous answer.
Note
Please test the example in other browsers as well.
See this post why results differ.
If you are getting result Asia/Katmandu return value as Asia/Kathmandu.
//for kathmandu, it returns Asia/Katmandu(chrome)
//returns Asia/Kathmandu (firfox);
var timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
if(timeZone === 'Asia/Katmandu'){
timeZone = 'Asia/Kathmandu';
}
console.log(timeZone);
MomentJs DEMO
var timeZone = moment.tz.guess();
if(timeZone === 'Asia/Katmandu'){
timeZone = 'Asia/Kathmandu';
}
console.log(timeZone);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.21/moment-timezone-with-data.js"></script>

Flash/Animate CC Tween Formatted Number

I'm using Animate CC (the erstwhile Flash CC) to do some ads that I'm exporting in HTML5 format (<canvas> and CreateJS stuff). They're working quite nicely overall.
I have a formatted number, in a Static Text box, like so: 5,000,000 and I want to tween it to, say, 20,000, over the course of 30 frames. I want to tween the same text to 5,000 and 1,000,000 and so on throughout the course of my scene.
In my limited Animate CC experience, I've managed to avoid using any Javascript, but I imagine that I will need to now. So, my question: how do I do this?
My thoughts on ways of doing this:
Since I'm using CreateJS, which has the TweenJS library as part of it, maybe I can just use that for tweening? Make little Actions at different points of my timeline? Not sure how all that works, and a lot of the references online are for ActionScript 3 or even AS2. Sample code would be appreciated.
If I do get into Javascript, there's the question of how I would do the number formatting. I could tween the number as 5000000 -> 20000 and on each frame update insert commas, that's one way of doing it. But to make matters more complex, these ads are going to be translated, and different locales come into the mix. So in English you get 5,000,000 and in German would you have 5.000.000, of course.
Since we're talking Javascript in the browser, I'm aware of the method Number.prototype.toLocaleString() which does the following:
The toLocaleString() method returns a string with a language sensitive
representation of this number.
That seems like it would do the trick, but then I have to worry about browser compatibility and what happens if I don't specify a locale. Ideally, since the German ads would only be displayed to people who had a German locale on their browser/OS, I could just call the method without any locale specified, and it would read it off the user's computer. I suppose it's possible to have the scenario where a German person is seeing an English ad, but I'm not that worried about it.
However, on the MDN page for toLocaleString() it has this big warning about earlier versions of FF defaulting to Western Arabic digits, so it makes me doubt the use of the method entirely.
Finally, I have the interesting fact that the translators will almost certainly take 5,000,000 and convert it into 5.000.000 for German. So it may be possible to avoid the use of toLocaleString() since I'll already have localized text. So if it were possible to write a simple Javascript function that could tween arbitrarily formatted numbers, I think that would do the trick. Perhaps:
Take the starting number and rip formatting out of it, save it
Tween the number
On each frame update, inject the formatting back into it
Probably not that hard from a JS perspective, but where I get stumped is how the heck I would do this in Animate/Flash and/or with CreateJS/TweenJS?
As far as tweening a formatted number using TweenJS, you can just tween a non-formatted number, and on "change", create a formatted version to do what you need:
createjs.Tween.get(obj, {loop:true})
.to({val:10000}, 4000)
.to({val:0}, 4000)
.on("change", formatNumber);
function formatNumber(event) {
// Round and format
var formattedNumber = (obj.val|0).toLocaleString();
}
Here is a simple fiddle: http://jsfiddle.net/m3req5g5/
Although Lanny gave some good data, I wanted to lay out exactly what I ended up doing to get this working.
First, you need to get a reference to the object you're going to be tweening in some way. When you make an Action in Flash and write Javascript, this is bound to the Stage, or to the MovieClip or Graphic that you're editing:
http://createjs.com/html5ads/#Scope
You can access objects using their instance names which are defined in Flash on the Properties of the object, once you've placed it on the Stage. Some sources online said that it was based on the symbol name or some such, but I haven't found that to be the case.
// Get a reference to the object you want to tween
var obj = this.anInstanceName;
Note that, if you want to access something that's inside a MovieClip, you will need to give your MovieClip on the stage an instance name, and then go inside the MovieClip and give an instance name to your target object. Then you can just walk down the hierarchy:
// Get a reference to the nested object you want to tween.
var obj = this.movieClipInstanceName.nestedInstanceName;
Now you can tween any numeric property of the object in question. For me, because I wanted to tween the text, I set an additional property on the object and tweened that, then formatted and copied it over into the text property as I went along.
It was useful to be able to specify how many frames the tween lasted, rather than the milliseconds, so I passed the useTicks flag.
obj.counter = 0;
createjs.Tween.get(obj, {useTicks: true})
.to({counter: 100}, 30) // <- 30 frames, this number is ms without useTicks
.on("change", formatNumber);
function formatNumber(event) {
obj.text = obj.counter.toLocaleString();
}
The above is generally applicable. Otherwise, here's the working code that I ended up using. It should be able to be dropped into a Flash Action in an HTML5 Canvas project and just work.
// Figures for tweening
var textStart = "2,000";
var textEnd = "6,000,000";
// Locate our target text box
var target = this.myTextBox; // replace "myTextBox" with your instance name
// Get our formatting data and so on
var data = this.getFormatData(textStart);
// Set up the text box
target.number = data.number;
target.text = textStart;
// Get the raw number we're tweening to
var endNumber = this.getFormatData(textEnd).number;
// Create the tween
createjs.Tween.get(target, {useTicks: true})
.to({number:endNumber}, 30)
.on("change", format);
//Formatting function, gets called repeatedly for each frame
function format(event) {
var rounded = Math.round(target.number);
var formatted = formatNumber(rounded, data.format);
target.text = formatted;
}
// UTILITY FUNCTIONS:
// Takes "###,###,###" or somesuch
// Returns a raw number and a formatting object
function getFormatData(formattedNumber) {
var toString = "" + formattedNumber; // in case it's not a string
var reversed = toString.split('').reverse(); // get a reversed array
// now walk (backwards) through the array and remove formatting
var formatChars = {};
for (var i = reversed.length-1; i >= 0; i--) {
var c = reversed[i];
var isnum = /^\d$/.test(c);
if (!isnum) {
formatChars[i] = c;
reversed.splice(i, 1);
}
}
// get the actual number
var number = parseInt(reversed.reverse().join(''));
// return the data
var result = {number: number, format: formatChars};
return result;
}
// Takes a raw number and a formatting object and produces a formatted number
formatNumber(number, format) {
var toString = '' + number;
var reversed = toString.split('').reverse();
var index = 0;
while (index < reversed.length) {
if (format[index]) {
reversed.splice(index, 0, format[index]);
}
index++;
}
var finished = reversed.reverse().join('');
return finished;
}
This fiddle demos the formatting and has a bit more of an explanation in the comments.
There are other ways of doing this, for sure, such as toLocaleString(), but this fit my exact requirements. Hopefully it'll help someone else.

Date range picker - invalid date

I am using this date range picke (http://www.daterangepicker.com/#options)
Here are some of options, I understand the most but I need help about "isInvalidDate"
I use this code and it works perfectly. Date 11/12/2015 is disabled and users can't select it.
isInvalidDate: function(date) {
if (date.format('YYYY-MM-DD') == '2015-11-12') {
return true;
} else {
return false;
}
},
But I need to add few dates to invalid, so user can't use them.
I don't know how to do some array and loop through to return true or false days, could anyone help me with this?
I hope it will help someone
var some_date_range = [
'02-04-2016',
'03-04-2016',
'04-04-2016',
'05-04-2016'
];
"isInvalidDate" : function(date){
for(var ii = 0; ii < some_date_range.length; ii++){
if (date.format('DD-MM-YYYY') == some_date_range[ii]){
return true;
}
}
}
You'll need a way to feed the blocked date from your backend to the client.
But let's suppose you solved that and have the dates in an array.
All you need to do then is to check if the date in in the array.
See e.g. here:
Checking if date belongs to array of dates
To get the invalid dates from the backend you could either put them in the script itself, of have the script fetch the to be blocked dates from the server using e.g. ajax.
Don't forget to revalidate on the server, never trust filtering in the clients to actually happen.

Using a funcCall that retrieves multiple fields

Ello, I'm using jQuery-Validation-Engine and i don't know if this is currently possible but, Is there a way for you to possibly use the funcCall in a senario such as this.
I have to check a date range using 2 textboxes. I want to bind funcCall[dateRangeCheck] in such a way that I can get access
to 2 fields as opposed to just the one. The end result would would something like this.
dateRangeCheck = function (fields, rules, i, options) {
if (isDate(fields[0]) && isDate(fields[1])) {
if (!dateCompare(fields[0], fields[1])) {
return "* Invalid Date Range";
}
}
};
Or possibly all the fields that a utilizing this particular funcCall like this
dateRangeCheck = function (fields, rules, i, options) {
for (var i=0;i<fields.length;i++)
if(!isDate(fields[i]){
return "* Invalid Date Range";
}
}
};
Is there some way to accomplish this?
Well now jQuery-validation-engine does support date range checking. Just made the commit myself waiting for it to be reviewed. lol, But no to that second example as of now.
Here is the source. Have a nice day.
Update
The latest version does support group validation.

String operations in Vista/W7 gadget's javascript

I experimenting with writing Vista/W7 gadgets. In my experiment I want to write the modification date of certain files on the system. Problem is that if I want use string manipulation functions the gadget just stops writing its output. Part of the gadget's code looks like this:
function format_lmd(lmd)
{
// Parse something like "Sun Aug 26 17:13:22 UTC+0200"
var lmdFields = lmd.split(' ');
//weekday = lmdFields[0];
//month = lmdFields[1];
//monthday = lmdFields[2];
//moment = lmdFields[3];
//return monthday+' '+month+' '+moment;
return lmd;
}
function paintGadget()
{
var fileitem = System.Shell.itemFromPath("c:\\myfile.txt");
//canvas.addTextObject(' '+fileitem.modifyDate, 'Segoe UI', 9, 'white', text_offset, 21);
var result = null;
result = ' ';
result += format_lmd(fileitem.modifyDate);
canvas.addTextObject(result, 'Segoe UI', 9, 'white', text_offset, 21);
}
The call to split (in the function format_lmd) seems to halt the script (or better: throw an exception). Although documentation seems to indicate that the split function can be used to split a string in multiple parts, it doesn't work in my case.
Questions:
How should I correctly use the split method?
I didn't use Javascript before so when to declare a variable with "var" and when not remains a mystery for me. Is there a good introduction to Javascript that can be used for gadgets?
What is the best way to debug a gadget?
Thanks,
Patrick
EDIT: I found out how to enable the debugger for Javascript (see http://msdn.microsoft.com/en-us/library/bb456467%28v=VS.85%29.aspx#_sidebar_overview_debugging_basic). A debug window now pops up and says "Object expected", but this doesn't really help me.
This is one of the major issues with the Windows Desktop Gadgets API and System.Shell namespace. Some of the commands return types that aren't handled natively by JScript. Fortunately, this isn't one of those times but the issue is similar. I'll get to the answer, but first, a bit of side-note rambling.
You noticed when checking typeof lmd in the function, "date" is the result. What's strange about this is that there is no native date type JScript/ECMAScript - typeof new Date() will result in "object". The reason for this is that many System.Shell.* methods are mapped to the .net equivalent methods and the result is just returned to the JScript with no effort to convert the data into a JScript native type. A very short-sighted implementation by Microsoft.
When outputting lmd to a debugger you'll see a string result, something like:
Wed Nov 25 11:06:30 UTC 2009
This is because a function that expects a string will convert a non-string argument to a string. System.Debug.outputString() is no exception here. Realizing this, the solution becomes clear - force the type conversion from "date" to a string:
var lmdFields = String(lmd.split(' '));
// or
var lmdFields = (lmd+"").split(' ');
//-> ["Wed","Nov","25","11:06:30","UTC","2009"]
If you want to convert the date to a JavaScript Date object, you can just pass it to the Date() constructor:
var lmdFields = new Date(lmd);
System.Debug.outputString(lmdFields.toLocaleString());
//-> "25 November 2009 11:06:30"
If its a Date then maybe this will help (not tested, but a guide)...
function format_lmd(lmd)
{
month = lmd.getMonth()+1; // returns numeric value
monthday = lmd.getDay(); // 0 for Sunday, 1 for Monday, 2 for Tuesday, and so on
// not sure what you mean for 'moment'?
return monthday+' '+month+' '+moment;
}
You could provide month and day values in an array and just look them up if you wanted.
Reference:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date#Methods

Categories

Resources