Planet FoxPro

March 03, 2015

VisualFoxProWiki

UpcomingEvents

Editor comments: Philly March
A place to list upcoming Visual FoxPro events like conferences, meetings, user groups, open training sessions...
Closest at the top please, and please remove past events.

March 03, 2015 09:58 PM

VFP Philly

March 10: Bill Fitzgerald on SQL Server Reporting Services



Our next meeting will be Tuesday, March 10 at 7 PM.

Member Bill Fitzgerald will present “SSRS 101: SQL Server Reporting System for beginners”:

SSRS – SQL Server Reporting System has been evolving quietly over the past decade and has now emerged as Microsoft’s preferred tool for preparing and displaying database reports. It is the default reporting system for SQL Server and .NET, and also is a powerful standalone report generator. At the same time there has been a decline in the support for the  integration of Crystal Reports with .NET, creating a need that Microsoft has moved to fill.

SSRS is well supported, there are many tutorials available and perhaps most important for some of us – it’s free!

This presentation will look at SSRS from a VFP programmer’s point of view and show how one VFP programmers made the journey to learning enough about SSRS to do most of the things we do with the VFP report writer. (Alas- not all- but most.) It will also show a few things that can’t be done with the VFP report writer.


 

by Tamar E. Granor (noreply@blogger.com) at March 03, 2015 09:44 PM

Alex Feldstein

Photo of the Day


Cushman Eagle (1957)
2015 Dania Vintage Motorcycle Show

by Alex Feldstein (noreply@blogger.com) at March 03, 2015 06:00 AM

March 02, 2015

Alex Feldstein

Sandstorm's Blog (Home of ssClasses)

Fake Checkbox on Grid

As most of my posts, this one also comes from a need of a member inside Foxite forum.  His desire is to have a uniquely looking checkbox and so my advice is to utilize two images representing checkboxes, one that is ticked and the other not ticked.  Then to manipulate viewing of the image via  DynamicCurrentControl.



In my mind, even without testing yet, I believe it will work good.  But I was notified later that that trick requires two clicks and so I tested and it did needs two clicks as follows:

1st click - to set focus and activate the cell
2nd click onwards - actual toggling of the underlying logical field

And I agree that if we can get around the issue of the first click, then that would be better.  However, I cannot find a property or event  to activate a cell using click and then perform click on the image as well in one go.  But believing  there is always a way, I tried other ideas.  And as I found a way, then here it is again, maybe you'll need something like this:



loTest = Createobject("Sample")
loTest.Show(1)

Define Class Sample As Form
      Caption = 'DynamicCurrentControl'

      Add Object grid1 As Grid With ColumnCount = 2


      Procedure Load
      Create Cursor junk (x C(1), Y l)
      For lnloop = 1 To 26
            Insert Into junk Values (Chr(m.lnloop+64),.F.)
      Next
      Go Top
      Endproc

      Procedure grid1.Init
      Local lcImage, lcFile
      With This
            .RecordSourceType= 1
            .RecordSource='junk'
            .Column1.ControlSource = 'junk.x'

            With .Column2
                  .ControlSource='junk.y'
                  .AddObject("ImgChk","MyImage")
                  .AddObject("ImgNoChk","MyImage")
                  .Width = 24
                  With .imgChk
TEXT TO lcImage NOSHOW
/9j/4AAQSkZJRgABAAEAYABgAAD//gAfTEVBRCBUZWNobm9sb2dpZXMgSW5jLiBWMS4wMQD/2wCEAAgFBgcGBQgHBgcJCAgJDBQNDAsLDBgREg4UHRkeHhwZHBsgJC4nICIrIhscKDYoKy8xMzQzHyY4PDgyPC4yMzEBCAkJDAoMFw0NFzEhHCExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMf/EAaIAAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKCwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+foRAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/AABEIABIAFQMBEQACEQEDEQH/2gAMAwEAAhEDEQA/APVvEmtatD4it9H0eTTbXNm93Nc36O6gB0QKArLgkt1J/CgDG8WeJfE3hG0gudUv9DuJLiUQ21lbWM3n3TkgBEzKcHnqRge/AIB0HgG81DU9BXU9UvY7ia8dnEUKBYrYAlfLU4y2CDliTk9MDFAGP4o03TtZ8ef2VrKo1neaDNG6swXP7+M5B9QcEHscUAcz8NPAd/p3iy41Txjqw1IaODaaM00wf9318zGeODtHoc+goA7X4UEHwDppUggmYgjoR5z80Abmr6LpWsJGur6ZZ36xElBdQJKEJ643A4oAzP8AhCPCf/Qr6J/4L4v/AImgDft4YraCOC3iSGGNQqRooVVA6AAdBQB//9k=
ENDTEXT
                        lcFile = Addbs(Getenv("TEMP"))+"check"
                        Strtofile(Strconv(m.lcImage,14),m.lcFile)
                        .Picture = m.lcFile
                        .Visible = .T.
                  Endwith

                  With .imgNoChk
TEXT TO lcImage NOSHOW
/9j/4AAQSkZJRgABAQEAYABgAAD//gAfTEVBRCBUZWNobm9sb2dpZXMgSW5jLiBWMS4wMQD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAASABUDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9Wv2jfj18Xbn9rzwx8HvhIfh3o9/eeEb7xhqmseLdOvdSiEMN5aWqW0UNtPblHdpyxkeQ8KcRnFUte0X9s3wb4e1DWINe/Z98Wz6ZBPdR+H9L8Kanp95rJRWZLWG6udVaGCWXGxXlXy42cFtyKQYPFHiKx8Nf8Fo/DD6jeW2nxT/BjVkjaaVIlkI1zTmblvvAbl5/hLgfxV9Ot8RvDynB17Rgdu7/AI/Ys4zjP3umePrQB59+xR+0Te/tPfsueDPHGqWmj2Ora5YZ1G3027kuLO3vIpZILiOKV0XeqyxOMjcOOGddrsV5L/wRVu7d/wDgmX8N5EuY/Jlm1ho5IfuTL/bF7hh9RRQB7Z8Wv2ZPht+0rZafB8Rvh74H8fwaXdXDWcfiTQrXVUtCWYExidHCEgAHbjOBXB/8Osv2Yv8Ao3L4D/8AhAaT/wDGKKKAPbPAvhnTfBnhbTdJ0fT7HSdK06zigtbOzgSC3to1BCokaAKqgdAAAKKKKAP/2Q==
ENDTEXT
                        lcFile = Addbs(Getenv("TEMP"))+"Nocheck"
                        Strtofile(Strconv(m.lcImage,14),m.lcFile)
                        .Picture = m.lcFile
                        .Visible = .T.
                  Endwith

                  .DynamicCurrentControl='IIF(junk.y=.F.,[ImgNoChk],[ImgChk])'
                  .Sparse = .F.

            Endwith
            .RowHeight = 22
      Endwith
      Endproc

      Procedure grid1.AfterRowColChange
      Lparameters nColIndex
      If This.ActiveColumn = 2
            Replace Y With !Y In junk
      Endif

Enddefine

Define Class MyImage As Image
      Procedure Click
      Replace Y With !Y In junk
      Endproc
Enddefine


The final trick on the single click need, if you have not noticed, lies on usage of the AfterRowColChange event of the grid. Hope this helps!  Cheers!

by Jun Tangunan (noreply@blogger.com) at March 02, 2015 04:26 AM

March 01, 2015

VisualFoxProWiki

Federatedwiki

Editor comments: To be continued To be continued To be continued
I wonder if someone knows what has happened at C2.com. No one can edit pages anymore.

Ward Cunningham is into Federated Wikis now. See https://github.com/fedwiki for its code and project, and http://fed.wiki.org/ to see one live. He has shut down editing his C2 wiki ( http://c2.com/cgi/wiki ) because it had run its course. Here's a Javascript Jabber podcast episode that I found interesting. I don't "get" Ward's implementation of wiki federation in its current form. I can barely use it. -- Steven Black February 28, 2015

Thanks for the info, fellow Canadian Steven (I am from Montreal). I clicked on the links you gave me and I couldn't make sense of this federated wiki business. Nothing new under the sun! Ward never had the word user-friendly in his dictionary! GUIs are definitely not his forte but he's generally a heck of a programmer! -- Robert Abitbol February 28, 2015

I listened to the whole show. No one in the panel understood was Ward was talking about. Ward was always like that: He always poses as an inventor, a genius of sorts but he comes up with silly stuff. He had this programming game going on. It was called ultra-programming or something like that. Programmers were looking in each other's eyes. They were playing cards. It was kid stuff. -- Robert Abitbol February 28, 2015

He came up with the wiki concept before everyone else. That was the only good thing he came up with. Hundreds of people had the idea of sets of pages people would collaborate on but Ward rushed to implement his concept on internet before everyone else. He just won the race -- Robert Abitbol February 28, 2015

One thing I like about him however is the fact that at least he tries to invent things, he tries to go forward. But I never thought much of his so-called inventions. I never thought the man understood human nature, the need for clarity. He is right the opposite of myself: I understand people very well, my inventions are useful, simple, easy to understand. -- Robert Abitbol February 28, 2015

I am certainly not as efficient as he is in publicity stunts however... -- Robert Abitbol February 28, 2015

I came here on this very site around 2004 or perhaps later and I had right away the feeling that this was the most user-friendly wiki I had ever seen. Ward was incapable of designing a user-friendly wiki. The guy who did Usemod designed the first good wiki interface. Usemod has taken ward's engine written in Perl. -- Robert Abitbol February 28, 2015

However Ward came up with a great Differences function (Diffs). His linked pages concept is excellent. But all the other improvements have been made by Media wiki which is in excellent wiki. -- Robert Abitbol February 28, 2015

OK NOW I GET IT!

As usual Ward was never able to explain things simply. He comes up with fancy explanations in order to make a simple conceot sound like something cosmic, out of this world.

Before I explain it,let me say that this in a great idea.

Now here is how this whole thing works.

Click here: http://don.fed.wiki.org/view/time-again-for-wiki-mutiny/view/robert-abitbol

Now click on the first hyperlink you'll see in the text. It is: forecastle council. What happens then? A page called Forecastle Council opens on the right of the page. Click on + and a paage explaining the forecastle council concept. You apparently can use a set of tools on the right hand page.

In other words, a bunch of wikis are connected

When you read a page located on the left of the screen and you click on a link it will show you contents of page X . If a page called X exists on other wikis, its contents will open on the left page.

Now do you remember the links you had to other wikis on C2.com? I am talking about the link to the same page on what was called sister sites? Well it is the same concept except this: you had to click on each link on each page one by one to get the contents and now the software does it for you.

It is not at all a bad idea. It is sort of an enriched blog concept.

March 01, 2015 11:26 PM

Alex Feldstein

Photo of the Day


1911 Pierce Arrow motorcycle lamp
2014 Dania Vintage Motorcycle Show

by Alex Feldstein (noreply@blogger.com) at March 01, 2015 06:00 AM

VisualFoxProWiki

MemoriesofC2.com,thefirstwiki

Editor comments: Moved text from my own page Minor changes Link to Ward's article the grammar vandal
C2.com was a great experiment

It was like a jungle where might was making right. There was no respect, no rules, no leadership. It was complete anarchy. You can't run any organization without any form of coercition, punishment, without rules of any kind. Look at the way forums operate: If you don't behave properly you're banned for 3 days, a month, 3 months and so on. Not on C2.com. There were virtual thugs, a virtual mafia, virtual bullying... I was playing the virtual righter of wrongs; I was protecting the virtally bullied wikizens... -- Robert Abitbol February 28 2015

I heard that in the last days of C2.com, no one was posting there any more. Why is that? -- Robert Abitbol February 28 2015

I was sure then that sometimes in the future, C2 wiki would have to close for one simple reason: Ward Cunningham was always a terrible manager for he could not see clear in people and he could not listen to good advice. He had a sure recipee for catastrophe. It's as simple as that. -- Robert Abitbol February 27 2015

I think he simply did not understand the need to establish rules, a voting system, a sort of democracy. Things got worse and worse and he had to close. Wnen did the editing close on c2.com. who wrote the last post? -- Robert Abitbol February 28 2015

