Sunday, June 8, 2014

working with JSON model dates in UI5

Update 2: Article now also available on SCN.
Update: included binding example.

Let's say you've designed an OData Service that returns an Entity with a Date-/Time-value (Edm.DateTime).
Let's also say that you're consuming the service with SAP UI5, particularly with the JSON Model (sap.ui.model.json.JSONModel).
And to top things off, you're binding that to a DateTime UI control (sap.m.DateTimeInput) to display a nice mobile datepicker.

Then you might have gone through a hell of a time already :)

No, seriously - making those three things play together nicely isn't difficult, but provides some obstacles. John Patterson has written an excellent article explaining the handling of OData DateTime with Gateway and UI5.
What didn't make it into the article was handling Edm.DateTime in the UI5 JSON model explicitly.

So off we go:

First, Gateway's Edm.DateTime are represented in the UI5 JSON Model as Strings à la
 /Date(1402166783294)/
This seems to represent a JavaScript timestamp object.
Strange?
Me thinks too.
But that's the way it is (with UI5 version 1.20.4 as of this writing at least).

Next, if you're trying to bind this to the DateTimeInput, this will fail - the UI control expects a JavaScript Date object: "Type Error: Expected JavaScript Date Object".

So the JSON model Date strings needs to be converted to a Date object at runtime in order to be usable in UI5 controls.

I've found two ways to do that.

The first extracts the numbers from the string, using them to construct a new Date object.

// this comes from SAP NW Gateway
// and is in the JSON model
var sJsonDate = "/Date(1402166783294)/";

var sNumber = sJsonDate.replace(/[^0-9]+/g,'');
var iNumber = sNumber * 1; //trick seventeen
var oDate = new Date(iNumber);
Attention: JS String.replace method returns a string that can't be used directly to construct a Date object. Multiplying it with 1 causes an implicit type cast to Integer - the latter goes directly into new Date() then.

The second way uses the RegExp object. With its exec Method, all content between the two "/" of the Date string are extracted - the resulting Date(1402166783294) is auto-assigned to RegExp.$1 and subsequently used for a new call.

// this comes from SAP NW Gateway 
// and is in the JSON Model
var sJsonDate = "/Date(1402166783294)/";
/\/(.+)\//.exec(sJsonDate);
var oDate = eval("new " + RegExp.$1);
Clue here is, that exec returns an Object - Date(1402166783294) resides in RegExp.$1 as an object representation. So with the help of eval(), it can directly be used with "new" for instantiating a Date object.

Both methods work: they result in converting the Gateway-JSON-Model "/Date(1402166783294)/" into its Date object representation, that can then be used for the sap.m.DateInput control.


var oDateTimeInput1 = new sap.m.DateTimeInput({
   dateValue: oDate,
   displayFormat: "MMM yyyy",
   valueFormat: "yyyy-MM-dd"
});

Let's combine this with the proper DateInput "type" property and UI5's binding and formatting API.
The dateValue property of the UI control is bound to the path "/date" of the JSON model. The value the JSON model injects then gets formatted with one of the above two snippets.

        var oData = {  
                date: sJsonDate 
        }; 
        var oJsonModel = new sap.ui.model.json.JSONModel(); 
        oJsonModel.setData(oData); 
        var oDateTimeInput3 = new sap.m.DateTimeInput({ 
            type: sap.m.DateTimeInputType.Date, 
            displayFormat: "dd - M - yy", 
            dateValue: { 
                path: "/date", 
                formatter: function(sDate) { 
                    if(sDate) { 
                        /\/(.+)\//.exec(sDate); 
                        return eval("new " + RegExp.$1); 
//                        var sNumber = sDate.replace(/[^0-9]+/g,''); 
//                        var iNumber = sNumber * 1; //trick seventeen 
//                        return new Date(iNumber); 
                    } 
                } 
            } 
        }); 
        oDateTimeInput3.setModel(oJsonModel);  

And that's it - a working DatePicker UI control, bound to a JSON model that holds values from a Gateway OData call.
Good karma all around.

Hint: both ways take < 1ms in execution time - so no performance gain possible here, use the possibility of your liking. 

A working example can be found on GitHub.

 

Friday, January 10, 2014

Apple Magic Mouse in Windows 8.1

Out of the box, pairing the magic mouse via bluetooth with the Windows 8.1 box works.
But scrolling by touch is missing.

So:

  • Download both Mouse Driver Installer and Mouse Utility Setup from http://trackpadmagic.com/magic-mouse/download
  • Run the Installer -> atencíon: the installer will download the 303 MB (!) Bootcamp 3.3
  • installer automatically extracts the magic mouse driver from the bootcamp exe 
  • Run the Setup -> will launch a GUI config utility also showing the battery status for the magic mouse
  • Pair magic mouse with Windows box via bluetooth (if paired previously, de-pair and re-pair)