Jumbo Wales on the other hand is a great manager and look at the amazing results: Wikipedia. -- Robert Abitbol February 27 2015

I believe that Jumbo Wales did not give his founding partner, or his employee, the credit he deserved and he had to leave. This is pretty unfortunate. Clash of the egoes. We had a lot of that on C2. I've always said it was a jungle. -- Robert Abitbol February 28 2015

March 01, 2015 04:47 AM

Federatedwiki

Editor comments: Stuff moved from my homepage Minor changes
I wonder if someone knows what has happened at C2.com. No one can edit pages anymore.

Ward Cunningham is into Federated Wikis now. See https://github.com/fedwiki for its code and project, and http://fed.wiki.org/ to see one live. He has shut down editing his C2 wiki ( http://c2.com/cgi/wiki ) because it had run its course. Here's a Javascript Jabber podcast episode that I found interesting. I don't "get" Ward's implementation of wiki federation in its current form. I can barely use it. -- Steven Black February 28, 2015

Thanks for the info, fellow Canadian Steven (I am from Montreal). I clicked on the links you gave me and I couldn't make sense of this federated wiki business. Nothing new under the sun! Ward never had the word user-friendly in his dictionary! GUIs are definitely not his forte but he's generally a heck of a programmer! -- Robert Abitbol February 28, 2015

I listened to the whole show. No one in the panel understood was Ward was talking about. Ward was always like that: He always poses as an inventor, a genius of sorts but he comes up with silly stuff. He had this programming game going on. It was called ultra-programming or something like that. Programmers were looking in each other's eyes. They were playing cards. It was kid stuff. -- Robert Abitbol February 28, 2015

He came up with the wiki concept before everyone else. That was the only good thing he came up with. Hundreds of people had the idea of sets of pages people would collaborate on but Ward rushed to implement his concept on internet before everyone else. He just won the race -- Robert Abitbol February 28, 2015

One thing I like about him however is the fact that at least he tries to invent things, he tries to go forward. But I never thought much of his so-called inventions. I never thought the man understood human nature, the need for clarity. He is right the opposite of myself: I understand people very well, my inventions are useful, simple, easy to understand. -- Robert Abitbol February 28, 2015

I am certainly not as efficient as he is in publicity stunts however... -- Robert Abitbol February 28, 2015

I came here on this very site around 2004 or perhaps later and I had right away the feeling that this was the most user-friendly wiki I had ever seen. Ward was incapable of designing a user-friendly wiki. The guy who did Usemod designed the first good wiki interface. Usemod has taken ward's engine written in Perl. -- Robert Abitbol February 28, 2015

However Ward came up with a great Differences function (Diffs). His linked pages concept is excellent. But all the other improvements have been made by Media wiki which is in excellent wiki. -- Robert Abitbol February 28, 2015

March 01, 2015 02:46 AM

February 28, 2015

VisualFoxProWiki

Alex Feldstein

February 27, 2015

Calvin Hsia's WebLog

Call C# code from your legacy C++ code

For many decades, folks have been quite productive in creating C++ code. These “legacy” apps have been quite useful. However, as most software developers know, software needs to be maintained. Business needs change, and the applications need to change...(read more)

by CalvinH at February 27, 2015 09:37 PM

Alex Feldstein

February 26, 2015

Rick Strahl's Web Log

Using FontAwesome Fonts for HTML Radio Buttons and Checkboxes

Creating nice looking checkboxes and radio buttons in browsers is still kind of a pain. If you want to have spruce up checkboxes and radios in your Web applications and don’t want to rely on the crappy and differing implementations in various browsers, you have to take things into your own hands. In this post I’ll show how to use FontAwesome symbols for radio button and checkbox selectors.

I originally had been using background images for my radio buttons, which looked alright but I found out that the images would not print properly. I needed another solution so I started looking around to see if I could use FontAwesome fonts and of course you can. I found a few examples, but as is often the case there were a few complications and a few additions I had to make. This post covers all the issues I ran into.

What’s wrong with checkboxes and radio buttons?

Currently I’m working on an application that has a lot of surveys so it consists of a tons of radio buttons and checkboxes and I wanted to have a nicer and more bold look to them than the boring plain form interface provided in browsers.

For example here’s the default look for radio buttons in Chrome:

DefaultRadios

While that doesn’t look too bad the interface does vary quite a bit depending on which browser you’re using. Internet Explorer uses white background and solid highlights, FireFox uses something similar but has a particularly ugly highlight. On the Mac things look completely different and mobile apps have yet a completely different look that often doesn’t jive well with an HTML design.

Often it’s nice to have consistent look for the application regardless which device or browser it’s running and customizing checkboxes and radio buttons is one way to keep the look and feel the same across browsers and devices.

FontAwesome is Awesome

If you haven’t looked at FontAwesome before, definitely make it a point to take a look. I’ll wait here.

FontAwesome is essentially the WingDings for the Web with over 500 symbols in its font repertoire that you can easily use in a Web page by using a simple <i> or <span> tag.

A FontAwesome symbol can be embedded into text or buttons and menu pats and it’s a super easy way to add some basic imagery to your application if you don’t have designated designers creating artwork for you. To embed a symbol is as easy as:

<i class="fa fa-fw fa-envelope"></i>

or:

<button type="submit" name="btnSubmit" id="btnSubmit"
        class="btn btn-primary"
        value="SIGN IN">
    <i class="fa fa-lock"></i> SIGN IN
</button>

All sorts of common icons are provided for typically business applications and application tasks. You can even combine symbols and create animated symbols that make it super easy to create action indicators for things like downloads for example.

FontAwesome and Radios and CheckBoxes

FontAwesome also includes a few different symbols for handling checkboxes and radio buttons. Below is the same form shown above created with FontAwesome symbols for the radio buttons.

FontRadioButtons

Here’s the same application form on Safari on an iPhone:

iphoneradios

As you can tell it looks the same rather than using the iPhone’s custom radios which in this case is desirable.

People have been using tricks to use custom content for checkboxes and radio buttons for a while. The way this ‘trick’ works is by essentially hiding the checkbox itself, and injecting extra content in its place. You can use either static content you put into the page, or as I’ll do here, use the CSS :before selector to force extra content into the page.

One of the advantages of using fonts over images is that you’re likely already using some sort of font library like FontAwesome (or Bootstraps glyphicons) for icons, so you get the ‘images’ for free. Fonts can also resize themselves with the documents/element’s font-size so you don’t have to worry about scaling issues - as shown in the iPhone screen shot which uses a smaller font for the phone media query. If you use images you’d have to resize the image.

Yesterday I ran into a CodePen from James Barnett that shows the basics of how to use FontAwesome symbols for checkboxes which gave me a good start for my project. I ended up tweaking the original code a little and adding keyboard support after some discussions on Twitter with a few folks, so I decided to put this all together into a short blog post.

Radio Buttons

The following is the CSS used to set up the radio buttons.

Please note that I use an explicit .with-font class here to specify which radio buttons to apply this styling to so I can control which radio buttons get this treatment. If you want to do this globally just remove the .with-font class, but I recommend not to because the styling has a few requirements. This code requires a radio button that is immediately followed by the display label for the radio. If the label is not there and not immediately following the checkbox you get a missing checkbox – not desirable.  Hence I want to be explicit about it.

Here’s the CSS:

input[type=radio].with-font { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; } input[type=radio].with-font + label:before { font-family: FontAwesome; display: inline-block; content: "\f1db"; letter-spacing: 10px; font-size: 1.2em; color: #535353; } input[type=radio].with-font:checked + label:before { content: "\f00c"; font-size: 1.2em; color: darkgreen; letter-spacing: 5px;
width: 35px: 5px; } input[type=radio].with-font:focus + label:before { font-weight: bold; color:orange; }

The CSS first hides the original checkbox using some tricky code from Html BoilerPlate (.visuallyhidden) that leaves the checkbox hidden but alive for focusing and keyboard navigation (thanks to @James_M_South for the tweak) . This is so that we can still focus the control which is handled by the last CSS style that changes the color of the control using the checkbox’s :focus pseudo selector. The second and third sections basically ‘inject’ the symbol using the :before pseudo selector which allows inserting for content before the selected control. Here the font-awesome fa-circle-thin and fa-check symbols are injected using their character codes. The checkmark is displayed with a green color to make it stand out.

So now to use this CSS all I have to do now is add the with-font CSS class to a radio button. Here’s what this radio button markup looks like as part of an Angular JS form that displays all the quiz questions in the code above:

<div class="question-body"
     ng-class="{ 'not-answered': !question.Selection, 'answered': question.Selection}">

    <div class="question-item" ng-repeat="choice in question.Choices">
        <input class="quizquestionchoice with-font"       
                id="Quiz_Questions_{{$parent.$index}}__Selection_{{$index}}"
                name="Quiz.Questions[{{$parent.$index}}].Selection"
                type="radio"
                ng-value="choice.Value"
                ng-model="question.Selection"
                required />
        <label for="Quiz_Questions_{{$parent.$index}}__Selection_{{$index}}"                           
                class="css-label" style="display: inline-block">{{choice.Text}}</label>
    </div>
</div>

Checkboxes

Checkboxes are really very similar to radio buttons, so you can use essentially the same code – just change the type to checkbox and change the symbols to reflect checkboxes. Here’s the checkbox CSS that I use:

input[type=checkbox].with-font {
    border: 0;
    clip: rect(0 0 0 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px; 
}    
input[type=checkbox].with-font + label:before {
    font-family: FontAwesome;
    display: inline-block;
    content: "\f096";
    letter-spacing: 10px;
    font-size: 1.3em;
    color: #535353;
}
input[type=checkbox].with-font:checked + label:before {
    content: "\f046";        
    color: darkgreen;
    letter-spacing: 5px;
}
input[type=checkbox].with-font:focus + label:before {
    font-weight: bold;
    color: orange;
}

Here’s what the checkbox looks like when checked:

Checkbox

Accessibility

I was originally pointed at this approach by a CodePen entry I found online that outlines the basic idea I described above. But as James South pointed out quickly after I posted a link to it on Twitter:

MakeItAccessible

The accessibility of the original example is lacking severely – there’s no keyboard navigation or visual indicator of the selected checkbox. The original code simply hid the original checkbox, which gives the right visual appearance for using a mouse and touch device, but does not provide for keyboard navigation.

I made a few tweaks to code to visually hide the control but effectively leaving it active so that a screen reader can still ‘see’ the control. I initially used a Width of 1px and overlaid the checkbox/radio ontop of the little visible pixel. James replied with a better way using this:

input[type=checkbox].with-font {
    // using Html Boiler Plate .visuallyhidden code
    border: 0;
    clip: rect(0 0 0 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px; 
}    

And that works without any visual debris. Incidentally I’m glad this came up – I’ve used a number of different tricks to make invisible but not hide elements and this code should come in real handy for other things. Thanks James!

The other lucky side effect of leaving the control visually hidden is that you still get focus events that fire on the control so you can use CSS to hook up the :focus selector to highlight the injected content. When using the first example you can tab through the list of radio buttons and the set of radios that’s selected will be highlighted in orange. Yay!

ASP.NET MVC

While my original use case was for the quiz questions and radios in my Angular front end code I ran into some problems with some MVC Razor code. For example on the login form I originally had this Razor code:

@Html.CheckBoxFor(mod => mod.RememberMe, new {@class="with-font"})
<label for="RememberMe">Remember me on this device</label>

Unfortunately that didn’t work and the form came up without a checkbox. Why? Because MVC’s HTML helpers for checkboxes and radios create hidden fields that look like this:

<input class="with-font" id="RememberMe" name="RememberMe" type="checkbox" value="true">
<
input name="RememberMe" type="hidden" value="false"> <label for="RememberMe">Remember me on this device</label>

Notice the hidden field injected in the middle which breaks the CSS selector that finds the label:

input[type=checkbox].with-font + label:before {

This selector looks for the immediate next sibling and expects a label but unfortunately there isn’t one. So the + isn’t going to work. Instead we could use the ~ selector instead and force the checkbox and label to be in their own DOM tree, which is pretty common. In my case I’m using BootStrap anyway so I have:

<div class="form-group" style="margin-left: 5px;">
    @Html.CheckBoxFor(mod => mod.RememberMe, new {@class="with-font"})
    <label for="RememberMe">Remember me on this device</label>
</div>

and for this the ~ selector works fine. I can change the checkbox selectors to:

input[type=checkbox].with-font {
    border: 0;
    clip: rect(0 0 0 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px; 
}    
input[type=checkbox].with-font ~ label:before {
    font-family: FontAwesome;
    display: inline-block;
    content: "\f096";
    letter-spacing: 10px;
    font-size: 1.3em;
    color: #535353;
}
input[type=checkbox].with-font:checked ~ label:before {
    content: "\f046";        
    color: darkgreen;
    letter-spacing: 5px;
}
input[type=checkbox].with-font:focus ~ label:before {
    font-weight: bold;
    color: orange;
}

with the explicit understanding that checkbox and label need to isolated.

The other alternative is to simply skip the Html Helper and just use raw HTML:

<div class="form-group" style="margin-left: 5px;"> <input type="checkbox" name="RememberMe" id="RememberMe" value="true" class="with-font" checked="@(Model.RememberMe)"/> <label for="RememberMe">Remember me on this device</label>
<input name="RememberMe" type="hidden" value="@(Model.RememberMe)">
</div>

Ugly but it works.

Consolidating

Now that you can see how using fonts for checkbox and radio indicator works, here’s a more consolidated version that handles both with a little less CSS code:

input[type=radio].with-font,
input[type=checkbox].with-font {
    border: 0;
    clip: rect(0 0 0 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;
}
    
input[type=radio].with-font ~ label:before,
input[type=checkbox].with-font ~ label:before {
    font-family: FontAwesome;
    display: inline-block;
    content: "\f1db";  /* fa-circle-thin */
    letter-spacing: 10px;
    font-size: 1.2em;
    color: #535353;
    width: 1.4em;   /* reduce bounce */
}
input[type=radio].with-font:checked ~ label:before,
input[type=checkbox].with-font:checked ~ label:before  {
    content: "\f00c";  /* fa-check */
    font-size: 1.2em;
    color: darkgreen;
    letter-spacing: 5px;
}
input[type=checkbox].with-font ~ label:before {        
    content: "\f096";  /* fa-square-o */
}
input[type=checkbox].with-font:checked ~ label:before {
    content: "\f046";     /* fa-check-square-o */   
    color: darkgreen;
}
input[type=radio].with-font:focus ~ label:before,
input[type=checkbox].with-font:focus ~ label:before,
input[type=radio].with-font:focus ~ label,
input[type=checkbox].with-font:focus ~ label
{                
    color: green; /* highlight both box and label */
}

So there you have it. FontAwesome checkboxes and radio buttons are pretty sweet and pretty easy once you have some simple boilerplate CSS in place…

Resources

© Rick Strahl, West Wind Technologies, 2005-2015
Posted in CSS  ASP.NET  HTML5  

by Rick Strahl at February 26, 2015 12:29 PM

Alex Feldstein

February 25, 2015

Beth Massi - Sharing the goodness

Understanding .NET 2015

Last year after BUILD I posted Exciting Times for .NET and since then I have had the pleasure of working much closer with the .NET team, which includes the runtime, framework, languages & compilers. Although my focus has been a lot more on internal community in the last year, such as helping run internal conferences for our field employees, I’ve also spent time helping get the .NET Foundation off the ground and learning a lot about open source communities and all our .NET Foundation projects. Oh right, I also got married. :-) It’s been a transition period for me. Going from community “evangelist” to more of a “facilitator” or “connector”.  I really like Alex Hillman’s term: Tummler.

Now that we’re approaching the next BUILD, I’m even more excited about the progress we’ve been making, particularly around the .NET platform itself, and the team’s approach to open source. There are multiple tracks of .NET innovations happening so I thought I’d write a high-level “sign-post” style blog post to help people understand the major pieces and how and where to get involved with the projects. In other words, a good place to start learning about .NET 2015. At least that’s my hope!

.NET 2015 – 10,000 foot view

At a very high level, here’s the rundown of the major components that fall under the “.NET 2015” umbrella.

image

It’s important to note that there are three key investment areas for .NET Core that influence the development of the major components.

  1. .NET Innovation – bring the platform forward and innovate. We’re modernizing every layer including the languages, compilers, base class libraries, app models, runtimes and tools.
  2. Open Source – bring our engineering processes out in the open and develop with the help and support of the community, fostering a vibrant .NET ecosystem.
  3. Cross platform – expand .NET to the Linux and Mac platforms because our customers are operating in increasingly heterogeneous environments.

Major components of .NET 2015

Frameworks and Runtimes

The .NET Framework is a managed execution environment that provides a variety of services to its running applications. It consists of two major components: the common language runtime (CLR), which is the execution engine that handles running applications; and the .NET Framework Class Library, which provides a library of tested, reusable code that developers can call from their own applications.

.NET Framework 4.6 builds upon 4.5.2 and contains new APIs, improvements to event tracing, and many bug fixes. This is the next version of the full .NET Framework we know today. .NET Framework 4.6 will be included in Windows 10 and will also ship on Windows Update for previous OSes (Vista and above). See: .NET Framework 2015 Preview

.NET Core 5 is a general purpose, modular framework that can be used across a wide variety of app models and platforms, is available as open source, can be deployed modularly & locally (side-by-side), and will be supported by Microsoft on Windows, Linux and Mac OSX. It is a refactored set of base class libraries (corefx) and runtime (coreclr) which includes a new JIT compiler (“RyuJIT”), the .NET Garbage Collector, native interop and many other .NET runtime components. Today, .NET Core builds and runs on Windows. We are adding Linux and Mac implementations of platform-specific components over the next few months. See: Introducing .NET Core and CoreCLR is now Open Source.

If you click only one link from this post, make sure it is Introducing .NET Core. Immo goes into great detail explaining the reasons why we need it and how it fits.

Compilers

The .NET Compiler Platform ("Roslyn") provides open-source C# and Visual Basic compilers with rich code analysis APIs. It enables building code analysis tools with the same APIs that are used by Visual Studio. Roslyn produces platform independent Intermediate Language (IL) and is used when building against .NET 2015, including Framework and Core. At release, the entire .NET Framework will be compiled using Roslyn. There are also key language innovations in both VB and C#. See: Roslyn on GitHub. There are also innovations happening with F# language and compiler. See F# on GitHub.

“RyuJIT” is the new default just-in-time (JIT) compiler for .NET on x64. The JIT compiler takes IL and compiles it for the particular machine architecture the first time it is executed at run-time. Used for desktop and server-based scenarios, RyuJIT is an overhaul of the previous 64-bit JIT compiler that significantly reduces startup times. It also includes support for SIMD (single instruction, multiple data) which allows mathematical operations to execute over a set of values in parallel. This can offer a profound speed-up to certain types of apps that rely on vector operations. See: The next-generation JIT compiler for .NET

.NET Native compiles C# to native machine code that performs like C++, so developers continue to benefit from the productivity and familiarity of the .NET Framework with the performance of native code. Typically, apps that target .NET are compiled to intermediate language (IL). At run time, the just-in-time (JIT) compiler translates the IL to native code. In contrast, .NET Native is an ahead-of-time compiler that compiles apps directly to native code and contains a minimal CLR runtime. Popular Windows Store apps start up to 60% faster and use 15-20% less memory when compiled with .NET Native. Universal Windows apps will run on .NET Native (ARM, x86, x64). See: Compiling Apps with .NET Native

App Models

App models extend the common libraries of .NET Framework 4.6 and .NET Core 5. Windows Forms, WPF, ASP.NET Web Forms, MVC 5, etc., app models that you are familiar with today are part of the .NET Framework 4.6, come with many new features, as well as benefit from the new innovations in the languages, Roslyn compiler, and RyuJIT. There’s a lot happening on the .NET 4.6 stack. See: ASP.NET Overview – What about Web Forms?, The Roadmap for WPF and .NET Framework 2015 Preview

Additionally, there are new app models that are designed to run on the optimized .NET Core 5.

ASP.NET 5 is a lean .NET app model for building modern web apps. It was built from the ground up to provide an optimized development framework for apps that are either deployed to the cloud or run on-premises. It consists of modular components with minimal overhead, so you retain flexibility while constructing your solutions. ASP.NET 5 can run on top of .NET Framework 4.6 or .NET Core 5. Today, ASP.NET 5 uses the Mono runtime to run on Linux and Mac. Once .NET Core supports Linux and Mac, then ASP.NET 5 will move to using .NET Core for those platforms. See: ASP.NET 5 Overview and Introducing ASP.NET 5

Universal Windows apps is an app model that allows you to share source code between Windows Phone & Windows apps (8.1+) and are deployed to the Windows Store. Universal Windows apps will run on .NET Native which compiles IL to native machine code and contains a minimal CLR runtime. See: Building universal Windows apps for all Windows devices and Getting Started with .NET Native

So what’s .NET Core, again?

.NET Core 5 is a general purpose, modular framework that can be used across a wide variety of app models and platforms because it is a refactored set of base class libraries (corefx) and runtime (coreclr). The APIs for the .NET Core base class libraries (BCL) is identical for the different app models. The APIs don’t just look the same – they share the same implementation. The majority of the APIs/assemblies are factored much more modularly and are platform independent.

App-local (or side-by-side) deployment is also a key characteristic of .NET Core. You choose the packages you need to deploy alongside your app. Modular packages are available via NuGet. This means your apps run in isolation and are not affected by machine-wide versions of the full .NET Framework. Your apps can be x-copy deployed without worry.

.NET Core is also supported by Microsoft on Windows, Linux and Mac OSX. .NET Core builds and runs on Windows today but we are adding Linux and Mac implementations of platform-specific components. And it’s all open source. It is hugely important to lay the foundation for .NET cross-platform and build a stronger ecosystem.

image

From code to running application – .NET Core development

I think it always helps when learning technology to have a mental model of how things work together. Here’s my simplistic view of developing apps with .NET Core, from the code/build/debug cycle to app deployment and execution. Deployment and execution is different depending on what app model you are targeting.

image

You write code taking very modular references to the parts of the BCL and App Model you need. Roslyn is the compiler that takes your code and produces platform independent Intermediate Language (IL). Besides the compiler pipeline, there is a rich set of APIs you can use to do all sorts of analysis on your code. If you’re using Visual Studio, there are a ton of new IDE features that utilize these APIs to give you a much more productive coding experience.

If you’re building a universal Windows app, the .NET Native tool chain takes it from there. References are built with your app into a native image deployed locally with a minimal runtime. If you’re building an ASP.NET 5 app, references and the CoreCLR are deployed with your app locally to the server. JIT compilation then happens on startup using RyuJIT.

Additionally, ASP.NET 5 allows you to make changes in your code, save the changes, and refresh the browser without explicitly re-building the project. Visual Studio uses Roslyn to enable this dynamic compilation. You still have all of the structure and power of a compiled framework, but the development experience feels more like an interpreted language.

Note: If you are targeting the full .NET Framework 4.6 then you will still enjoy the new innovations in the languages and Roslyn compiler. App deployment doesn’t change from how it’s done today, it still relies on having the full framework installed on the machine, but the JIT compilation happens with the new optimized JIT compiler, RyuJIT.

What is open right now?

Many of the pieces of .NET 2015 are open source and are under the stewardship of the .NET Foundation. We’re actively working out in the open with the community on these projects.

image

You can see all the repos and activity of all the projects in the .NET Foundation here on GitHub: http://dotnet.github.io/

Here’s a couple good places to get started. Check out the very detailed readme’s and contribution guides.

It’s also worth mentioning that the full .NET Framework is “source open”. Meaning, we’re not taking contributions and it’s not completely released under an OSI approved license, but you can explore all the source code here: http://referencesource.microsoft.com/

Engineering in the Open

OSS isn’t new to Microsoft, but it is new to the .NET runtime & libraries. It’s a pretty big deal to take a 15+ year old project that so many people have worked on internally for that long and move not only the code, but all the engineering processes out in the open. It takes time. That’s why the team started with a small set of base class libraries at first, and have been releasing more and more and learning along the way. Those learnings and best practices have rippled throughout the team. We’ve been humbled by the overwhelming support and contributions so far.

You might be thinking to yourself “I don’t have enough time in the day to build my own apps, let alone figure out how to write code for the CLR!” Fair enough, I’m with you! You choose how involved you want to be. You don’t have to write code to be a contributor. File an issue, comment on a proposal, answer a question. Or just hang around and watch the activity.

You might be thinking “I don’t want to lose the simplicity nor the quality or support that I’m used to!” Don’t worry! We’re still dedicated to the same level of quality and service as before. To think of it simply, all we’re doing is taking our engineering out in the open. Everything that we had previously done internally to build quality software is still in place, it’s just now done publicly.

I’m truly excited about this new culture on the team and the future of .NET.

Enjoy!

[UPDATE 2/26/2015] – I should have also mentioned that dotNetConf 2015 is coming up where you can learn a lot more. This is a free virtual event with speakers from both the community and product teams. Tune in for the live stream March 18th & 19th.

by Beth Massi - Microsoft at February 25, 2015 04:33 PM

Alex Feldstein

Photo of the Day


Boeing 737 (previously as Vision Airways, same company just a marketing move), doing the Miami-Havana run several times a day. Dusk shot.

by Alex Feldstein (noreply@blogger.com) at February 25, 2015 06:00 AM

Sandstorm's Blog (Home of ssClasses)

For Each...EndFor GOTCHA!!!!

Working on a new concept for my Fake Tabs need, I decided to create a container class that will act as a page tab.  Then to emulate a pageframe, I control the position of the tab on each instances of the class.  Then pile those up on top of each other.  So if I need say 5 tabs, then that will be 5 of that container class that is piled on top of each other.  Switching tabs is done via switching Zorder().

With this fake tab, I can change colors per tab or use the same color but with different shades.  With the tab width auto-adjusting based on the caption I put into it plus its Font Name and Size, I am happy with the result.

While those can be achieved as well on the native VFP tab via turning Themes=.F. and TabStyle = 1 (Non-justified) properties of a pageframe object, I like to have a uniquely looking tab for my use and not that Windows 98 looking tabs when I need a colored tab; so the extra work on my end to achieve it.

Everything works to my satisfaction until I decided to add a sort of highlighter in the form of a dotted transparent shape to act as an indicator of the active tab.



While testing that highlighter though, I noticed that it sometimes does not seem to follow my instruction on the FOR EACH....ENDFOR  for there are times (not always) that two dotted shapes remain.  For you to help understand this, here are my codes:

For Each loObject In This.Parent.Objects FoxObject
      lnAbsLeft = m.lnLeft + loObject.Left + loObject._nTabLeft
      If Between(laObj(3),m.lnAbsLeft , m.lnAbsLeft + loObject._nTabWidth)
            loObject.ZOrder(0)
            loObject.shpActiveTab.Visible = .T.
      Else
            loObject.shpActiveTab.Visible = .F.
      Endif
Next

And a variation:

For Each loObject In This.Parent.Objects FoxObject
      loObject.shpActiveTab.Visible = .F.
      lnAbsLeft = m.lnLeft + loObject.Left + loObject._nTabLeft
      If Between(laObj(3),m.lnAbsLeft , m.lnAbsLeft + loObject._nTabWidth)
            loObject.ZOrder(0)
            loObject.shpActiveTab.Visible = .T.
      Endif
Next

And we expect that that shpActive (dotted shape) will only show once, right?  On a case to case basis, it does not:


Gotcha

I realized only a while ago prior to this post what is causing this, and while this may not be a bug, it is not documented either on my VFP help (at least on my stock copy of it).

The gotcha is that FOR EACH...ENDFOR relies on the z-order of objects subject to the loop.  It starts reading from the bottom of the z-order going to top.  So by changing the z-order of the objects while in the loop, then that switch may cause it to shortcircuit where the FOR EACH reading "again" the one that may have already passed the previous loop and is then put on top or in front of the z-order;  and that the one that is not read yet that goes below the z-order may no longer be read.

So the solution to my problem is simply allowing the loop to complete before applying new Zorder():

For Each loObject In This.Parent.Objects FoxObject
      lnAbsLeft = m.lnLeft + loObject.Left + loObject._nTabLeft
      loObject.shpActiveTab.Visible = .F.
      If Between(laObj(3),m.lnAbsLeft , m.lnAbsLeft + loObject._nTabWidth)
            loActive = loObject
            loObject.shpActiveTab.Visible = .T.
      Endif
Next
*Change Zorder outside of the loop
loActive.ZOrder(0)

This post  is for your awareness to never change a Zorder() of an object inside a FOR EACH loop!


by Jun Tangunan (noreply@blogger.com) at February 25, 2015 05:13 AM

February 24, 2015

Alex Feldstein

February 23, 2015

Alex Feldstein

February 22, 2015

Alex Feldstein

February 21, 2015

Alex Feldstein

February 20, 2015

Articles

Preparations for Developers Conference 2015

The First of its Kind in Mauritius

Developers Conference 2015 is the first event in Mauritius, maybe even in the Indian Ocean which is organised as a "classic" conference. Yes, there have been various vendor-specific bootcamps in the past but never anything like this.

"From craftsmen - For craftsmen"

This year's conference is first time organised by the Mauritius Software Craftsmanship Community (MSCC) in partnership with a number of local and international companies. Although the MSCC was founded back in 2013 it quickly became clear that our tropical island has a certain lack of informational and technical events. During some monthly meetups we spoke about this situation and that it would be very interesting and delightful to organise such an event.

Also, the monthly meetings of the MSCC are usually topic-centered and most amazingly we had solid technical information and good presenters - even though none is a professional trainer - during the last couple of month. The Developers Conference is just the consequent development of this process - our thirst for more information in the world of modern IT.

Mauritius has been branded "Cyber Island" in the Indian Ocean... Opinions in those matters vary but with this conference we strive to improve the general attribution of our island. Mauritius has great political stability and economical advantages for foreign investors, and the most precious resource Mauritius has to offer is people's knowledge.
The ICT sector in Mauritius is growing since years and maturing as the fourth pillar of our economy. With its geographical position Mauritius is also welcome as a business and knowledge hub between Africa and Asia.

Welcome to the first ever Developers Conference in Mauritius!

Extras & Specialties - It's not all about sessions

Apart from the technical sessions and presentations during the day the conference is going to be complemented with additional activities of different types. Our venues provide lots of space for some extra fun...

Stroll around and get some inspiration from our side activities. Socialise with other attendees offline and seize the opportunity to get some ideas for DIY projects from others.

Global Azure Bootcamp Again!

In April of 2013 we held the first Global Windows Azure Bootcamp at more than 90 locations around the globe! In March 2014 we topped that with 136 locations!

This year we are again doing a one day deep dive class to help thousands of people get up to speed on developing Cloud Computing Applications for Azure.

In addition to this great learning opportunity we will have another set of hands on labs.

Hack-a-thon - Programming is a lifestyle

Tired of listening and talking? Let the source code fly!

The Developers Conference is a great chance to show your programming skills. Team up with other developers and solve a variety of challenging tasks. There will be different categories of competitions and we will organise different prices for the winners and runner-ups.

A hack-a-thon is not only fun but also a solid way to put your skills on the table. Be part of it...

Touch-typing Contest - Show us your keyboard skills

Working with computers is bound to typing your source code, specifications or any kind of documentation via keyboard since decades. New alternatives like speech recognition are still in their early phase of development and practical use. Which leads us ultimately to the following questions:

Do you know about touch-typing or speedtyping? How good are your skills?

Show us and other participants your impressive speedtyping skills and compete among each other in various competitions and races. The typing speed is usually measured in words-per-minute (WPM), and a word is standardized to five characters or keystrokes.

Ubuntu 15.04 - Celebrating Vivid Vervet

The next version of Ubuntu is highly anticipated with its continuous development towards an unified user experience on the desktop, on the server, in the cloud, or on the mobile platform. Welcome the Internet of Things (IoT).

Mark Shuttleworth introduced the new version Ubuntu and its foray into the mobile space some months back:

"This is a time when every electronic thing can be an Internet thing, and that’s a chance for us to bring our platform, with its security and its long term support, to a vast and important field. In a world where almost any device can be smart, and also subverted, our shared efforts to make trusted and trustworthy systems might find fertile ground."

Bring your laptop or USB pendrives to receive a copy of the latest incarnation of Ubuntu, and step into a world of open source.

DIY projects - Raspberry Pi, Arduino, any...

You are more of a hardware geek? You like to pull up your sleeves and get cracking with single-board computers (SBC) like the Raspberry Pi, the Arduino, or other models? Then the maker space will be the right place to demo your Do-It-Yourself (DIY) projects to the rest of the audience.

Learn the latest trends about small hardware projects and get some inspiration from others.

Networking - Communication and exchange with others

Communication with your environment is an essential part of everyone's life. And it doesn't matter whether you are actually living in a rural area in the middle of nowhere, within the pulsating heart of a big city, or in my case on a wonderful island in the Indian Ocean. The ability to exchange your thoughts, your experience and your worries with another person helps you to get different points of view and new ideas on how to resolve an issue you might be confronted with.

Take the chance to exchange with other attendees in the reception area or on the balcony. Have some interesting conversations about software development, latest information gained during one of the presentations and let others know about your ups & downs in your projects.

Also, join the Mauritius Software Craftsmanship Community and be part of the local IT community.

The MSCC is a community for those who care and are proud of what they do. For those developers, regardless how experienced they are, who want to improve and master their craft.

It is a community for those who believe that being average is just not good enough.

Join the community and stay informed.

by Jochen Kirstaetter (jochen@kirstaetter.name) at February 20, 2015 07:18 AM

Alex Feldstein

FoxCentral News

wwMongoDb - FoxPro access to MongoDb

 wwMongoDb is a library that allows access MongoDb from Visual FoxPro. The library uses the MongoDb C# .NET driver and provides a simple CRUD and JSON string based interface that allows FoxPro to interact with MongoDb via JSON commands and FoxPro serialized objects. Push FoxPro objects or string based JSON into MongoDb databases very quickly, query data using MongoDb's query syntax and use the MongoDb Aggregation Pipeline to query data. Results are returned as FoxPro objects or optionally as JSON strings. wwMongoDb is open source with source code on GitHub. The current version is beta so any feedback and pull requests are welcome. Please star the repo if you have any interest.

by West Wind Technologies at February 20, 2015 12:51 AM

February 19, 2015

FoxCentral News

Southwest Fox/Xbase++ 2015: Call for Speakers

We?re inviting anyone interesting in speaking at this year?s conferences to submit topics. You'll find the Call for Speakers at http://www.swfox.net/callforspeakers.aspx. Please read the complete Call for Speakers document (linked from that page), and use our proposal submission application at https://geekgatherings.com/Submission. Session proposals are due by March 9. As in the past few years, we plan to offer a good selection of topics in core VFP development, extending VFP, using VFP with other technologies, and VFPX, as well as technology sessions to help VFP developers become better developers, not just more expert at VFP. We are looking for a few sessions on paths forward for VFP developers and we?re looking for a few deep-dive post-conference sessions. The Call for Speakers also lists some topics last year?s attendees specifically requested. Please don?t hesitate to ask if you have any questions. We?re looking forward to seeing your proposals. We expect that, as usual, choosing among them will be one of the hardest things we do all year.

by Southwest Fox Conference at February 19, 2015 10:35 PM

Shedding Some Light

Southwest Fox/Xbase++ 2015: Call for Speakers

The call has gone out!

We’re inviting anyone interesting in speaking at this year’s conferences to submit topics. You’ll find the Call for Speakers at http://www.swfox.net/callforspeakers.aspx. Please read the complete Call for Speakers document (linked from that page), and use our proposal submission application at https://geekgatherings.com/Submission. Session proposals are due by March 9. (Yes, this is earlier than in prior years. We have some publicity plans that require us to have a little more lead time than in the past.)

As in the past few years, we plan to offer a good selection of topics in core VFP development, extending VFP, using VFP with other technologies, and VFPX, as well as technology sessions to help VFP developers become better developers, not just more expert at VFP. We are looking for a few sessions on paths forward for VFP developers and we’re looking for a few deep-dive post-conference sessions. The Call for Speakers also lists some topics last year’s attendees specifically requested.

Please don’t hesitate to ask if you have any questions. We’re looking forward to seeing your proposals. We expect that, as usual, choosing among them will be one of the hardest things we do all year.

And don’t forget, we will be opening registration in mid-May.

White Light Computing is a sponsor again, our 12th straight year.

Only 238 days until we gather in Gilbert.

by Rick Schummer at February 19, 2015 10:31 PM

Alex Feldstein

February 18, 2015

FoxProWiki

SouthwestFox

Editor comments: Call for speakers

Southwest Fox 2015


October 15-18, 2015
SanTan Elegante Conference & Reception Center > in Gilbert, Arizona<br> <br> <a href=http://swfox.net
Blog: http://swfox.net/blog/index.php
RSS/Atom: http://swfox.net/blog/feed
Twitter: http://twitter.com/swfox

February 18, 2015
Anyone interested in speaking at this year's conferences is invited to submit topics. See the Call for Speakers page for details.

December 15, 2014
Geek Gatherings LLC is officially asking you to save the dates for Southwest Fox and Southwest Xbase++ 2015! The conferences take place October 15-18, 2015.

We look forward to seeing you in Arizona in October!

Regards,
Rick Schummer
Doug Hennig
Tamar Granor

February 18, 2015 04:19 PM

Doug Hennig

Southwest Fox/Xbase++ 2015 Call for Speakers

The call has gone out!

We’re inviting anyone interesting in speaking at this year’s conferences to submit topics. You'll find the Call for Speakers at http://www.swfox.net/callforspeakers.aspx. Please read the complete Call for Speakers document (linked from that page), and use our proposal submission application at https://geekgatherings.com/Submission. Session proposals are due by March 9. (Yes, this is earlier than in prior years. We have some publicity plans that require us to have a little more lead time than in the past.)

As in the past few years, we plan to offer a good selection of topics in core VFP development, extending VFP, using VFP with other technologies, and VFPX, as well as technology sessions to help VFP developers become better developers, not just more expert at VFP. We are looking for a few sessions on paths forward for VFP developers and we’re looking for a few deep-dive post-conference sessions. The Call for Speakers also lists some topics last year’s attendees specifically requested.

Please don’t hesitate to ask if you have any questions. We’re looking forward to seeing your proposals. We expect that, as usual, choosing among them will be one of the hardest things we do all year.

by Doug Hennig (noreply@blogger.com) at February 18, 2015 04:09 PM

Alex Feldstein

February 17, 2015

Alex Feldstein

Sandstorm's Blog (Home of ssClasses)

Firefox Inside VFP Form

Nothing new here, I used the same approach in the Chrome one but worked on FireFox itself this time.  This is to see if my suspicion that the reason for WinAPIs' inability to control the titlebar of Chrome is because it really has its own titlebar.

Also, this is based on advise of Bernard Bout to try this on FireFox.  This works on my end since I am using an older version of FF which is 12.  The titlebar is hidden properly.  I have not tried it though on newer version of FF as I don't download any being I prefer Chrome.  So it is up to you guys to test this on those newer version.


Anyway, here are the codes, with the same approach I used on Chrome and some changes on Windows Styles:

Public oForm
oForm = Createobject('form1')
oForm.Show()

Define Class form1 As Form
      Height = 600
      Width = 900
      Caption = "Firefox Inside VFP Form"
      Desktop = .T.
      AutoCenter = .T.

      Procedure Load
            Declare Integer FindWindow In user32;
                  STRING lpClassName, String lpWindowName

            Declare Integer GetActiveWindow  In user32

            Declare Integer GetWindow In user32 Integer HWnd, Integer wFlag

            Declare Integer GetWindowLong In User32 Integer HWnd, Integer nIndex

            Declare Integer GetWindowTextLength In user32 Integer HWnd

            Declare Integer IsWindow In user32 Integer HWnd

            Declare Integer IsWindowVisible In user32 Integer HWnd

            Declare Integer GetWindowText In user32;
                  INTEGER HWnd, String @lpString, Integer cch

            Declare Integer ShellExecute In shell32.Dll ;
                  INTEGER hndWin, ;
                  STRING cAction, ;
                  STRING cFileName, ;
                  STRING cParams, ;
                  STRING cDir, ;
                  INTEGER nShowWin

            Declare Integer SetWindowLong In user32 Integer HWnd,;
                  INTEGER nIndex, Integer dwNewLong

            Declare Integer SetWindowPos In user32;
                  INTEGER HWnd,;
                  INTEGER hWndInsertAfter,;
                  INTEGER x,;
                  INTEGER Y,;
                  INTEGER cx,;
                  INTEGER cy,;
                  INTEGER uFlags

            Declare Integer SetParent In user32;
                  INTEGER hWndChild,;
                  INTEGER hWndNewParent

            Declare Sleep In kernel32 Integer

            #Define GW_HWNDFIRST  0
            #Define GW_HWNDLAST   1
            #Define GW_HWNDNEXT   2
      Endproc

      Procedure KeyPress
            Lparameters nKeyCode, nCtrlShift
            If nKeyCode = 27
                  Thisform.Release
            Endif
      Endproc

      Procedure Init
            Local lcURL
            lcURL = 'http://www.clipartpanda.com/clipart_images/fox-clip-art-2605413'
            ShellExecute(0,'open','firefox.exe',m.lcURL,'',1)
            Activate Window (Thisform.Name)
            Sleep(1000)
            Thisform.SearchProcess()
      Endproc

      Procedure SearchProcess()
            With This
                  Local hWinActive, hWindow, lcWinText
                  hWinActive = GetActiveWindow()
                  hWindow = -1

                  Do While hWindow <> GetWindow(hWinActive, GW_HWNDLAST)
                        If hWindow = -1
                              hWindow = GetWindow(hWinActive, GW_HWNDFIRST)
                        Else
                              hWindow = GetWindow(hWindow, GW_HWNDNEXT)
                        Endif

                        If IsWindow(hWindow) <> 0 And IsWindowVisible(hWindow) <> 0;
                                    And GetWindowTextLength(hWindow) > 0
                              lcWinText = .GetWinText(hWindow)
                              nHwnd = FindWindow(Null, m.lcWinText)
                              If 'Mozilla Firefox' $ m.lcWinText
                                          Exit
                              Endif
                        Endif
                  Enddo
                  lnStyle = GetWindowLong(m.nHwnd, -6)
                  SetWindowLong(m.nHwnd, -16, Bitxor(lnStyle, 0x00400000))

                  With This
                        SetParent(m.nHwnd,.HWnd)
                        SetWindowPos(m.nHwnd, 1, 0, 0, .Width, .Height,0x0040)
                  Endwith
            Endwith

      Endproc

      Function  GetWinText(hWindow)
            Local lnBufsize, lcBuffer
            lnBufsize = 1024
            lcBuffer = Repli(Chr(0), lnBufsize)
            lnBufsize = GetWindowText(hWindow, @lcBuffer, lnBufsize)
            Return  Iif(lnBufsize=0, "", Left(lcBuffer,lnBufsize))
      Endfunc

Enddefine

The same approach can be used on any other browser or any other 3rd party app that cannot be easily reached via automation.  Though I would prefer automation if it is available as it gives us more control over the object.

by Jun Tangunan (noreply@blogger.com) at February 17, 2015 03:29 AM

February 16, 2015

Alex Feldstein

Sandstorm's Blog (Home of ssClasses)

Chrome inside VFP Form

Update February 18, 2015:

This is getting interesting.  I suddenly thought maybe Chrome allows parameters to be passed and indeed there are, tons of it.   Here are the switches:

http://peter.sh/experiments/chromium-command-line-switches/

As for forcing Chrome to open on a new window instead of the existing one as a tab, it is --new-window

I also updated the sample below to know whether the operation is successful or not so it won't accidentally open any other active window aside from our target.

Later:

Paul Hemans post inside Foxite Forum while working on another approach using the --app switch of Chrome, gave me another idea on how to fix our problem with the titlebar.  And you'll be surprised that the trick of getting rid of that internal pesky not so good (in this case) Chrome's own titlebar is really very simple. All we need to do is move the chrome up from within our form that its own internal titlebar cannot be seen anymore, and thus rendering it likewise immovable.  LOL!

Check again the codes below, adjust lnMove value based on how you set up your Chrome on your end.  Since in mine I show my bookmarks, then my adjustment is 100.  Maybe on the link I gave above on the command switches, there are commands to hide those, but I did not check anymore. :)

======

Sparked by last week's thread inside Foxite Forum about placing an IE Browser inside VFP Form, I thought to myself it would be cool to put Google Chrome inside our form for a change.

Also, this will ensure that most probably a webpage can be displayed properly being Chrome is always up to date with changes introduced now and then, as compared to IE that has been left far behind and is giving developers now some headache to fix it via Registry tweaks.


Googling does not give me any result on how this new sudden thought of mine can be done as I never found any that shows how to achieve this without downloading and working on extension designed to provide automation to google.  But I simply wanted chrome to be inside our VFP form using stock VFP commands and function plus utilizing WinAPIs.



I knew for a fact beforehand that this one is not as simple as placing other app inside our form like what I have shown in http://sandstorm36.blogspot.com/2014/05/3rd-party-apps-from-within-our-forms.html

For among its obstacles is that Chrome browser creates several processes when you open it.  This can be seen via Task Manager so using its process ID (PID) is not a good way to go.  Although originally that is where my first few thoughts went.


Next is Chrome might open several tabs depending on your local setting if you set it to remember the previous tabs opened when you close it, via "Continue where you left off".

Further, Google Chrome Browser is an entirely separate beast, so to speak.  After I found the way to bring it inside our VFP form, belatedly I realize that it does not respect Windows Styles so while we can put it inside our VFP form, it is somewhat useless to me unless I can hide its TitleBar to disallow its further movements.

Maybe you will ask me, what is the purpose of placing chrome inside VFP form? Honestly, I do not have a use on my end as I never needed this nor the IE browser inside our form due to very slow internet services here in this country where I am working.  But I have to satiate my curiosity for if I don't, then it will bug me now and then when the thoughts interfere on my day to day job.  I simply have to satisfy my curiosity on how this can be done; so I can move on with new lines of thought. Or else I will be stuck thinking about this now and then.

Anyway, it is fun finding a way to bring it inside VFP form.  Plus I learn new WinAPIs in the process just to make this possible.

I am shelving this now and will work on real things that are important.  I am making this post so if anyone got an interest to even just find out how this can be done and maybe tries to enhance this, then this can maybe serve as your starting point.  Codes are below:

Public oForm
oForm = Createobject('form1')
oForm.Show()

Define Class form1 As Form
      Height = 600
      Width = 900
      Caption = "Chrome Inside VFP Form"
      Desktop = .T.
      AutoCenter = .T.

      Procedure Load
            Declare Integer FindWindow In user32;
                  STRING lpClassName, String lpWindowName

            Declare Integer GetActiveWindow  In user32

            Declare Integer GetWindow In user32 Integer HWnd, Integer wFlag

            Declare Integer GetWindowLong In User32 Integer HWnd, Integer nIndex

            Declare Integer GetWindowTextLength In user32 Integer HWnd

            Declare Integer IsWindow In user32 Integer HWnd

            Declare Integer IsWindowVisible In user32 Integer HWnd

            Declare Integer GetWindowText In user32;
                  INTEGER HWnd, String @lpString, Integer cch

            Declare Integer ShellExecute In shell32.Dll ;
                  INTEGER hndWin, ;
                  STRING cAction, ;
                  STRING cFileName, ;
                  STRING cParams, ;
                  STRING cDir, ;
                  INTEGER nShowWin

            Declare Integer SetWindowLong In user32 Integer HWnd,;
                  INTEGER nIndex, Integer dwNewLong

            Declare Integer SetWindowPos In user32;
                  INTEGER HWnd,;
                  INTEGER hWndInsertAfter,;
                  INTEGER x,;
                  INTEGER Y,;
                  INTEGER cx,;
                  INTEGER cy,;
                  INTEGER uFlags

            Declare Integer SetParent In user32;
                  INTEGER hWndChild,;
                  INTEGER hWndNewParent

            Declare Sleep In kernel32 Integer

            #Define GW_HWNDFIRST  0
            #Define GW_HWNDLAST   1
            #Define GW_HWNDNEXT   2
      Endproc

      Procedure KeyPress
            Lparameters nKeyCode, nCtrlShift
            If nKeyCode = 27
                  Thisform.Release
            Endif
      Endproc

      Procedure Init
            Local lcURL
            lcURL = 'http://www.clipartpanda.com/clipart_images/fox-clip-art-2605413 --new-window '
            ShellExecute(0,'open','chrome.exe',m.lcURL,'',1)
            Activate Window (Thisform.Name)
            Sleep(1000)
            Thisform.SearchProcess()
      Endproc

      Procedure SearchProcess()
            With This
                  Local hWinActive, hWindow, lcWinText, lSuccess, lnMove
                  hWinActive = GetActiveWindow()
                  hWindow = -1
                  lSuccess = .F.
                  Do While hWindow <> GetWindow(hWinActive, GW_HWNDLAST)
                        If hWindow = -1
                              hWindow = GetWindow(hWinActive, GW_HWNDFIRST)
                        Else
                              hWindow = GetWindow(hWindow, GW_HWNDNEXT)
                        Endif

                        If IsWindow(hWindow) <> 0 And IsWindowVisible(hWindow) <> 0;
                                    And GetWindowTextLength(hWindow) > 0
                              lcWinText = .GetWinText(hWindow)
                              nHwnd = FindWindow(Null, m.lcWinText)
                              If 'Google Chrome' $ m.lcWinText
                                    lSuccess = .T.
                                    Exit
                              Endif
                        Endif
                  Enddo
                  If m.lSuccess
                        lnStyle = GetWindowLong(m.nHwnd, -6)
                        SetWindowLong(m.nHwnd, -16, Bitxor(lnStyle, 0x00400000))

                        * The trick to hide the pesky built-in titlebar of chrome is to
                        * move chrome up that it won't display the titlebar anymore.  Since there is a difference in settings
                        * on each of our machines such as in my end, my bookmarks are shown, then here is my setting
                        * Adjust it based on your end settings of Chrome

                        lnMove = 100

                        With This
                              SetParent(m.nHwnd,.HWnd)
                              SetWindowPos(m.nHwnd, 1, 0, -m.lnMove, .Width, .Height + m.lnMove,0x0040)
                        Endwith
                  Endif
            Endwith

      Endproc

      Function  GetWinText(hWindow)
            Local lnBufsize, lcBuffer
            lnBufsize = 1024
            lcBuffer = Repli(Chr(0), lnBufsize)
            lnBufsize = GetWindowText(hWindow, @lcBuffer, lnBufsize)
            Return  Iif(lnBufsize=0, "", Left(lcBuffer,lnBufsize))
      Endfunc

Enddefine




 ===== 

As a guide on how I achieve this, it involves forcefully opening a URL to Chrome via ShellExecute(), cycling to all active windows (Chrome, VFP, Explorer, etc.) until it finds Chrome, and getting its corresponding window handle so we can put a hold on to it.

As for Chrome, depending on the speed of the connection, you may get the internal caption of the newly opened Tab or if it is slow, you will get "New Tab - Google Chrome".  In which case, to ensure that no matter what we can know if it is chrome is to look for the word Google Chrome as that will always be a part of its internal caption.

Aside from the purpose of my usage of those APIs above, I posted the above as I deem it is also good for interested readers to study each APIs I used there as that may come handy on other needs as well.

Cheers!




by Jun Tangunan (noreply@blogger.com) at February 16, 2015 05:53 AM

February 15, 2015

Alex Feldstein

February 14, 2015

Alex Feldstein

February 13, 2015

The Problem Solver

Alex Feldstein

February 12, 2015

Doug Hennig

Blog Posts on Improving Performance in Stonefield Query

I posted a couple of entries today on the Stonefield Query blog about improving the performance of calculated fields and formulas. If you’re a Stonefield Query customer, I strongly recommend checking them out as they can improve the performance of your reports by orders of magnitude for not a lot of work:

Improving the Performance of Calculated Fields and Formulas, Part 1

Improving the Performance of Calculated Fields and Formulas, Part 2

by Doug Hennig (noreply@blogger.com) at February 12, 2015 05:11 PM

Alex Feldstein

Charles Darwin Birthday!

darwin_day_evolution-from-single-cells

Darwin Day is an international celebration of science and humanity held on or around February 12, the anniversary of Charles Darwin‘s birth in 1809. Honoring the discoveries and life of Darwin—the man who first described biological evolution via natural selection—Darwin Day celebrates the enormous benefits that scientific knowledge has contributed to the advancement of humanity.

by Alex Feldstein (noreply@blogger.com) at February 12, 2015 05:30 AM

VisualFoxProWiki

ChicagoFUDG

Editor comments: February 2015 meeting details
FUDG stands for FoxPro User / Developer Group. This one is based in Chicago, IL. Visit our web site at www.ChicagoFUDG.com !

Leaders:
Michael Hogan
Randy Bosma Speaker Agitator
Jeff Simon Treasurer jeff@datamarkcorp.com
Tom Corrigan Secretary (his FUDG e-mail: tom@corrigan.com)
Greg Gershuny gel4it [at} hotmail {dot] com

Bill Drew Past President bill.drew@sbcglobal.net

Monthly Meetings:
When: Chicago FUDG normally meets on the third Monday of each month, unless it collides with a major event. The meeting room is normally accessible at about 5:15 PM; presentation starts at shortly after our 'business chatter' and introductions at 5:30.
Where: 1871 at the Merchandise Mart suite 1212 (enter from Orleans on the west side of the building and take the west elevators to the 12th floor). When you arrive at the 1871 front desk (adjacent to the west elevator bank) ask to be directed to the FoxPro meeting in the IMSA classroom. Reasonable ($11) parking is available 1 block north of the Orleans Street (west) entrance of the Merchandise Mart.

February 12, 2015 03:01 AM

UpcomingEvents

A place to list upcoming Visual FoxPro events like conferences, meetings, user groups, open training sessions...
Closest at the top please, and please remove past events.

February 12, 2015 02:27 AM

February 11, 2015

VisualFoxProWiki

TypesOfSoftwareDevelopmentRisk

What are the types of Software Development Risk?

See also Taxonomy Of Software Development Risk

Technical Risk
These risks may result from excessive constraints, lack of experience, poorly defined parameters, or dependencies on organizations outside the direct control of the project team.
  • Problems with language
  • Project size ( ... leading to FinancialRisks and Schedule Risk )
  • Project functionality
  • Platforms
  • Methods, Standards, Processes

February 11, 2015 04:58 PM

Alex Feldstein

February 10, 2015

ERROR: Status read failed: Connection reset by peer

February 10, 2015 05:37 PM

Some older American paints

These are different aircraft landing in Miami International this past weekend. American Airlines has many aircraft still with the old livery.

1. Boeing 737 955AN

2. Boeing 737 N913NN

3. Boeing 737 N886NN

by Alex Feldstein (noreply@blogger.com) at February 10, 2015 01:13 PM

Rick Strahl's Web Log

Back to Basics: UTC and TimeZones in .NET Web Apps

Most applications we build tend to have date and time data associated with it. If the application is not used just in a single location you are likely have to deal with times zones in your application. While .NET has a good set of date manipulation function, the various time zone conversion routines are a bit of a pain to use. I find myself having to look up what functions need to be called and review my thinking about how to best manage dates frequently. I see others struggling with this often as well, so I decided to take some time to write it down here in a post so I can find this info in one place.

Thinking about Time in .NET Web Apps

Web apps typically require that dates are stored in time zone agnostic fashion. This means storing DateTime values as UTC, so that you have a consistent baseline date value. This means storing dates in UTC format either with generated values using DateTime.UtcNow or, if you are capturing user input dates converting the time zone specific dates to UTC dates using .ToUniversalTime().

However in Web apps, this is not quite so easy because you can’t just use the server’s local time and use .ToUniversalTime() on a captured date input because that time reflects the server’s time, not necessarily the user’s time. So in addition to converting to UTC you also need to be able to convert user local dates to and from specific time zones which you can do with TimeZoneInfo.ConvertTime() and THEN convert that value to UTC.

On the other end when retrieving dates you convert all dates from UTC dates to local dates according to the user’s time zone for which you need to using the TimeZoneInfo class. You need two static methods from it: TimeZoneInfo.FindSystemTimeZoneById() and TimeZoneInfo.ConvertTimeFromUtc(). Also useful are TimeZoneInfo.ConvertTime() which converts between two timezones and TimeZoneInfo.ConvertTimeToUtc(). Finally if you’re building UI to allow users to select Time zones you’ll probably want to use TimeZoneInfo.GetSystemTimeZones().

Let’s see how we can put all of these together.

Simple Conversion Routines

Before looking at more specific examples of how to set this up in a more application specific way in a Web application, let’s look at a couple of easy ways to convert UTC dates to a specific locale via some DateTime extension methods which demonstrate the basic features that .NET provides for time zone conversions.

/// <summary>
/// Returns TimeZone adjusted time for a given from a Utc or local time.
/// Date is first converted to UTC then adjusted.
/// </summary>
/// <param name="time"></param>
/// <param name="timeZoneId"></param>
/// <returns></returns>
public static DateTime ToTimeZoneTime(this DateTime time, string timeZoneId = "Pacific Standard Time")
{
    TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
    return time.ToTimeZoneTime(tzi);
}

/// <summary>
/// Returns TimeZone adjusted time for a given from a Utc or local time.
/// Date is first converted to UTC then adjusted.
/// </summary>
/// <param name="time"></param>
/// <param name="timeZoneId"></param>
/// <returns></returns>
public static DateTime ToTimeZoneTime(this DateTime time, TimeZoneInfo tzi)
{
    return TimeZoneInfo.ConvertTimeFromUtc(time, tzi);
}

To use these extension methods is super easy. The first one works by getting the value from a string:

DateTime time = DateTime.UtcNow.ToTimeZoneTime("Pacific Standard Time");

while the second works of an existing TimeZoneInfo instance:

var tz = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
DateTime time2 = DateTime.UtcNow.ToTimeZoneTime(tz);

The latter is important as you want to cache a TimeZoneInfo instance in order to reduce the overhead of looking up the TimeZoneInfo repeatedly when running these functions in a loop – like displaying a long list of items with dates in them. I’ll talk more at performance later, but suffice it say that compared to direct date access doing time zone conversions is (relatively) slow…

Next let’s look at how we get TimeZones into our applications.

Admin User Interface

In order to properly convert user time zone values you need to figure out which time zone the user is coming from, so you you need to capture a preference for this and save it with a user. I typically capture his as part of my User Admin Interface and let the user pick from a list of the available time zones. This looks something like this on my Profile form:

DateField

which drops down a list retrieved with TimeZoneInfo.GetSystemTimeZones:

DroppedDownTimeZones

The code to do this is pretty straight forward. I use ASP.NET MVC 5 and have the code in my ViewModel to create an array of SelectList objects:

public class ProfileViewModel : AppBaseViewModel { public User User { get; set; } public string Password { get; set; } public string PasswordConfirm { get; set; }

public string JsTime { get; set; } public SelectListItem[] TimezoneList { get; set; }
public ProfileViewModel() { var tzs = TimeZoneInfo.GetSystemTimeZones(); TimezoneList = tzs.Select(tz => new SelectListItem() { Text = tz.DisplayName, Value = tz.Id }).ToArray(); } }

The actual TimeZone value is then bound to my User object which has a TimeZone property.

<div class="form-group">
    <div class="input-group ">
        <div class="input-group-addon" title="Timezone to display dates.">
            <i class="fa fa-fw fa-flag"></i>
        </div>
        @Html.DropDownListFor(mod => Model.User.TimeZone, Model.TimezoneList,
            new {@class = "form-control", title = "Timezone to display dates."})
    </div>
</div>

The model binds to it and the value is stored in the database in this case in MongoDb. The property stores the TimeZoneInfo.Id which is a value like Hawaiian Standard Time or Eastern Standard Time that can be used as keys for looking up timezones. This key is what’s used to find the right time zone to perform any conversions.

Capturing a Web User’s Default Time Zone

When a user comes in to the site for the first time, we can in most cases also detect the user’s time zone from the browser, so the list above can be pre-selected to the proper time zone. The JavaScript Date() object includes the time zone information in it when you write out the time to string:

var dt = new Date().toString();
//Wed Feb 04 2015 18:37:55 GMT-1000 (Hawaiian Standard Time) 

The time zone value uses official time zone string which is the same as the standard names that the .NET time zones use, so all we have to do is peel out the zone expressions in parenthesis and map that to our list box input.

To do this  I have to pass the time zone from the client to the server in some way when accessing my Profile view for the first time. This requires a little JavaScript to do. There are a few ways to do this. The easiest is probably to add some JavaScript to append the time to the link URL:

@if (!Model.IsSubscribed)
{
    <a href="@Url.Action("Profile", "Account")" id="SubscriptionButton">
        SUBSCRIBE NOW
    </a>
    <script>
        var el = document.getElementById("SubscriptionButton");
        //Wed Feb 04 2015 18:37:55 GMT-1000 (Hawaiian Standard Time)                    
        var href = el.href + "?JsTime=" + new Date().toString();
        el.href = href;
    </script>
}

This code injects a JsTime query string value into the link URL and… creates a pretty ugly URL. If you care about that, you can use RegEx in the JavaScript to clean up the date string and extract just the time zone string for a little cleaner URL. However, I prefer to do the parsing on the server so I just pass the whole messy date string up to the server in the URL. If you want to keep the URL clean you can also wrap the initial access into a form and POST the data using a hidden form variable. Either way you have to get the data to the server in some way.

Inside of the controller I can then check and convert this value to a proper time zone string with the following C# ASP.NET MVC code (ExtractString is a helper method in Westwind.Utilities):

// try to pick up user's timezone
var jsTime = Request.QueryString["JsTime"];
if (!string.IsNullOrEmpty(jsTime))
    //Wed Feb 04 2015 18:37:55 GMT-1000 (Hawaiian Standard Time) 
    model.TimeZone = StringUtils.ExtractString(jsTime, "(", ")");
else
    model.TimeZone = App.DefaultTimeZone;

It’s a good idea to check for a missing value and default it to the default time zone even though the conversion routines automatically detect invalid timezones and fix them up.

Sweet - with this you save your users some mousing around a long list of time zones.

TimeZone Conversions on the User Class

My application level User class includes some logic to convert dates for a given user. Since the time zone is typically associated with a user and the user is usually in context throughout the application’s domain and front end logic, it makes sense to attach the time zone and a few time zone routines that act on it the user for easy access. Here’s a partial code of the relative properties and method of my user entity:

public class User
{
    public User()
    {
        Id = AppUtils.GenerateId();
        TimeZone = "Hawaiian Standard Time";
    }

    public string Id { get; set; }
        
    [Required]
    public string UserName { get; set; }
        
    [MinLength(6)]
    public string Password { get; set; }

    /// <summary>
    /// The users TimeZone using .NET TimeZoneNames
    /// </summary>
    public string TimeZone
    {
        get { return _timeZone; }
        set
        {
            TimeZoneInstance = null;
            _timeZone = value;
        } 
    }
    private string _timeZone;

    [BsonIgnore]
    public TimeZoneInfo TimeZoneInstance
    {
        get
        {
            if (_timeZoneInstance == null)
            {
                try
                {
                    _timeZoneInstance = TimeZoneInfo.FindSystemTimeZoneById(TimeZone);
                }
                catch
                {
                    TimeZone = "Hawaiian Standard Time";
                    _timeZoneInstance = TimeZoneInfo.FindSystemTimeZoneById(TimeZone);
                }
            }
            return _timeZoneInstance;
        }
        private set { _timeZoneInstance = value; }
    }

    private TimeZoneInfo _timeZoneInstance;

   ... additional model data omitted

    /// <summary>
    /// Returns a UTC time in the user's specified timezone.
    /// </summary>
    /// <param name="utcTime">The utc time to convert</param>
    /// <param name="timeZoneName">Name of the timezone (Eastern Standard Time)</param>
    /// <returns>New local time</returns>
    public DateTime GetUserTime(DateTime? utcTime = null)
    {
        TimeZoneInfo tzi = null;

        if (utcTime == null)
            utcTime = DateTime.UtcNow;        
           
        return TimeZoneInfo.ConvertTimeFromUtc(utcTime.Value, TimeZoneInstance);
    }

    /// <summary>
    /// Converts local server time to the user's timezone and
    /// returns the UTC date.
    /// 
    /// Use this to convert user captured date inputs and convert
    /// them to UTC.  
    /// 
    /// User input (their local time) comes in as local server time 
    /// -> convert to user's timezone from server time
    /// -> convert to UTC
    /// </summary>
    /// <param name="localServerTime"></param>
    /// <returns></returns>
    public DateTime GetUtcUserTime(DateTime? localServerTime)
    {
        if (localServerTime == null)
            localServerTime = DateTime.Now;

        return TimeZoneInfo.ConvertTime(localServerTime.Value, TimeZoneInstance).ToUniversalTime();
    }
                   
}

This code basically provides you the ability to make conversions based on the user’s time zone. There are two steps in the process for time zone conversion:

  • Get an instance of the TimeZone for the user
  • Converting the actual Date values from UTC to the specific TimeZone

Note that the time zone is cached so that the time zone lookup occurs only once in looping situations. Whenever the TimeZone is changed the cached value is also released.

Converting Utc Dates to User Local Time for Display

.GetUserTime() returns an adjusted local time for a given UTC time which you can use for user displayed output of dates. Anytime I display a Date value I apply this function to the date to get the dates to display in the user’s time zone. Pretty straight forward. The easiest scenarios are display cases where you can simply wrap the code in your views with calls to the converter methods – in my case the User.GetUserTime() method.

Here’s what this looks like in my Razor views for example for a simple date value:

<a href="@Url.Action("Prognosis", new {id = prakritiQuiz.Id})">
    @Model.User.GetUserTime(prakritiQuiz.Started.Value).ToString("MMM. d, yyyy")
</a>

or in looping situations:

@foreach (var quiz in historyQuizzes)
{
    <tr>
        <td>
            <a href="@Url.Action("Prognosis", new {id = quiz.Id})">
                @Model.User.GetUserTime(quiz.Started.Value).ToString("MMM. d")
            </a>
        </td>
        <td>@quiz.Result.Dosha</td>
        <td>@quiz.ToDoshaResultsString()</td>
    </tr>
}

Note that my Model includes a user record as part of my Base ViewModel that all models are based on so that User info is always available in all views.

If you don’t want to use a specific User model or have extra baggage on your view model you can also use the .ToTimeZoneTime() extension methods I showed earlier. If you do, I recommend you first retrieve the TimeZoneInfo and then store it as a variable in the view for caching. Then use the overload with the TimeZone to improve performance.

The same logic is applied inside of business code that needs to generate any output related data. For example, in one of my business object I generate summary graph data that is fed via JSON to a client side graph control and I populate the graph data in a loop:

foreach (var res in resultValues)
{                    
    var gp = new QuizGraphDataPoint();
    gp.StartedDate = user.GetUserTime(quiz.Started.Value);
    gp.Date = gp.StartedDate.ToString("MMM d");                    
    gp.Dosha = res.Key;
    gp.Value = ((decimal) res.Value/(decimal) totalDoshaCount)*100;

    data.ResultSets[res.Key].Add(gp);

    doshaString += res.Key;
}

Just keep in mind though that most business code probably doesn’t need to deal with display formatting as this conversion is generally a UI operation. So you’ll typically find calls to user.GetUserTime() isolated to View markup code, or possibly in controller code that preformats display data.

Date Conversions for Date Range Queries

Using timezone adjusted dates in queries tend to be tricky because you have to adjust the input dates for the the users time zone before you can use them in the query and then convert them to UTC. If you also have to group dates by date boundaries things get even more tricky as you have to adjust the UTC times to catch the date boundaries properly.

This can be a simple thing like do a query and return data for the last 30 days, or run a query where the user provides local dates for start and end dates. The issue here is that the date range has be based on the user’s local time not UTC, lest you miss or include to much data for a request.

The following example demonstrates doing a date range query for the last 30 days range using a LINQ query against MongoDb (same concept works with any LINQ provider):

var now = user.GetUserTime(DateTime.UtcNow);

// force date boundary to be matched to users time
var start = now.Date.AddDays(days*-1).ToUniversalTime();
var end = now.Date.AddDays(1).AddSeconds(-1).ToUniversalTime();

var results = Collection.AsQueryable()
    .Where(q => q.UserId == userId &&
                q.Started >= start &&
                q.Started <= end &&
                q.Result != null &&
                q.QuizType == QuizTypes.Daily)
    .OrderBy(q => q.Started)
    .Select(q => q)
    .ToList();

Note that I have to first get the current date (or whatever dates the user provided) into the specific user’s time. Then once I have the adjusted local time, I can perform the date math to establish the date range – in this case subtracting 30 days and adding 1 day to today. This gives me the date range in the user’s timezone. Then convert that back to UTC so it can be passed into the LINQ query.

Note that you need to be careful in your queries to pre-calculate these values as stored in the start and end  variables as I’ve done here – provider LINQ queries tend to not understand custom methods so always pre-assign the values and don’t use the expressions in the query.

User Captured Time

If you capture user input from users from a different time zone you have to convert the captured time to the user’s time zone. Most built in data binding date conversions give you dates in server local time, which is likely not the time user expected to give you. So a user in Oregon will input date/time values as Oregon time, not Hawaiian time as my server expects.

In order to account for that the user’s input has to be converted to the proper time zone.

To demonstrate, take the following MVC controller method as an example, which captures a user time input from the Pacific Timezone when running on a machine in the Hawaiian TimeZone that has a –2 hour offset:

public string DateMath(DateTime start)
{    
    var offset  = user.TimeZoneInstance.GetUtcOffset(start).TotalHours;
    var offsetLocal = TimeZoneInfo.Local.GetUtcOffset(start).TotalHours;
    var startTime = start.AddHours(offsetLocal - offset);

    // this is the time you write to the db
    var timeToSave = startTime.ToUniversalTime();

    return TimeZoneInfo.Local.ToString() + "<hr/>" + 
           "Captured time: " + start + " -> UTC:  " + start.ToUniversalTime() + "  <hr/>   " +
           "Adjusted time: " + startTime + " -> UTC: " + timeToSave;
}
If I now call this page with:

http://localhost/MyDailyDosha/home/DateMath?start=2/1/2015

I get the following output:

(UTC-10:00) Hawaii
(UTC-08:00) Pacific Time (US & Canada)
Captured time: 2/1/2015 12:00:00 AM -> UTC: 2/1/2015 10:00:00 AM
Adjusted HI time: 1/31/2015 10:00:00 PM -> UTC: 2/1/2015 8:00:00 AM

The time is entered by the user with the intent of using Pacific time (-8) as midnight 12am, but the time is captured as Hawaiian time. In Hawaiian local time the user’s date would be at 10pm to reflect the 2 hour time offset.

The code above calculates the difference between the local time zone and the users timezone and applies the difference. The result is the last value which appropriately captures the 8 hour time zone offset for UTC: 12am PST entered –> 8am UTC written to DB.

This seems terribly convoluted, but it’s necessary as you need to take the user’s input and convert it into a known timezone. ASP.NET MVC converts dates based on the local server time, so the time comes in as Hawaiian, even though the user is in Oregon and this code essentially adjusts that difference.

A more generic version of this logic is also attached to my User class:

/// <summary>
/// Converts a local machine time to the user's timezone time
/// by applying the difference between the two timezones.
/// </summary>
/// <param name="localTime">local machine time</param>
/// <param name="tzi">Timezone to adjust for</param>
/// <returns></returns>
public DateTime AdjustTimeZoneOffset(DateTime localTime, TimeZoneInfo tzi = null)
{
    if (tzi == null)
        tzi = TimeZoneInstance;

    var offset = tzi.GetUtcOffset(localTime).TotalHours;
    var offset2 = TimeZoneInfo.Local.GetUtcOffset(localTime).TotalHours;
    return localTime.AddHours(offset2 - offset);
}

DayLight Savings Time

Since we’re talking about time offsets keep in mind that time zones also have to deal with day light savings time. You might be tempted to store TimeZone offsets from UTC for your users, but the problem of DayLight Savings time makes that a really bad idea.

Daylight savings time changes the time for certain parts of the year (typically by an hour), in some places of the world. Daylight savings time is not applied universally. For example Hawaii doesn’t have it, while Oregon does. Typically the closer you are to the equator the less likely the time zone will have daylight savings time since days don’t vary much closer to the equator.

The good news is that daylight savings time is automatically handled by the various time zone conversions I’ve discussed so far. So if I change my date to a date that is in the summer when daylight savings is active – 6/1/2015 -the result looks like this:

(UTC-10:00) Hawaii
(UTC-08:00) Pacific Time (US & Canada)
Captured time: 6/1/2015 12:00:00 AM -> UTC: 6/1/2015 10:00:00 AM
Adjusted time: 5/31/2015 9:00:00 PM -> UTC: 6/1/2015 7:00:00 AM

Note that the difference between the Hawaii and Pacific time zones now is 3 hours and the conversion automatically figured this out. There were no changes required in code because the time zone conversion and offset routines know and understand the day light savings rules.

Date Grouping

Another tricky task you may have to deal with when doing UTC date conversions is date grouping. The problem is that when dates are stored in UTC you can’t easily group on date boundaries (ie. give me all orders from March 1st – 31st). If you do the grouping on the UTC date the date groups will be off by the UTC offset and you would end up with some orders falling into the wrong groups.

To get around this you need to convert dates to user adjusted local dates. Sounds easy enough, except that you can’t do these types of date conversions we’ve talked about in some LINQ data code because the various DB LINQ Providers don’t understand arbitrary .NET functions – they have a finite set of support functions that are translated into queries.

So if you take the previous result which contains all entries and all dates and run it to list you could then filter it down to only retrieve the last date for a given date:

// find all entries by last started date
var gresults = results
    .OrderByDescending(s => s.Started)
    .GroupBy(q=> user.GetUserTime(q.Started.Value.Date))
    .Select(group => group.First())
    .ToList();

You might think that this grouping would work in the first query but it won’t. MongoDb doesn’t support GroupBy queries at all (using LINQ anyway), and Entity Framework would choke on the User.GetUserTime() method call which it wouldn’t know how to convert to SQL.

So if you need to do internal query operations that require UTC date conversions that you can’t do with the date intrinsic functions you unfortunately have to resort to LINQ to Objects in memory to make the aggregations work.

What about DateTimeOffset?

A number of people commented asking about DateTimeOffset which is DateTime like class that is actually recommended by Microsoft to use as a DateTime replacement. DateTimeOffset stores the timezone offset of a date value with the date so you can always tell the timezone the date came from originally. One of the things about DateTimeOffset is that you have to use it throughout the system to be effective – both in the application layer and the data layer. SQL Server has a DateTimeOffset field type that matches the .NET type.

Personally I’ve never used DateTimeOffset because it only addresses a single scenario that I think doesn’t work very well for Web applications. DateTimeOffset is not all that useful in server applications where the timezone is fluent. If I enter a date in Hawaii, then later go to Oregon and want to see the date in the Oregon time zone format I still have to do the conversions mentioned in this post. Since DateTimeOffset only supports a single time zone,  you also have to get the date into the right time zone for saving first, since the server will capture dates using server local time. So you end up doing the time zone conversion up front, but then it’s stuck in that timezone. If a user moves across time zones, you’re back to doing conversions based on the UTC date part of the DateTimeOffset.

So in a fluent Web date environment where users are not statically tied to a timezone DateTimeOffset buys very little IMHO. To be honest I've not used DateTimeOffset much at all, because of the above issues, but maybe I'm missing something obvious.

Performance

One thing to consider is that time zone calculations are relatively slow. Compared to just grabbing a raw date value  like DateTime.Now and just using it or even adding some offset value to a date, time zone conversions add a fair bit of overhead. Times are still fast, but if you’re doing time conversions in tight loops for thousands of dates you will definitely see some overhead. Hopefully you’re practicing good view design and don’t ever display many thousands of records in the first place, which is your primary protection against the extra overhead.

John Skeet’s NodaTime

Realizing that the concepts of time in the .NET BCL are scattered about in various classes that aren’t quite optimal for doing time conversions, Jon Skeet created a separate Time system library called NodaTime. NodaTime makes the concept of a timezone a first class citizen where you pick a date based on the timezone and the date time format it presents. You can then easily convert between these formats. It’s a great implementation and definitely worth checking out, but it is a little more complex than the BCL DateTime/TimeZoneInfo implementations because it forces you to think about what kind of date you are dealing with before you assign it. But it requires some commitment – for it to work effectively, you essentially have to replace standard DateTime values with NodaTime types throughout your application.

In the end though the issues I discussed above still apply. You still have to decide when times have to be adjusted and how, so while NodaTime makes the conversions and management easier and more intuitive, it doesn’t free you from the application related issues that come up when you’re dealing with TimeZones in your application.

Using UTC in Applications

Using UTC dates for data is a pretty common and necessary practice but it definitely adds some complexity when managing dates as you always have to remember to properly adjust dates. For display purposes this is pretty straight forward, but for query operations there’s a bit of mental overhead to ensure your date math adds up properly.

No easy solutions, but I hope this post and some of the helpers make life a little easier for you – I know they do for me.

So what about you? Have any tips and tricks and best practices that have worked well for you to make managing UTC dates easier in your application? Leave a comment if you do.

© Rick Strahl, West Wind Technologies, 2005-2015
Posted in ASP.NET  C#  .NET  

by Rick Strahl at February 10, 2015 12:21 PM

Alex Feldstein

Photo of the Day


Pitts S-1-11 at North Perry

by Alex Feldstein (noreply@blogger.com) at February 10, 2015 06:00 AM

February 09, 2015

Alex Feldstein

February 08, 2015

CULLY Technologies, LLC

FoxCon 2015: My presentation on “Xojo for the Desktop and Web”

I had a great time at the FoxCon in Toledo. FoxCon is a long running invitation-only conference that historically came from the Visual Foxpro programming world. The conference has, pleasantly, transformed itself more into a technical business conference. Yes, there were sessions on programming and databases, but there were great presentations on Being More Productive as well as Sales And Marketing your business.

My presentation was intended to be on the technical side of the presentation list, to give a (very) brief overview of the Xojo product with greater focus on Web application development. I prepared a lot of slides for the presentation but attempted to get through the slides as quickly as possible. I understood that the attendees are going to be most impressed by seeing the actual demonstration of the Xojo programming development environment. After a brief and simple example of a web application, I headed into a more extensive sample application of “Eddie’s Electronics”. This demo application demonstrated more advanced web topics: database access and data display, dynamic image display, and Google Maps.

If you want to see a copy of the slides from my presentation, click here: Xojo for VFP Developers

After introducing the web edition application for a bit, I decided to “place my head into the lion’s mouth”. I was going to spin up a virtual server, FTP the application, launch it, and invite each of the attendees to hit the web application from whatever device they choose whether that is from a laptop of a phone device.

I created a Ubuntu 32bit Server at DigitalOcean.com and it was created in 27 seconds. I connected with the console application via the browser and logged in to change the password. Never has something been so difficult to type than that damned password. I eventually got it however and changed the password. I FTP uploaded the main Eddie’s Electronics application first. When that completed I started loading the supporting libraries. While those files were uploading, I set the execution privileges on the main application. I published a link to this application on my website to help ease the phone users enter into the site.

Bottom line is that we had 29 simultaneous connections all hitting the web application at one time, running on a $0.007/hour server. I had made some changes to the web application that logged out the hits, session ID, memory available, and the browser and OS of the visiting user. It was great seeing that scroll along on the screen.

Overall we had some great questions about Xojo, what it could do and what is is bit more difficult to accomplish. I really appreciated the opportunity to speak about a product that I’m passionate about.

by kcully at February 08, 2015 04:47 PM

Alex Feldstein

February 07, 2015

VisualFoxProWiki

LeslieKoorhan

Leslie Koorhan is a Microsoft Certified Professional, Trainer, Solutions Developer, Systems Engineer, and Database Administrator. He does consulting, development and training in DotNetOffsite link to http://gotdotnet.com (.NET) including ASP.NET, VB.NET, C#.NET and ADO.NET. Also XML/XSLT, Visual Basic, Active Server Pages and Microsoft SQL Server 2000. Leslie is the co-author of a HentzenwerkePress book on VFP and SQL Server (ISBN 1930919018). He is also co-author and technical editor of SAMS' "Teach Yourself Object - Oriented Programming in Visual Basic.NET in 21 Days (ISBN 0672321491)." Leslie also developed training materials on Microsoft SQL Server 2000, centering on Data Transformation Services (DTS) and Analysis Services. He also did the video for these courses and if you look hard enough, you can find a vendor who sells the video and courseware.

February 07, 2015 10:45 PM

DevCon13

Editor comments: Added speaker list
Pictures from VFP DevCon Ft. Lauderdale link broken -- Alex Feldstein
Pictures from the UT: https://www.universalthread.com/ViewPageAlbum.aspx?ID=4

February 07, 2015 08:56 PM

Alex Feldstein

February 06, 2015

FoxProWiki

DimensionsOfScalability

Editor comments: Found an old article on the Wayback Machine
Quick Synopsis: If volumes, or some other semantics of the system, are going to increase substantially during the life of your system, then you have a scalability issue. The question is not whether you will confront the issue, but when. Here are the key aspects of system scalability:

Classic Dimensions of Scalability
  • Data size. Sometimes also called size up.
  • Speed. Sometimes also called speed up.
  • Workload. Sometimes simply called scale up.
  • Transaction cost (See Transaction Time).

Less Common Dimensions of Scalability

February 06, 2015 05:53 PM

DrewSpeedieMemories

This is not an edit, it is a comment. It is hard to see inside the mind of another person. That's part of the human condition. Maybe Drew had darker demons than any of us understood. (Charles Hankey, who is as smart as anyone I have known. maybe saw the dark side before the rest of us). Maybe Drew did jump off that bridge. But he sure didn't take Brent with him. I saw the way they were together and he never, ever, EVER would have done that.

A place to remember...

Here's my favorite memory of Drew Speedie. It's actually more a memory of Brent. Years ago I entered a big Devcon session room shortly before Drew was to speak. The room, a big one, was almost totally PACKED, with few if any seats left, people standing along the walls, sitting in the isles, and the room was already pretty dark, just before Drew was to begin. I spotted Irene Speedie in the back right corner of the room near the door I just entered, with young Brent, aged maybe 5 years old, on her lap, waiting for the session to start. Brent was being so good, happily and quietly sitting on his mom's lap, not too interested or understanding what was going on. I approached them and I said "Hey Brent, how's it going?. Brent, do you realize that ALL these people are here to see *YOUR* dad? They've come from all over the world, some of them across oceans, to hear what he has to say. Isn't that amazing? Your dad is great, he's a STAR!". Brent's eyes lit up, he gave me the biggest grin, I ruffled his hair and walked away real happy to have told him that about his dad. In the years since, at every conference where I saw Brent, I like to think he remembered me, and that special moment, when someone confirmed what, surely, he already intuitively knew and believed about his dad. -- Steven Black

February 06, 2015 06:00 AM

Alex Feldstein