Monday, December 2, 2013

Phonegap 3.2 + Windows Phone 8

Locally building Win Phone 8 apps in PhoneGap 3.2.0 with a non-English Windows version will currently always fail and deliver the following error:

>phonegap install wp8
[phonegap] detecting Windows Phone 8 SDK environment...

>phonegap local build wp8
[phonegap] adding the Windows Phone 8 platform...
<snip />
[error] Error while checking requirements: The command `msbuild` failed. Make
 sure you have the latest Windows Phone SDKs installed, AND have the latest .NET
 framework added to your path (i.e C:\Windows\Microsoft.NET\Framework\v4.0.30319
).

This is due to an insufficient regex in line 82 of
<$home>\.cordova\lib\wp\cordova\3.2.0\wp8\bin\check_reqs.js

var msversion = output.match(/Microsoft\s\(R\)\s+Build\sEngine\s[a-z]+\s4\.0\.30319/i);

The regex will match the string "Microsoft (R) Build Engine, Version 4.0.30319" - which is the output of msbuild from the command prompt on Windows Systems (with .NET 4 framework installed) with English locale only.
With German language setting, msbuild says:
Microsoft (R)-Buildmodul, Version 4.0.30319.33440

And that string the above regex will never match and always report that msbuild is missing - no matter whether .NET is installed or not.

Quick Fix: replace the above line with 
var msversion = output.match(/.NET\sFramework\,\s\w*\s4.0/);
This will at least match an installed .NET Framework in Version 4.

Proper Fix: I've reported both to the PhoneGap forum and community.phonegap.com (where they didn't want to see it). 








Thursday, June 20, 2013

Registration of phone number not possible for iMessage & Facetime

UPDATE: as of now (Jun 21, 9:00 am CET), phone# activation works again for both iMessage & Facetime. Didn't even have to re-enable any settings.

Just to jot this down, for Apple support or anybody else twisting their heads on the problem:

Currently (at least since 2 days ago, June 18, 2013) there seems to be a global issue with registering an iPhone's phone number for use in iMessage and Facetime: both screens remain in status "waiting for activation..." (German: "Auf Aktivierung warten...").
But: iMessage & Facetime both work fine with the Apple-ID.

Many similar complaints currently in the Apple Support Communities confirm the issue.
(Hint: this is on the latest and greatest iPhone 5 16 GB & iOS 6.1.4)


So...what gives?!?

Here's my chronology (all Pics in German, sorry):

Switching on iMessage & Facetime including Apple-ID usage shows the information expected:

But both status screens remain in "waiting for activation..." (German: "Auf Aktivierung warten...").
Also strange: since I switched SIM cards some days ago, my old phone number is still shown in the status screens, even though the phone itself works fine with the new number (both calls and SMS/text messages)!

Story gets even more funny: after yet another registration attempt on my side, I keep receiving text messages from the UK Apple Activation numer +44 7786 205 094. Not only 1, but at the time of this writing already 16 :)
Hint: the iPhone sends a silent SMS/text message to the above number on every activation try of iMessage and Facetime. This is not unusal. But receiving back not only one but many text messages is.
And by looking at the content of the message (hey, I'm a tech guy after all), it seems clear that it is a reply to an activation request:


And just for the record:






Wednesday, January 23, 2013

ZF2 with macports' ZendFramework2 port

Quick Handreichung how to set up the skeleton application Zend Framework 2 (ZF2) on OS X, using macports' distribution of ZF2. Otherwise you'd have to download/install ZF2 every time for every project - redundancy and version confusion ahoi.
The ZF2 skeleton application is a good starting point for your own ZF2 development.

Quick facts:

  • OS X 10.8
  • ZF2 2.0.6
  • PHP 5.3 (from macports - hint: will be installed anyway with macports' version of ZF2)
  • Apache 2.2.23 (from macports)


$> cd /opt/local/ww
$> sudo git clone git://github.com/zendframework/ZendSkeletonApplication.git zf2.git

$> tree zf2.git
zf2.git
├── LICENSE.txt
├── README.md
├── composer.json
├── composer.phar
├── config
│   ├── application.config.php
│   └── autoload
│       ├── README.md
│       ├── global.php
│       └── local.php.dist
├── data
│   └── cache
├── init_autoloader.php
├── module
│   └── Application
│       ├── Module.php
│       ├── config
│       │   └── module.config.php
│       ├── language
│       │   ├── ar_SY.mo
│       │   ├── ar_SY.po
│       │   ├── cs_CZ.mo
│       │   ├── cs_CZ.po
│       │   ├── de_DE.mo
│       │   ├── de_DE.po
│       │   ├── en_US.mo
│       │   ├── en_US.po
│       │   ├── es_ES.mo
│       │   ├── es_ES.po
│       │   ├── fr_CA.mo
│       │   ├── fr_CA.po
│       │   ├── fr_FR.mo
│       │   ├── fr_FR.po
│       │   ├── it_IT.mo
│       │   ├── it_IT.po
│       │   ├── ja_JP.mo
│       │   ├── ja_JP.po
│       │   ├── nb_NO.mo
│       │   ├── nb_NO.po
│       │   ├── nl_NL.mo
│       │   ├── nl_NL.po
│       │   ├── pl_PL.mo
│       │   ├── pl_PL.po
│       │   ├── pt_BR.mo
│       │   ├── pt_BR.po
│       │   ├── ru_RU.mo
│       │   ├── ru_RU.po
│       │   ├── tr_TR.mo
│       │   ├── tr_TR.po
│       │   ├── zh_CN.mo
│       │   ├── zh_CN.po
│       │   ├── zh_TW.mo
│       │   └── zh_TW.po
│       ├── src
│       │   └── Application
│       │       └── Controller
│       │           └── IndexController.php
│       └── view
│           ├── application
│           │   └── index
│           │       └── index.phtml
│           ├── error
│           │   ├── 404.phtml
│           │   └── index.phtml
│           └── layout
│               └── layout.phtml
├── public
│   ├── css
│   │   ├── bootstrap-responsive.min.css
│   │   ├── bootstrap.min.css
│   │   └── style.css
│   ├── images
│   │   ├── favicon.ico
│   │   └── zf2-logo.png
│   ├── index.php
│   └── js
│       ├── bootstrap.min.js
│       ├── html5.js
│       └── jquery.min.js
└── vendor
    ├── README.md
    └── ZF2


Note the vendor/ZF2 directory above - comes in empty.

$> sudo port install ZendFramework2
--->  Computing dependencies for ZendFramework2
   <snip />
--->  Cleaning ZendFramework2
--->  Scanning binaries for linking errors: 100.0%
--->  No broken files found.

Now comes the the important part: linking macports' ZF2/library to the actual ZF2-directory of the git repository.

$> cd /opt/local/www/zf2.git/vendor/ZF2
$> sudo ln -s /opt/local/www/ZendFramework/library
$> ls -al

total 8
drwxr-xr-x  3 root  admin  102 23 Jan 16:04 .
drwxr-xr-x  5 root  admin  170 23 Jan 16:02 ..
lrwxr-xr-x  1 root  admin   36 23 Jan 16:04 library -> /opt/local/www/ZendFramework/library

Configure /opt/local/www/zf2.git/public to be the DocumentRoot of your local webserver and you should see ZF2's starting screen.

Ta-Ta!!!

OS X 10.8: remove HTML formatting in messages.app for ICQ/AIM

Handlungsanweisung on how to remove the awkward HTML formatting that messages.app on OS X 10.8 (Mountain Lion) produces for ICQ or AIM accounts:

  1. quit messages.app
  2. open terminal.app
  3. if ~/Library/Preferences/com.apple.iChat.AIM.plist.lockfile exists,
    rm ~/Library/Preferences/com.apple.iChat.AIM.plist.lockfile
  4. in terminal.app, 
    open ~/Library/Preferences/com.apple.iChat.AIM.plist
  5. (XCode will start)
  6. Locate ICQ Account under root -> Accounts and set 
    ForceICQPlainText to YES
  7. File -> Save
  8. Reboot!
    Yes, seriously, boot your box. I know, feels strange on OS X.
    But if you start messages.app before rebooting, the setting above will not be saved. And you have to start over (-> goto 1.) again.
Now, happy plaintext ICQing.

Wednesday, September 19, 2012

LyX missing shortcuts

Update:
#insert Lyx note is also quite helpful

#⌥⌘n
\bind "C-A-n" "note-insert"


Here are my top 3 keyboard shortcuts that are missing in LyX's standard settings:

#insert reference (de: "Einfügen -> Querverweis")
#⌥⌘R
\bind "C-A-r" "dialog-show-new-inset ref"

#insert label (de: "Einfügen -> Marker")
#⌥⌘M
\bind "C-A-m" "label-insert"

#citation (de: "Einfügen -> Literaturverweis")
#⌥⌘Z
\bind "C-A-z" "citation-insert"

Being on a Mac, place them as user.bind in  ~/Library/Application Support/LyX-2.0/bind/
Restart LyX and off you go, saving yourself them awkward mouse-clicks.