Planet FoxPro

May 27, 2015

Rick Strahl's Web Log

Interactive ASP.NET Resource Linking and Editing with Westwind.Globalization

One of the most effective ways to improve localization workflow in an application is to have easy access to resources from within a running application. It’s useful to see your resources, and then be able to click on the resource content and jump directly to editing that resource. Further it’s pretty nice to be able to switch an application into a specific language easily to see the results of localizations immediately.

I’ve been putting the final touches on the next version of my Westwind.Globalization library and one of the last pieces that were rebuilt have been the interactive resource linking features. Westwind.Globalization is a localization library for .NET that allows storing resources in various kinds of databases (MS SQL, MySql, SqLit, SqlCe) which makes it much more dynamic to create, edit and generally manage resources. Because the resources are in a database they can be easily edited and the resource linking feeds into this by making it possible to directly link your Web content to the localization resource administration form and the in-context resource.

This allows not only for localization, but also for basic CMS like features that allow for admin editable user content in the page. Together with the Markdown support for resources as a baked in feature of the library, it’s actually quite easy to build runtime customizable interfaces. It isn’t going to replace a full featured CMS system, but if you have a few pieces of content that need to be user editable in an otherwise custom coded site this can certainly provide that flexibility.

In this post I’ll describe how the resource linking features in Westwind.Globalization work as well as describe some of the logic of how it’s implemented. You might find this useful if you have a need in your own applications to link content quickly to other resources either on the web or in your own applications.

What is Resource Linking?

Let’s start by demonstrating what the resource linking features in Westwind.Globalization look like. Here’s a short animated GIF that demonstrates the typical workflow for resource editing:

The flag icons are links that bring up the Web based resource editor with the selected resource preselected. At this point the resource is in context with the cursor jumping directly to the editable resource text, ready for editing. In this redesign of the Westwind.Globalization the resource editor in particular has gone through a lot of tweaking to make it efficient to use via keyboard, so you can quickly navigate, add and edit resources without taking your hands off the keyboard. For example, pressing Ctrl-Enter saves the current entry and jumps to the next resource entry and tabs/shift tab cycle through the resource entries. If a resource doesn’t exist you’re jumped straight into the Add Resource dialog to add a new resource so no extra clicks to add.

To facilitate turning resource editing on and off in your own pages the library also provides a small JavaScript based button/icon to enable resource editing on the page. You can see the opaque icon on the bottom right of the page, which when clicked turns on the resource links on the page.

Hooking up the Resource Linking

To be clear, the resource linking in the example above does not happen automatically. It relies on at least one extra attribute on an element to designate an HTML element as ‘resource linkable’.

Whether you’re using client side or server side resources you still have to add the actual resource links (ie. Razor tags (@), WebForms Script (<%: %>), or client side binding expressions like Angular ({{ expr }} or ng-bind values) in order for resources to render. If you want resources to be linkable/editable  an additional attribute on either the actual element or a container where you want the edit icon to appear is also required.

The process works by requiring a data-resource-id and data-resource-set attribute to be present on elements. The data-resource-set attribute can exist either on the actual element or on any parent element in the DOM hierachy up the chain. If a data-resource-id  element is found, the a helper function searches out the data-resource-set and then proceeds to inject an element into the page that represents the resource link icon.

For typical pages this means that you can declare the data-resource-set at the body tag or other view level DOM element:

<body data-resource-set="LocalizationForm">

Then for each for the controls you bind you can just wrap the controls with data-resource-id attributes.

Here’s an example using server side Razor syntax in ASP.NET MVC or WebPages:

<body data-resource-set="LocalizationForm">
    <div class="page-title"
         data-resource-id="PageTitle">
        @DbRes.T("PageTitle", "LocalizationForm")
    </div>

    <span data-resource-id="HelloWorld">@LocalizationForm.HelloWorld</span>
</body>

The example demonstrates both the string based DbRes resource binding (which can use any configured Resource store including Resx interchangably in any application) and strongly typed resources.

Using WebForms you can use the same approach of marking up either wrapping HTML markup or the actual WebForms controls:

<label data-resource-id="MetaTag"> Meta Tag (meta:resourcekey= lblHelloWorldLabel.Text):</label>
<asp:Label ID="lblHelloLabel" runat="server" meta:resourcekey="lblHelloWorldLabel"></asp:Label>
            
            
<label data-resource-id="StronglyTypedDbResource">Strongly typed Resource Generated from Db (uses ASP.NET ResourceProvider)</label>
<span data-resource-id="HelloWorld">
    <%= Resources.HelloWorld %>      
</span>

This works fine is essentially identical to raw markup. If you are using meta:resourcekey tags, you can also use a custom WebForms control I’ll describe later on, that can automatically generate the data-resource-id link icon for any WebForms control that includes localizable properties.

Using a pure client side interface with AngularJs you can use the following:

<div>
    <p data-resource-id="CreateClassInfo">
        {{::view.resources.CreateClassInfo}}
    </p>
    <p data-resource-id="CreateClassInfo2">
        {{::view.resources.CreateClassInfo2}}
    </p>
</div>

You can apply the same mechanism to any other kind of client side template framework. This approach works with HandleBars templates or Ember scripting – heck it works with any kind of HTML. The resource linking can be attached to any HTML elements and works on both client and server side.

Adding resource edit links with data-resource-id is optional. It may not be necessary to expose every resource id this way, but using this declarative client side mechanism you have a choice of whether and where to add the resource editing feature if at all.

Advertisement

Getting the Resource Linking to Work

The markup above on its own doesn’t provide the linking features – a bit of script code and CSS markup is required to provide the logic and display features.

To get resource linking to work you need to do the following:

  • Add the required JavaScript references to your page
  • Add CSS to provide the Resource Link display
  • Enable Resource Editing by calling showResourceIcons()/removeResourceIcons() 
    or use the built in Icon/Button calling showEditButton()
  • Mark up elements to edit with data-resource-id and data-resource-set

Enabling Resource Editing with JavaScript

The JavaScript required to launch the resource edit linking is minimal. There are two approaches.

The first is to just add the resource edit button to the page and let it handle enabling and disabling edit mode (example uses an MVC Razor page):

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js" type="text/javascript"></script>
@if (allowResourceEditing)
{
    <script src="~/localizationAdmin/scripts/ww.resourceEditor.js"></script>
    <script>
        // enable resource editing - button on bottom right
        ww.resourceEditor.showEditButton(
            { adminUrl: "./localizationAdmin/" }
        );
    </script>
}

This adds the Resource Edit button shown in the animated gif above which is a nice drop in way to get resource editing to work with a one liner.

If you want more control and hook enabling and disabling of resource  linking to your own application logic you explicitly enable and disable the resource linking:

@if (allowResourceEditing)
{
    <script src="~/localizationAdmin/scripts/ww.resourceEditor.js"></script>
    <script>
        var toggleEditMode = false;
        $("#btnEditResources").click(function() {
            toggleEditMode = !toggleEditMode;
            if(toggleEditMode)
                ww.resourceEditor.showResourceIcons({ adminUrl: "./localizationAdmin/" });
            else
                ww.resourceEditor.removeResourceIcons();
        });
    </script>
}

Here you are hooking the click event of some button that can act as a toggle and call showResourceIcons() and  removeResourceIcons() to toggle the edit state.

Protect Access to Resource Editing

Note the server side allowResourceEditing variable in both implementations. You don’t want the public to edit your site :-) Since resource editing is rather an administrative task you’ll want to isolate the resource editing code so that only admin or otherwise authorized users have access to this functionality.

Adding the CSS

You’ll also need a bit of CSS for the resource link icons, and the edit toggle button/icon. The resource icons are rendered as absolutely positioned and layered transparently on top and slightly above the element that is wrapped which is managed through a bit of CSS.

.resource-editor-icon, .resource-editor-icon:hover,  .resource-editor-icon:visited {
    position: absolute;
    display: inline;
    height: 13px;
    width: 13px;     
    text-decoration: none;
    z-index: 999999;
    opacity: 0.35;
    margin: -14px 0 0 -2px;
    cursor: pointer;
}
.resource-editor-icon:hover {
    opacity: 1;         
}
.resource-editor-icon:before {
    font-family: fontawesome;
    content: "\f024"; /* flag */
    font-size: 9pt;
    color: red;        
}
.resource-editor-button { z-index: 999999; color: white; background-color: DarkGreen; opacity: 0.35; position: fixed; bottom: 10px; right: 20px; padding: 7px 9px 5px 10px; border-radius: 50%; } .resource-editor-button.off { background-color: #b64545; } .resource-editor-button:before{ font-family: fontawesome; content: "\f024"; /* flag */ font-size: 14pt; } .resource-editor-button:hover { font-family: fontawesome; opacity: 0.65; }

This CSS relies on FontAwesome for the flag icon. However, if you don’t use FontAwesome just remove the FontAwesome font reference and pick any other character:

font-family: arial; content: "#";

The edit resource button is rendered as a fixed position semi-transparent object that stays in the bottom right corner of the screen and is clickable at anytime to toggle the resource edit mode. When clicked resource icons appear and disappear depending on the status and the button itself changes color from green (active) and red (inactive).

How does it work?

Behind the scenes the ww.resourceEditor class is used to retrieve all data-resource-id elements in the page. When it finds one it picks out the data-resource-set and if both of those are available generates a new element into the page which is injected just before the element that holds the data-resource-id attribute. The element is absolutely positioned with the CSS so it sits right on top of the source element in the top left corner.

The generated HTML (minus the comments) looks something like this:

<!-- injected element -->
<res-edit class="resource-editor-icon"
          title="Edit resource: Add"></res-edit>

<!-- original element -->
<button class="btn btn-sm btn-default ng-binding"
        title="Add new ResourceSet"
        ng-click="view.onAddResourceClick()"
        data-resource-id="Add">
    <i class="fa fa-plus"></i> Add
</button>

I’m using a custom res-edit HTML element for the injected element rather than a link or other official tag to avoid styling interference. This minimizes layout CSS conflicts as much as possible, but it doesn’t eliminate them completely. In testing on a variety of forms and applications I find that in most cases the resource editing works fairly well, shifting things on the page slightly but not drastically. Because the resource editing feature is an optional attribute if there is a problem with a particular control you can always remove the attribute for editing, or create another element that more appropriately represents the proper location in the document if the element is crucial for editing.

The ww.resourceEditor.js that drives this code is installed alongside the LocalizationAdmin interface and referenced from there. You can check out the code on GitHub if you’re curious, but here is the relevant code that creates the resource links and embeds them into the page.

showResourceIcons: function(options) {
    self.removeResourceIcons();

    var opt = self.options;
    $.extend(opt, options);
    self.options = opt;

    var set = $("[data-resource-set]");
    if (set.length < 1) {
        console.log("resourceEditor: No 'data-resource-set' attribute defined");
        return;
    }

    var $els = $("[data-resource-id]");
    if ($els.length < 1) {
        console.log("resourceEditor: No 'data-resource-id' attributes found");
        return;
    }

    $els.each(function() {
        var $el = $(this);
        var resId = $el.data("resource-id");
        var pos = $el.position();

        var $new = $("<res-edit>")
            .addClass("resource-editor-icon")
            .css(pos)
            .data("resource-element", this) // store actual base element
            .attr("target", "resourceEditor")
            .attr("title", "Edit resource: " + resId)
            .click(self.showEditorForm);

        $new.insertBefore($el);
    });

    $(window).bind("resize.resize_ww_resourceeditor",
        function() {
            ww.resourceEditor.removeResourceIcons();
            ww.resourceEditor.showResourceIcons(options);
        });
},
removeResourceIcons: function () {
    $(window).unbind("resize.resize_ww_resourceeditor");
    $(".resource-editor-icon").remove();
},

The key feature is the element creation where the $new variable is created. The original element item is attached in the data element to provide a reference back to the original control which that the resource id references when the icon is clicked.

When clicked the target routine picks out the data-resource-id and data-resource-set and builds up a link which is navigated with a window.open() call:

showEditorForm: function(e) {
    e.preventDefault();

    var $el = $($(this).data("resource-element"));
    var resId = $el.data("resource-id");
    var resSet = $el.data("resource-set");
    var content = $el.text() || $el.val() || "";
    content = $.trim(content);

    if (content && content.length > 600)
        content = "";

    if (!resSet) {
        var $resSets = $el.parents("[data-resource-set]");
        if ($resSets.length > 0)
            resSet = $resSets.eq(0).data("resource-set");
    }

    window.open(self.options.adminUrl + "?ResourceSet=" + encodeURIComponent(resSet) +
        "&ResourceId=" + encodeURIComponent(resId) +
        "&Content=" + encodeURIComponent(content),
        self.options.editorWindowName, self.options.editorWindowOpenOptions);
},

Web Forms Support

The original versions of Westwind.Globalization were built in the age of Web Forms, and this new release distances itself a bit from the purely WebForms based approach. Nowhere is this more prominent than in this resource linking functionality. In the past I hooked into the meta-resource key architecture of Web forms which allowed the server side to automatically generate resource links for resources based on the any [Localizable] properties on any given control.

This process worked well at the time, but it’s extremely limited to WebForms for one, and also adds a ton of overhead on the server when resource icons are rendered as the processing has to walk the entire control hierarchy and scan for localizable attributes. Further it’s not always obvious where the resource icons should be displayed since in some cases the Localizable attributes might point at non-visible or related elements. In short, while it was nice for some simple cases there were also a host of problems.

In the new version of Westwind.Globalization you now have a choice between using the same mechanism I described above, of manually marking up HTML or Control markup using the data-resource-id and data-resource-set attributes. Using this mechanism you get full control over where the icons pop up and what they link to. You can decide which resource ids you actually want to link and you can ignore a bunch of the superfluous stuff that is localizable that nobody ever actually localized…

DbResourceControl

If you liked the old behavior using the DbResourceControl which enabled resource editing no a page by walking the control hierarchy, that control is still available, and has been updated to use the new client side attribute syntax for controls. So rather than generating the flag control HTML into the page at render time, the new version only renders the attributes on the relevant controls.

To use this you can add the localization control to the bottom of your page:

<loc:DbResourceControl ID="DbResourceControl1" runat="server" EnableResourceLinking="true" />

You still need to add the JavaScript scripts and edit activation code as before:

<script src="LocalizationAdmin/bower_components/jquery/dist/jquery.min.js"></script>
<script src="LocalizationAdmin/scripts/ww.resourceEditor.js"></script>
<script>
    ww.resourceEditor.showEditButton(
        {
            adminUrl: "./localizationAdmin"
        }
    );
</script>

Then any ASP.NET controls on a page  are automatically marked up with data-resource-id and data-resource-set attributes:

<div class="form-group">
    <label class="control-label" for="form-group-input">
        <asp:Label runat="server" ID="lblName" Text="Name" meta:resourcekey="lblName" /></label>
    <asp:TextBox runat="server" ID="txtName" Text="" class="form-control" />
</div>

<div class="form-group">
    <label class="control-label" for="form-group-input">
        <asp:Label runat="server" ID="lblCompany" Text="Company" meta:resourcekey="lblCompany" /></label>
    <asp:TextBox runat="server" ID="txtCompany" Text="" class="form-control" />
</div>

<div class="well-sm well">
    <asp:Button runat="server" ID="btnSumbit" Text="Save"  meta:resourcekey="btnSubmit" CssClass="btn btn-primary" />
</div>

The resource control will automatically pick up any ASP.NET control and add links to it, whether meta-resourcekey values are assigned to it or not. The generated icons will default to a .Text property if it exists, and otherwise use the first localizable property available.

Here’s what the above form looks like including the resource linking toggle and resource editing icons activated:

WebFormsResourceEdit

Note that using the DbResourceControl is totally optional. If you want you can use the same explicit resource markup syntax described earlier and as shown for MVC applications, by explicitly marking data-resource-id attributes on your controls or containers. This is more effort, but it gives you more control.

If you are heavily use meta-resourcekey attributes for your localization bindings, then using the DbResourceControl can be useful, but if you are using other mechanisms (like strongly typed resources) in your WebForms apps, then using direct data-resource-id is a better choice.

Summary

Efficient resource linking and editing can make for a much easier workflow when localizing applications. The ability to see resources in real time as you are editing them and what effect they have on the user interface can be an invaluable tool to make you more productive in your localization process.

When I redesigned this library my goal was to make the process of editing resources easy and efficient so that localization becomes a bit less of a pain both during development when getting the localizable content set up, as well as later on actually localizing that content. The goal has been to optimize the workflow and I hope that this has been accomplished in this iteration of the tool…

Resources

© Rick Strahl, West Wind Technologies, 2005-2015

by Rick Strahl at May 27, 2015 06:20 PM

VisualFoxProWiki

DBFViewer2000

Attention!
Be aware that this tool cannot and does not respect any validation or trigger rules. It basically ignores any dbc-based information! Since it also doesn't know about collating sequences, updating or altering your data could in reality damage your data; especially if unaware users are using this tool to access your data. -- wOOdy

May 27, 2015 07:18 AM

Alex Feldstein

May 26, 2015

Alex Feldstein

May 25, 2015

FoxProWiki

DBFViewer2000

Attention!
Be aware that this tool cannot and does not respect any validation or trigger rules. It basically ignores any dbc-based information! Since it also doesn't know about collating sequences, updating or altering your data could in reality damage your data; especially if unaware users are using this tool to access your data. -- wOOdy

May 25, 2015 04:53 PM

Alex Feldstein

May 24, 2015

Alex Feldstein

Rick Strahl's Web Log

Right To Left (RTL) Text Display in Angular and ASP.NET

rtlYesterday I got a request for my Westwind.Globalization library about better support for Right To Left (RTL) language editing. The request was a simple one: When editing resources in our resource editor the editor should support RTL display for any locale that requires RTL, which makes good sense. I’m as guilty as the next guy to sometimes ignore forget that not all languages use left to right to display and edit text.

Westwind.Globalization is a bit unique in its use of localized resources in that the front end app ends up displaying any number of resource locales simultaneously since we display all of the localized versions for each resource Id for editing.

After some experimentation on how to actually provide the RTL information to the client application I ended up with an UI that looks like this:

Notice the Arabic and Hebrew languages showing with Right to Left display and that can be edited that way as well.

ASP.NET RTL Language Detection

So how can you detect Right To Left support? In this Web Resource Editor resources are served from the server running an ASP.NET Web application and the backend has a routine that returns all resources matching a given resource id. So as I navigate resources a service call is made to return an array of all the matching resources. One of the properties returned for each resource is whether the locale Id requires RTL display.

The actual routine that returns a list of resources works like this:

[CallbackMethod()]
public IEnumerable<ResourceItemEx> GetResourceItems(dynamic parm)
{
    string resourceId = parm.ResourceId;
    string resourceSet = parm.ResourceSet;

    return Manager.GetResourceItems(resourceId, resourceSet, true).ToList();
}

The key is the ResourceItemEx class which is serialized to JSON in the result. Specifically ResourceItemEx contains an IsRtl property looks up RTL status based on the LocaleId using the following code:

public bool IsRtl
{
    get
    {
        var li = LocaleId;
        if (string.IsNullOrEmpty(LocaleId))
            li = CultureInfo.InstalledUICulture.IetfLanguageTag;
                    
        var ci = CultureInfo.GetCultureInfoByIetfLanguageTag(LocaleId);
        _isRtl = ci.TextInfo.IsRightToLeft;
                    
        return _isRtl.Value;
     }
    set
    {
        _isRtl = value;
    }
}
private bool? _isRtl;

This code looks up a Culture by its locale ID and queries the TextInfo.IsRightToLeft property to determine whether the language supports RTL or not which is the set on the internal value. This calculated value is then read for each of the resources, when the resource list is serialized.

Advertisement

The end result is this JSON that is served to the Angular client app:

[
  {
      "IsRtl": false,
      "ResourceList": null,
      "ResourceId": "HelloWorld",
      "Value": "Hello Cruel World",
      "Comment": null,
      "Type": "",
      "LocaleId": "",
      "ValueType": 0,
      "Updated": "2015-05-24T02:14:21.4396383Z",
      "ResourceSet": "Resources"
  },
  {
      "IsRtl": true,
      "ResourceList": null,
      "ResourceId": "HelloWorld",
      "Value": "مرحبا العالم القاسي",
      "Comment": null,
      "Type": null,
      "LocaleId": "ar",
      "ValueType": 0,
      "Updated": "2015-05-24T02:14:21.4396383Z",
      "ResourceSet": "Resources",
  },
]

This data is consumed by an Angular Service and Controller which eventually binds the data into the HTML UI.

RTL in the Browser

Browsers have Right To Left support using the dir HTML attribute that you can place on any HTML element or container.

<body dir="rtl">

The other options are ltr and auto the latter of which is the default and will be used depending on the user’s current locale configured in the browser.

You can also control RTL using the direction CSS tag:

.rtl {
    direction: rtl;
}

In most applications you are likely to apply explicit text direction either by automatically letting the browser take care of it or setting the value globally at a top level element like  body or html.

However, in my Web Resource Editor I need to display values for multiple locales in a single page so I have to specify the dir attribute (or CSS class that uses the direction style) on particular controls.

When the server returns the list of resources the HTML pages uses an ng-repeat loop to create a ‘list’ of controls that make up each ‘row’ for each resource id that consists of the locale Id label, the textarea and the save and translate buttons.

The RTL setting specifically needs to be assigned to the textarea control, and my first cut of this used a slightly messy Angular expression in the dir attribute:

<textarea id="value_{{$index}}" name="value_{{$index}}"
                class="form-control"
                data-localeid="{{resource.LocaleId}}"
                ng-model="resource.Value"
                dir="{{resource.IsRtl ? 'rtl' : '' }}">
</textarea>

resource in this $scope context is the ng-repeat item that’s the resource item retrieved from the service and resource.IsRtl holds the value to set binding to.

It works and sets the binding properly and I get my RTL bindings for the HE and AR text as shown in the original picture.

Creating a ww-rtl Angular Directive

While the above works fine, it’s kinda messy. You have to write conditional expression and use expression syntax. It turns out that this initial fix wasn’t the only place where this is needed. There are 5 or 6 other places (and counting) that also needed to apply this same behavior, so I figured it’d be nice to build something more reusable.

Ideally I’d want to simple say:

ww-rtl="resource.IsRtl"

The directive takes an expression that should evaluate to a boolean value. If the expression is true the control or element should get the dir=”rtl” attribute set, otherwise the attribute should be removed or blank.

While I’ve been using Angular for a while, I’ve not been creating a lot of directives, so it took me a little bit to figure out exactly how to watch a model value and detect when the model changes. The logic is quite simple actually, but it’s not quite so straightforward arriving at that simple solution due to the quirky API that Angular directives use (and which is why I haven’t been using it a lot).

The ww-rtl directive is essentially a binding directive, meaning that it needs to watch a binding value and then change DOM behavior when the value changes – specifically by applying the dir attribute to the element with the appropriate value.

Here’s the directive:

app.directive('wwRtl', function() {
    return {
        restrict: "A",
        replace: true,
        scope: {
            wwRtl: "@"
        },
        link: function($scope, $element, $attrs) {
            var expr = $scope.wwRtl;
            $scope.$parent.$watch(expr, function(isRtl) {
                var rtl = isRtl ? "rtl" : "";
                $element.attr("dir", rtl);
            });
        }
    }
});

Pretty small… and cryptic, yes?  Let me explain :-)

This creates a directive for ww-rtl (wwRtl), which looks only at attributes (restrict: "A"). The attribute itself is replaced (with nothing in this case). I create a private scope for this control and I bind the ww-rtl attribute to an wwRtl property on the scope.

The meat is in the link() function which sets up a watch that monitors the expression. The expression is the attribute value that I can just grab of the scope ($scope.wwRtl). I can assign that expression to the scope $watch() function which now monitors this expression for changes. Note I use the watch on the parent scope which contains the actual expression to evaluate (resource.IsRtl).

The $watch() function gets a callback whenever the watched expression changes and passes the new value into the callback. This value the result of the evaluated expression – ie. true or false in this case. Based on that value I can now change the elements dir attribute to rtl or blank and voila the Right to Left display of the control will change.

Here’s what the applied directive now looks like:

<textarea id="value_{{$index}}" name="value_{{$index}}"
            class="form-control"
            data-localeid="{{resource.LocaleId}}"
            ng-model="resource.Value"
            ww-rtl="resource.IsRtl">                    
</textarea>

And it works the same as the previous code but looks a lot nicer with more obvious intent.

Adding a Resource and RTL

As mentioned there are a few other places where RTL needs to be displayed. For example here’s the Add/Edit Resource form which also displays resource text:

ResourceEditRtl

and I can easily reuse the attribute here. When editing a resource, the ww-rtl attribute works great – I simply bind the existing resource.IsRtl value and it just works.

But – it’s not so straight forward with a new resource. The problem is that the resource.IsRtl property is not set from the server when a new resource is created, so IsRtl is not actually set accurately.

To fix this I added a server callback that’s fired when the use exits the locale field:

[CallbackMethod]
public bool IsRtl(string localeId)
{
    try
    {
        var li = localeId;
        if (string.IsNullOrEmpty(localeId))
            li = CultureInfo.InstalledUICulture.IetfLanguageTag;

        var ci = CultureInfo.GetCultureInfoByIetfLanguageTag(localeId);
        return ci.TextInfo.IsRightToLeft;
    }
    catch {}

    return false;
}

Note the catch block used in case the user puts in a locale that’s not supported on the server in which case we assume the default mode of LTR is used.

On the client side this is hooked up to a blur operation of the Locale Id text box:

<input type="text" class="form-control"
        ng-model="view.activeResource.LocaleId"
        placeholder="Locale Id"
        ng-blur="view.onLocaleIdBlur()" />

which is then hooked up with this controller method:

vm.onLocaleIdBlur = function(localeId) {
        if (!localeId)
            localeId = vm.activeResource.LocaleId;

        localizationService.isRtl(localeId)
            .success(function(isRtl) {
                vm.activeResource.IsRtl = isRtl;
            });
    },

The code uses a localizationService that fronts all the $http calls to the backend service which in this case is nothing more than an $http.get() call that handles any errors.

This works great – so now when the user enters a RTL locale ID (or the locale is already set to RTL) the textbox switches to RTL mode. Type an LTR locale and it flips right back to that format.

Simplify?

Using an API callback for this might be overkill. In my application which is an admin interface the overhead of an API call is minor. If it’s not for you you can try to just hardcode the handful of top level locales that are Right to Left:

ar,dv,fa,he,ku,nqo,pa,prs,ps,sd,syr,ug,ur

And cache them in an array. You can then check newly entered locale ids against the values in the array.

If you want to see exactly what specific locales on your machine are available that support RightToLeft you can try running this code (in LinqPad of course!):

void Main()
{
    foreach(var culture in 
            CultureInfo.GetCultures(CultureTypes.AllCultures)
                       .Where(c=> c.TextInfo.IsRightToLeft))
    {
        Console.WriteLine( culture.IetfLanguageTag + " " + culture.EnglishName);
    }
}

which should give you a good idea what locales require RTL.

Summary

Right to Left display may feel like an edge case for those of using Left to Right displays and I’m as guilty as the next person for not thinking of that when I initially created the Web Resource Editor in Westwind.Globalization. However, it was easy enough to add at least basic editing support for this functionality into the editor along with gaining some better understanding on how to apply RTL in browser based applications.

Resources

© Rick Strahl, West Wind Technologies, 2005-2015
Posted in Localization  Angular  ASP.NET  

by Rick Strahl at May 24, 2015 03:42 AM

May 23, 2015

Alex Feldstein

May 22, 2015

FoxProWiki

DraganNedeljkovich

Doing all sorts of programming since 1983, started messing with Fox in 1989 (mFoxPlus, if anyone remembers that one) and stayed with it into the next century.

Presently doing business as an independent consultant, and as a telecommunist since 2002. Speak Fox, Serbian (et al), WWWC, English, TSQL, Hungarian, Russian, MySQL, Java Script, jQuery. Available pretty much anytime: ndragan@ndragan.com - but not much, still busy all day doing Fox.


To those who followed my flag change on UT but don't remember exactly which was when: up to 1999, FRY (Federal Republic of Yugoslavia), 1999-2010 USA, 2010 and on - Republic of Serbia.

Website is not programming related at all, unless we count assorted programming jokes, and that it's almost entirely written in Fox (not dynamic, though, just generated text and automated FTP). The old blog called "A Yugo from the US: back in Serbia" was removed when the google changed rules one time too many.

May 22, 2015 12:31 PM

Alex Feldstein

Photo of the Day


Southern screamer (Chauna torquata) / Chajá
Zoo Miami

by Alex Feldstein (noreply@blogger.com) at May 22, 2015 05:00 AM

May 21, 2015

Rick Strahl's Web Log

Angular Select List Value not binding with Static Values

Ran into a problem converting from Angular 1.3 to 1.4rc a couple of days ago. The issue is that the way ng-model bindings work has changed, in that Angular 1.4 and later uses exact type matching for value comparisons which results in behavior changes. In my case I ran into a problem with static list values binding to a non-string value which caused the binding to effectively not work at all. Here's what the problem is and how to work around it.

by Rick Strahl at May 21, 2015 10:57 PM

Alex Feldstein

May 20, 2015

Alex Feldstein

May 19, 2015

FoxProWiki

CraigBerntson

Craig Berntson
3399 W. 3470 S.
Salt Lake City, UT 84119
801-699-8782
email: craig@craigberntson.com

http://www.craigberntson.com

Visit my blog, Developer.Blog() at http://http://blogs.msmvps.com/craigber/

Author, "Crys Dev: A Developer's Guide to Integrating Crystal Reports" from Hentzenwerke Publishing.
Coauthor, "Continuous Integration in .NET" for Manning.
I have also written for Fox Talk and the VFUG newsletter.

I currently write the "Software Gardening" column for .NET Curry Magazine (http://www.dotnetcurry.com)

I was a Microsoft Most Valuable Professional for Visual FoxPro from 1996-2010, when I became a Visual C# MVP. As of 2015, a .NET MVP.
I am Grape City Community Influencer

My company, Mojo Software Worx, provides consulting from the C-suite down to the dev team. Our primary business is helping your dev team get better, but we also provide custom programming services.

I have spoken on Microsoft technologies since 2000 across the US and in Canada and Europe. Some events I have spoken at:
- GermanDevCon
- Prague DevCon
- FoxCon
- Dev TeachOffsite link to http://devteach.com
- Great Lakes Great Database Workshop
- Essential Fox
- Dev Essentials
- DevLink
- PrairieDevCon
- Codepalusa
- DevConnections
- KCDC
- User Groups
- Code Camps


Currently, I am a Senior Software Engineer for Quicken Loans.

I was the president of the Salt Lake City Fox User Group for over 10 years.


Most Valuable Professional
Microsoft Certified Solution Developer

May 19, 2015 03:43 PM

JSONParser

Editor comments: fixed problem with code not displaying.
More changes: added support for arrays instead of collections

May 19, 2015 02:32 PM

Alex Feldstein

May 18, 2015

VisualFoxProWiki

DelLee

Del Lee is currently employed as Supervisor, Information Technology at BenefitFirst where he oversees a team of Web Developers, Infrastructure Specialists, and Data Analysts. For over 20 years, he was the IT Manager and Cost Analyst for a Plastics Manufacturer in Lexington SC, actively developing with VFP, Visual FoxExpress, and SQLServer.

Del has an MBA specializing in Operations Management and a BS in Engineering from the University of South Carolina.

Del has strong Christian beliefs and strives to follow the example of the Bereans, who sought to confirm what they heard (Acts 17:11). For fun, he enjoys playing tennis, following Gamecock football, watching his kids play soccer, and plays piano.

dlee AT deltonlee.com
Del on LinkedIn

May 18, 2015 04:00 PM

JSONParser

Editor comments: replaced v === null with v == null
More changes: added support for arrays instead of collections

May 18, 2015 03:00 PM

Alex Feldstein

May 17, 2015

Alex Feldstein

Miami Cityscape

Even though I have lived here for over 30 years, it always amazes me how Miami has grown. If you have not visited in years you would be surprised too.

Yesterday I visited Virginia Key and shot these from the Rickenbacker Causeway bridge.

Here we have three panoramic shots and I can't decide which I like best
(click on each for original size - warning decent bandwidth required! They are big, The last one is 20MB!)

2-shot pano


4-shot pano


7-shot pano

You can see the port and a Carnival Cruise ship on this one

All shot with Nikon D700 - 80-400 VR1
Processed and stitched with LR + PS + Topaz Adjust and Topaz Clarity
Each started as 3 HDR RAW shots, in LR CC, then the resulting DNGs where stitched with LR CC

Which one do you like best?

You can see more of these series in my gallery:
http://www.alexfeldsteinphotography.com/Florida/Miami

by Alex Feldstein (noreply@blogger.com) at May 17, 2015 11:01 AM

BB King wil always be remembered


Rock Me, Baby
BB King with Eric Clapton, Buddy Guy, and Jim Vaughn

by Alex Feldstein (noreply@blogger.com) at May 17, 2015 10:02 AM

May 16, 2015

Alex Feldstein

Beth Massi - Sharing the goodness

Trip Report: //BUILD and Ignite Conferences

Wow, what a busy last few weeks (months for many of us) as we prepped and delivered a couple huge events with BUILD and Ignite. I had the pleasure of being involved with the planning around our .NET content and community event at BUILD and I also got to get up on stage with my manager for the first time and deliver a foundational (read: Overview/What’s New) session at Ignite.

I thought I’d write up my thoughts on my experience at both conferences as well as point out some of my favorite sessions and helpful links along the way.

//BUILD

image

There were a lot of great announcements, downloads, and more OSS goodness at //BUILD this year. Like:

I noticed attendees were excited about the direction of .NET and being open source and were generally familiar with our prior announcements and posts on the .NET Team Blog. They were looking at the next level: how the projects were coming along and how to get involved. Common questions I got were…

image

I also got to do a Channel 9 “Live” interview on the .NET Foundation. I’ve done so many recording where I’m the interviewer, it was fun being the interviewee this time. VERY classy, professional production. And Seth Juarez, the new Channel 9 host, was AWESOME. I was up there with Jay Schmelzer, Immo Landwerth and Martin Woodward (also on the .NET Team with me). Jay is also the President of the .NET Foundation, Immo is on the Advisory Council and project lead for CoreFx and Martin is the Executive Director of the .NET Foundation. I’m officially the “secretary” but I rather call myself the Technical Evangelist :-).

Check out the interview here: .NET Open Source Initiative

image

There were also a TON more .NET related sessions at BUILD. Check out them all here.

“After Hours” Community Event

The goal of this event was to speak to the local community as an evening (i.e. after work) free user group presentation & social event, utilizing speakers & experts that were at BUILD. We partnered with the local field evangelism team that helped book an amazing venue. Our message centered on .NET innovations + cross-plat + OSS to educate and energize the local community about .NET and the .NET Foundation.

Speakers were divided into four presentations:

The presenters were AWESOME. We had 268 attendees and 90% of them were local SF so that was great to see. Check out some of the tweets: https://twitter.com/search?q=%23AfterHoursAtBuild&src=tyah

Scott and Damian were awesome as always and showed us how to get started with ASP.NET 5 and .NET Core running on Linux. Then they fielded questions for about 20 minutes. Immo and Phil took time to show us how the .NET team is working (successfully) with the community on GitHub. Geoff Norton, our top community contributor, was also really awesome, telling a good, honest story and is a super likable guy. On behalf of the entire team, Immo and Phil thanked him for his amazing contributions.

My personal favorite speaker was Chris Wanstrath CEO of GitHub. He delivered a motivational speech to all those people that were “afraid” of contributing to OSS. He said we’ve all been there, afraid of what people will think of your first contribution, it’s tough out there. It’s our jobs to change that. That really resonated with me.

clip_image001[7] clip_image002 clip_image003 clip_image001[11]

Ignite

Let me first say that Chicago is my kind of town, baby! We had pretty great weather and I made it out to a Sox game which was fantastic (Cubs were on the road, but I did ride a bike by Wrigley field). Of the 23,000 people there (wow), about 15% were developers.

.NET OSS & Cross-platform support also had a huge interest here and I did a lot of pointing people to our repos. Even VB developers I spoke with were excited to learn that the future of VB.NET is being planned out in the open on the Roslyn repo, and of course I encourage all the VB devs out there to get involved. Please! :-)

Jay and I made a great team on stage. Demos resonated with people and we got great attendance (almost 600 people) and great comments (which is a relief because Jay was reading them too ;)). This was a whirlwind tour of a ton of stuff in on the Microsoft stack, .NET, Visual Studio, including modern mobile and web development across platforms.

Watch: An Overview of the Microsoft Application Platform for Developers and Watch the rest of the Developer-focused sessions here.

image

Of course, no trip to another city is complete without baseball. :)

clip_image001[15] clip_image001[17]clip_image002[8] clip_image003[7]

Thank you San Francisco and Chicago, see you next time!

Enjoy!

by Beth Massi - Microsoft at May 16, 2015 12:26 AM

May 15, 2015

Alex Feldstein

B.B. King dies at 89

B.B. King in 2009.jpg
"B.B. King in 2009" by Tom Beetz - http://www.flickr.com/photos/9967007@N07/6577873073. Licensed under CC BY 2.0 via Wikimedia Commons.


So sorry to hear the news. I listen to BB King's Bluesville on XM Radio every day on the drive to work.

We'll have your music forever BB. Thanks for your passion.

http://www.nytimes.com/2015/05/16/arts/music/b-b-king-blues-singer-dies-at-89.html

by Alex Feldstein (noreply@blogger.com) at May 15, 2015 09:02 AM

May 14, 2015

Alex Feldstein

May 13, 2015

Alex Feldstein

May 12, 2015

FoxCentral News

West Wind Client Tools 5.72 released

 West Wind Technologies has released version 5.72 of West Wind Client Tools. Client Tools provide a host of Internet functionality to FoxPro applications including support for SMTP email, rich HTTP access, FTP up and downloads as well as high level REST, SOAP and HTTP based data services. The toolkit also contains many utility classes including a simple business object layer, SQL Server data access wrapper, .NET bridge helper to access .NET code from FoxPro, JSON and XML serializers, PDF rendering and more. This update adds a new wwEncryption class, provides big performance enhancements to the JSON serializer and adds many enhancements to the wwDotnetBridge functionality as well as a host of important bug fixes. Updates are free to registered users of version 5.0 and later, and a free shareware version is available for download to check out the product.

by West Wind Technologies at May 12, 2015 09:49 PM

Alex Feldstein

May 11, 2015

Alex Feldstein

Photo of the Day


Airbus A320 - "Bada Bing Bada Blue"
Ft. Lauderdale

by Alex Feldstein (noreply@blogger.com) at May 11, 2015 05:00 AM

May 10, 2015

Alex Feldstein

May 09, 2015

Articles

Upgrade to Xubuntu 15.04 - Vivid Vervet

Running an operating system like Ubuntu or any of its derivates, like ie. Xubuntu, comes with some nice treats (and threats?). One of the nice things is that you'll get a scheduled upgrade approximately every six months. Usually, around April and October of each year. Meaning there are two releases per year resulting in those version numbers [Year].04 and [Year].10. Also, ever two years the April edition of Ubuntu is classified as a Long-Term Support (LTS) version which keeps an extended period of time. A nice touch and surely interesting for professional installations of Ubuntu but eventually not too practical for the daily use at home or when you're interested in latest versions.

Preparing the system

These steps are the same every time you decide to upgrade to the latest release. Eventually, you might be interested to update older installation and have a read here: 

In general, you should have a look at the official upgrade documentation of Ubuntu. Next, get your recent system up-to-date before you consider to upgrade. Also, take care that there are no pending partial upgrades or packages on hold. This might have a negative impact on the installation process of the newer packages. So, before you think about upgrading you have to ensure that your current system is running on the latest packages. This can be done easily via a terminal like so:

$ sudo apt-get update && sudo apt-get -y dist-upgrade --fix-missing

xubuntu 1504 uptodate

Next, we are going to initiate the upgrade itself:

$ sudo update-manager

As a result the graphical Software Updater should inform you that a newer version of Ubuntu is available for installation.

xubuntu 1504 uptodate

Ubuntu's Software Updater informs you whether an upgrade is available

Running the upgrade

After clicking 'Upgrade...' or 'Yes, Upgrade Now' you will be presented with information about the new version.

xubuntu 1504 uptodate

Details about Ubuntu 15.04 (Vivid Vervet)

Simply continue with the procedure and your system will be analysed for the next steps.

xubuntu 1504 uptodate

Analysing the existing system and preparing the actual upgrade to 15.04

xubuntu 1504 uptodate

Next, we are at the point of no return. Last confirmation dialog before having a coffee break while your machine is occupied to download the necessary packages. Not the best bandwidth at hand after all... yours might be faster.

xubuntu 1504 uptodate

Are you really sure that you want to start the upgrade? Let's go and have fun!

Anyway, bye bye Unique Unicorn and Welcome Vivid Vervet!

In case that you added any additional repositories like Medibuntu or PPAs you will be informed that they are going to be disabled during the upgrade and they might require some manual intervention after completion.

xubuntu 1504 uptodate

Ubuntu is playing safe and third party repositories are disabled during the upgrade

Well, depending on your internet bandwidth this might take something between a couple of minutes and some hours to download all the packages and then trigger the actual installation process. In my case I left my PC unattended during the night.

xubuntu 1504 uptodate

At the end Xubuntu will ask you whether you would like to remove old and obsolete packages of the previous version.

xubuntu 1504 uptodate

Time to reboot

xubuntu 1504 uptodate

Finally, it's time to restart your system and see what's going to happen... In my case absolutely nothing unexpected. The system booted the new kernel 3.19.0 as usual and I was greeted by a new login screen.

Honestly, 'same' system as before - which is good and I love that fact of consistency - and I can continue to work productively. And also Software Updater confirms that we just had a painless upgrade:

xubuntu 1504 uptodate

System is running Ubuntu 15.04 - Vivid Vervet - and up to date

See you in six months again... ;-)

Post-scriptum

In case that you would to upgrade to the latest development version of Ubuntu, run the following command in a console:

$ sudo update-manager -d

And repeat all steps as described above.

by Jochen Kirstaetter (jochen@kirstaetter.name) at May 09, 2015 05:13 AM

Alex Feldstein

May 08, 2015

Alex Feldstein

May 07, 2015

FoxProWiki

PhiladelphiaVFPUserGroup

Editor comments: May--RickSchummer on IntelliSense
Starting in August 2008, we meet the second Tuesday of the month.

A user group for Visual FoxPro developers in the greater Philadelphia area, including New Jersey, Delaware and the Lehigh Valley. We meet the second Tuesday of each month at 7 PM.

Beginning with the April 2006 meeting, there is a $5 charge per meeting.

Beginning with the July 2011 meeting, we will meet in room 158 at DeVry University, 1140 Virginia Drive, Fort Washington, PA. Beginning with the October, 2014 meeting, we're moving to room 104 at DeVry.

Feel free to bring something to eat and arrive as early as 6:30.

Check out our blog at vfpphilly.blogspot.com.
We're on Twitter: @VFUGPhilly

If you'd like to speak at our group or join our email list, send a message to tamar@tamargranor.com

May 07, 2015 09:38 PM

UpcomingEvents

Editor comments: Philly May
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.

May 07, 2015 09:37 PM

FoxCentral News

Philadelphia VFP User Group--May 12: Rick Schummer on IntelliSense

The next meeting of the Philadelphia VFP User Group will be Tuesday, May 12 at 7:00 PM in room 104, DeVry University, 1140 Virginia Drive, Fort Washington, PA. Feel free to come as early as 6:30 and bring some dinner. Rick Schummer will present the ?director?s cut? of his Southwest Fox 2014 session ?Inspiring Everyday Practical IntelliSense.?

by Philadelphia Visual FoxPro User Group at May 07, 2015 08:39 PM

VFP Philly

May 12--Rick Schummer: "Inspiring Everyday Practical IntelliSense"



Our next meeting will be Tuesday, May 12. Rick Schummer will present the “director’s cut” of his Southwest Fox 2014 session “Inspiring Everyday Practical IntelliSense”

Abstract: Microsoft introduced Visual FoxPro's highly extensible IntelliSense capability 14 years ago with the release of Visual FoxPro 7.0. I remember seeing the first live demo of IntelliSense at DevCon and recall the chills it sent up my spine because I knew this new feature would instantly make me more productive. This single VFP feature has been heralded as "the greatest thing since sliced bread" and is, at least in my mind, the single biggest productivity boost to developers. Yet to this day I feel I under-use it and wish I would take the time to make things better for myself.

This session reveals how IntelliSense works using scripts and settings, and how it can be implemented, using real world examples authored by numerous Visual FoxPro developers. The implementation will be demonstrated and analyzed with the number one goal of inspiring you to boost your own productivity in the VFP IDE, and later to share those items that might help other developers in the FoxPro community.

Discover the details needed to take advantage of Quick Info, Member Lists, Command and Keyword expansion, Types, and MRU Lists. Techniques include leveraging the FoxCode object, text merge, and more. If time allows, we will explore other IntelliSense implementations and extensions like MY, IntellisenseX, ISX, and FoxCodePlus.


Bio: Rick Schummer is the president and lead geek at White Light Computing, Inc., headquartered in southeast Michigan, USA where the team guides the customer's Information Technology investment toward success. He enjoys working with top-notch developers, thrives on the mode of continuous learning, has a passion for developing software using best practices, strives to surpass customer expectations, and shares his knowledge with others whenever he can. After hours you might find him creating developer tools that improve developer productivity, or writing articles for his favorite technology journals and his blog.

Rick is a co-author of VFPX: Open Source Treasure for the VFP Developer, Making Sense of Sedna and SP2, Visual FoxPro Best Practices for the Next Ten Years, What's New In Nine: Visual FoxPro's Latest Hits, Deploying Visual FoxPro Solutions, MegaFox: 1002 Things You Wanted To Know About Extending Visual FoxPro, and 1001 Things You Always Wanted to Know About Visual FoxPro. He is a regular presenter at user groups across North America and is founding member and Secretary of the Detroit Area Fox User Group (DAFUG). Rick is the lead organizer of the Southwest Fox Conference, and is a regular presenter at other conferences in North America, Europe, and Australia. He is an administrator of VFPX, and a Microsoft Visual FoxPro MVP from 2002 to 2011. Rick was awarded the FoxPro Lifetime Achievement Award in October 2010.


by Tamar E. Granor (noreply@blogger.com) at May 07, 2015 08:35 PM

Alex Feldstein

Kevin Ragsdale's FoxPro Blog

Southwest Fox 2015 Speakers and Sessions

Speakers and sessions for the Southwest Fox and Southwest Xbase++ conferences have been announced! The Southwest Fox 2015 Conference has fewer speakers and tracks this year (eight and two, respectively), but there is a chance that more speakers could be added, depending on the number of registrations by July 1st. The list of speakers for 2015 … Continue reading Southwest Fox 2015 Speakers and Sessions

The post Southwest Fox 2015 Speakers and Sessions appeared first on Kevin Ragsdale.

by Kevin Ragsdale at May 07, 2015 02:40 AM

May 06, 2015

VisualFoxProWiki

AndyKramek

British-born, now resident in Akron, OH. Co-owner (with wife Marcia Akins) of Tightline Computers, Inc. a consulting group specializing in Client - Server systems and application development.

May 06, 2015 08:22 PM

Shedding Some Light

Southwest Fox/Xbase++ 2015: Speakers and Sessions

Geek Gatherings LLC posted the speakers and the sessions they are assembling for your learning pleasure this October. Head over to Speakers, Southwest Fox sessions and Southwest Xbase++ sessions for all the details. A terrific line up of top notch presenters and some outstanding topics. Registration will open June 1st with the same prices as last year. We are meeting at the same conference center and hotel as last year too.

I am giving my usual and timely updated VFPX.Edition(“2015″) session and a brand new productivity session called Your Developer Life Improved By Thor, which I am very psyched about.

White Light Computing is a Platinum Sponsor again, our 12th straight sponsorship of Southwest Fox. White Light Computing is also doing two $150 scholarships to two lucky attendees that register before the July 1st deadline (get the Super-Saver rate for sure).

There are ways to help promote the conference, and please send any testimonials you might take time to write to: info [AT] geekgatherings.com. Please get the word out at your office, at user groups, on the various community forums, and any other place developers get together. We appreciate all the help and support you can offer.

Already looking forward to the conference this year as there are some terrific offerings and fun planned. Only 161 days until we gather in Gilbert.

by Rick Schummer at May 06, 2015 05:59 PM

Alex Feldstein

May 05, 2015

FoxCentral News

Southwest Fox/Xbase++ 2015: Speakers and Sessions

Speakers (http://www.swfox.net/speakers.aspx) and sessions have been announced for Southwest Fox (http://www.swfox.net/sessionsswfox.aspx ) and Southwest Xbase++ (http://swxbase.net/sessionsswxbase.aspx). Registration opens soon; send an email to info@geekgatherings.com if you want us to email you when it's ready. See you in October!

by Southwest Fox Conference at May 05, 2015 09:16 PM

Rick Strahl's Web Log

401 Response from ASP.NET Identity when linking to External Accounts

A couple of days ago I ran into an odd problem where all of my external ASP.NET Identity providers would fail to redirect to the external provider login URLs. Instead the app fired empty 401 requests without any other indication of failure. It turns out this was a misconfiguration issue, but it took a bit to track this down due to the fact that there's no error trapping and no error information. Here's more info on this edge case failure.

by Rick Strahl at May 05, 2015 07:53 PM

Doug Hennig

Southwest Fox and Southwest Xbase++ 2015 Speakers and Sessions Announced

Speakers and sessions for both conferences have been announced.

As Tamar blogged a few weeks ago, this year was the hardest it’s ever been to select speakers and topics. Not only were the submissions outstanding, economics have forced us to cut back on the number of speakers a little this year (although as Tamar notes, we’ll change that if registrations before July 1 allow us to do so).

Some sessions I’m personally looking forward to seeing are:

  • Toni’s An Introduction to SQL Server Reporting Services: I haven’t played with SSRS much so this sounds like a great introduction, and Toni is such a great speaker. I’m not sure I’ll be able to attend—it’s a morning pre-con session and we’re usually busy with registrations on Thursday morning—but I’ll try.
  • Christof’s GemBox: An Alternative to Microsoft Office Automation: another topic I’m very interested in. Christof is a speaker’s speaker: his sessions are always insightful and well-researched. Another pre-con so again I may not be able to make it; if not, I know his white paper will be top-notch.
  • Cathy’s Extending VFP Reports with XFRX and VFP Reports: A Potpourri of Cool Ideas: I’ve been using XFRX for more than 10 years and my company’s product, Stonefield Query, uses it extensively. However, Cathy’s session touches on some features I haven’t used, including its drawing API. Her potpourri session sounds like it’ll discuss how to do some really complex things that only Cathy can figure out how to do. I always learn a lot in Cathy’s sessions so these two should be gold.
  • Phil’s The New Rules of Marketing and Sales: last year, Phil hit it out of the park with his SWFox sessions. I’ve already implemented some of the tips he presented to great success (and by that I mean making money!), so I’m expecting this year’s session to be equally as great.

I’m also really interested in Tamar’s Can't This Application go any Faster? and Rick’s Your Developer Life Improved By Thor sessions, but hopefully they’ll present those sessions at the German DevCon in November so I can use those timeslots at SWFox to see other sessions.

Registration opens soon; send an email to info@geekgatherings.com if you want us to email you when it’s ready. See you in October!

by Doug Hennig (noreply@blogger.com) at May 05, 2015 07:50 PM

Alex Feldstein

May 04, 2015

CULLY Technologies, LLC

Resizing VirtualBox VM on Linux Host

I’m needing more space for my Windows 7 virtual machine that is being hosted on my LinuxMint 17 laptop. Yup, the Window$ patches have piled up and are using a huge amount of space in my 50Gb VM. Micro$oft recommends that you don’t remove these files. They hang around forever.

I’ve got my VM set up with a VMDK file. Resizing the VM ends up with an error message of 0%...
Progress state: VBOX_E_NOT_SUPPORTED
VBoxManage: error: Resize hard disk operation for this format is not implemented yet!

Here’s the steps it took to get it working. The trick is to get the VMDK converted over to a VDI and then join that to the VM.

  1. Open a terminal and change to your VirtualBox Virtual Machine directory.
  2. Change your VM by issuing this command:
    vboxmanage clonehd "{YourVMMachine}.vmdk" --format VDI "{YourVMMachine}.vdi"
  3. Resize your VM by issuing this command:
    vboxmanage modifyhd --resize {NewSizeInMb such as 81920} "{YourVMMachine}.vdi"
    In this example, I’m resizing this to 80Gb of space by entering “81920”.
  4. Start up the Oracle VM VirtualBox Manager
  5. Click on your VM, and then click on the “Storage” section.
  6. Click on the “Controller” section, and then click on the icon next to the “Hard Disk:” port. Select the “Choose a virtual hard disk file…” and choose your new VDI file.
  7. Choose the “OK” button to apply your changes.

I hope this helps you make the most of your VirtualBox VMs.

by kcully at May 04, 2015 07:59 PM

Articles

Mugg & Bean - Nightmare at Bagatelle

It took me quite some while to decide whether I should write about this culinary topic or not. In general, I try to keep it like Thumper - "If you can't say something nice, don't say nothin' at all..." but unfortunately this won't change the situation in the first place and second, it's not recommended to hold back (constructive) criticism in order to assist to improve things. In case of Mugg & Bean at Bagatelle particularly it's already since a very long time that I'm saying nothin'...

Bright and shiny opening

Mugg & Bean isn't new to myself at all. I've been to M&B in South Africa several times and having the news that there'll be a franchise in Mauritius was very welcoming. Even though I skipped the opening period on purpose for various reasons I have to admit that the initial service, offerings and gusto was to my personal liking. Surely, a place to recommend among friends and family. We have been there on several occassions and the overall experience right at the beginning was positive. You know, this typical feel-good feeling after having had a nice meal and pleasant waitron service.

Where's light, there're shades

Unfortunately, M&B's lucky strike didn't last for long and personally I had the impression that the decline started as soon as the initial management and trainers from South Africa left the building, or better said flew back. The first disappointing visit happened for a lunch break together with my BWE and my dear mother. Well, you know lunch break, you'd like to go out and instead of grabbing a sandwich from the super market or picking some snacks from the merchants on the street, we decided to stop by at M&B to have a quick bite. Hm, talking a quick... it was only our patience that went away quickly. First of all, in an half-filled restaurant with many empty tables left we were seated but not asked for drinks. Finally, after roughly 20 minutes someone of the waitron staff remembered that new guests have arrived and brought us menu cards and asked for the drinks. It's not like we were hungry and eventually might have limited time for a lunch break but okay at least we a waitress now. The drinks were brought after another 20 minutes in, and then we were finally allowed to place our orders for food. Seriously? Round about 40 minutes just sitting there and waiting for soft drinks and/or juices? And obviously, we were not the only ones. A couple two tables next to us had to wait approximately 30 minutes for their drinks. Alright, as we were sitting nicely and had some topics to talk about we waited patiently for our dishes... Oh boy, you might have guessed it. Another 35 minutes later the first two plates were brought over, and then another 5 minutes later the missing third one. I won't go into the details but there were bits and pieces wrong and we couldn't be bothered because of being too hungry to argue. Besides having a second, more weird waiter which seemed to have a personal pleasure in terms of sneaking up on guests from behind repetitively, all three of us had probably the worst lunch ever. And to close that horrible lunch "experience" we had to wait another 25(!) minutes between asking for the check and finally being allowed to pay.

Regular location for meetings of MSCC and LUGM

Well, surely this lunch event must have been an exceptional experience you'd might argue. Hm, I wished it would have been... Let's talk a little bit about my involvement in local IT communities, namely Mauritius Software Craftsmanship Community (MSCC) and the Linux User Group of Mauritius/Meta (LUGM). We have this habit to organise little get-togethers of six to ten people and meet at an easy accessible location. Frankly, some love the bottomless caffee at Mugg & Bean and therefore we arranged quite a number of meetings over there. As the kids are with me on Saturdays I have to take care of their well-being and nutrition. Okay, the food selection even for children is quite tempting and after all it's about having a good time. Despite the business generated for the restaurant. Personally, I'm a fan of milk-shakes... and it would have been great that M&B would be able to deliver but quite frankly over a period of at least six (6!) months I was always told that the machine is broken and that milk-shakes cannot be served. Okay, I can understand that things break and it takes a little bit longer to get them fixed up here on this remote island but... more than six months? A well-known brand like Mugg & Bean? And the shakes are still offered according to their menu cards? Come on! Just put a blank sticker over drinks or meals you cannot serve...

But that's not all... choosing other drinks or menus randomly from the menu ended up in a simply answer by the waitress: "Sorry, it's not available". I finally gave up, and started to ask what's available today without even bothering to look at the card anymore. And despite the declining trend of drinks and dishes it became obvious that the standards of cleanliness followed the same trend. Guests had to leave the restaurant in order to lighten their pressure around the hips - for several weeks or even months because the rest room upstairs was in a bad state! Sitting near the big window panels with a view on the fountain outside revealed a disgusting observation of grease on the door panels in the cake and tart section. Cups, plates and cutlery usually had a stain from previous meals, too. And finally, one of our MSCC members got some extra nutrition in his pot of tea which submerged in his cup after pouring the final drops of green tea... boiled cockroach!

Not surprisingly, any meetups of both user groups were done at other locations in Bagatelle. And there are plenty of other blog articles and photos documenting on that one, too.

New management - maybe a fresh wind of service?

During the MSCC meetup on entrepreneurship back in August 2014 one of the attendees mentioned that he's very close to the current manager of Mugg & Bean and that the new person in charge would like to meet and listen to our previous experience. Alright, we agreed on a time and location somewhere else in Bagatelle and had a great conversation about the stories you just read in the previous paragraphs. Funny side-note: The M&B manager had a fidelity card from that other cafe. Which might tell you a lot actually...

Honestly, I didn't bother to follow up on any kind of improvements but only by listening to other MSCC craftsmen about their recent visits, gave me enough information that it wouldn't be worth to spend any further time at that place. Not now, not in the future.

Granting a wish... 

... I guess that might be the only explanation why I finally agreed this morning to give it another shot. My BWE was already "chasing" me since weeks that she'd love to have a proper breakfast in the morning compared to the range of small bites at Vida e Caffe, also at Bagatelle. Since months, the weekly Code & Coffee meetings of the MSCC have been carried out at the little cafe opposite the Emtel showroom, and so far it had been always great. Even though the music might be too enthusiastic sometimes but the staff is always friendly and pays attention to their clients' demands.

Anyway, judgement day at Mugg & Bean... all those months I could convince my BWE that it wouldn't be an option to have a meal there anymore. I can't say what was the key aspect during the drive to Bagatelle but I accepted that we should give M&B another shot. Maybe things might have improved since last time. Okay, okay... let's give it a try.

Oh boy! What a fatal mistake!

Despite having six people from the waitron staff lurking around near the main entrance or the kitchen passage we didn't get that much attention. The kitchen was not yet ready... I mean, yeah, why would a breakfast place need to have a ready kitchen in the morning? Okay, let's wait for some 15 to 25 minutes then...
And let's see about the drinks? My BWE asked for a cup of regular black coffee... "Sorry, we don't have coffee right now". What? You have coffee-themed wallpapers all over the place and you cannot serve a simple cup of plain black coffee?
On the other hand, my first choice of drink from the menu... "Sorry, it's not available". What the flipping banana? Am I cursed in terms of food selections? And no it wasn't a milk-shake! That would have been a good choice as they somehow managed to fix their shake machine. Luckily, ordering our morning dishes wasn't an obstacle at all, just waiting... and waiting...

I didn't run a stop-watch but roughly after 45 to 50 minutes later we got our food, well partly. The South African Farm breakfast with additional Beef Strips came first, not my choice and some minutes later I was finally served with a portion of Mexican Scrambles and an additional portion of Country Fries. The beef was not seasoned and tasted blunt after all, the fries had tepid temperature rather than being hot, and taking into consideration that the scrambled eggs might have been put into an oven or microwave judging on the amount of liquid in the small gratin bowl. Honestly, disgusting look and even more horrible taste!

Mugg & Bean world-wide - No, thank you!

Seriously, it is not my intention to blackmail a brand with this posting but frankly speaking after all those months of continuous negative experience at Mugg & Bean in Bagatelle, I won't have another meal for a very long time in one of their branches. No matter where it is located. And believe me, Mugg & Bean isn't the first franchise I completely ditched for more than a decade. McDonalds' back in Germany had (and still have) that bad habit of putting too much salt on their french fries. And so, I went to spent my money somewhere else.

Please share your experience with either Mugg & Bean (Bagatelle or somewhere else) or other food places. Thanks!

by Jochen Kirstaetter (jochen@kirstaetter.name) at May 04, 2015 04:13 PM

Alex Feldstein

May 03, 2015

Alex Feldstein

May 02, 2015

Alex Feldstein

May 01, 2015

Alex Feldstein

FoxProWiki

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.

May 01, 2015 02:51 AM

April 30, 2015

Craig Bailey

On Taking a Life

For the sake of this discussion, let us assume a few things.

First, let us assume that when judgements in capital cases are handed down, they are judicially pure.

We know this is often not the case, that judgements can be the result of political machinations, bribery mismatchesracial inclinations and numerous other motivations. But let us assume for these few minutes that they are indeed pure and free from bias.

Second, let us also assume that the verdicts in capital cases are always correct.

That is, let us ignore the countless overturned findingsmiscarriages of justice, and wrongful executions. Instead let us say for now that guilty verdicts are 100% correct and never is a person wrongly convicted.

Third, let us next assume that the ones caught are always the key players.

For this discussion let us assume that only the ring leaders are caught and tried, never the small fry or racially disadvantaged or unlucky mistake-makers who got caught up in the tip offs of exchanged geopolitical favours.

Fourth, let us assume that there is never any chance of rehabilitation.

Although we know some countries have shown improved rehabilitation programs, and many offenders have reformed and contributed significantly to their communities, let us assume all convicted criminals would definitely reoffend.

Fifth, let us also assume that capital punishment is a proven deterrent to would-be offenders.

Even though numerous studies have shown that capital punishment provides no reduction in crime, let us say that’s not the case.

Sixth and finally, let us assume that all of the offenders ‘deserve’ to die.

Whether they ignored signs in airports, or took lives; without knowing much of their mental state, the pressures they were under, the contributing circumstances – let us say for this discussion that we agree that they deserve to die.

Let us assume all these things are true.

Even then.

Even then capital punishment is wrong.

It’s wrong because the punishment is delivered so acutely and so terribly to those who haven’t offended. To the families and loved ones of the accused. To the mothers, fathers, sisters, brothers, wives and husbands. To the long-time friends and colleagues and neighbours. The punishment for these people never ends.

And it is too much.

The very fabric of a society is broken when a mother who has grown up in a country, and contributed to it, and lived for it, must watch as that country exterminates her loved one. Or the two in Bali, or the eight in total. Or the 140 worldwide in March this year. Or the at least 607 in 2014. Or the thousands in China.

Because everyone has someone who loves them. Even the vilest of criminals and the worst of offenders has someone who loves them. And the pain for those who love sears for the rest of their lives, long after the offender has been extinguished.

This is why we cannot ever accept capital punishment. Even if we decide that we are powerless to fight against it physically, or financially, or mentally.

Even so, we must never accept it as being okay.

The post On Taking a Life appeared first on Craig Bailey.

by Craig Bailey at April 30, 2015 07:51 AM

Alex Feldstein

Calvin Hsia's WebLog

Wireless HeadPhone Adventures

I wanted to get wireless headphones to listen to music. At the office I have 3 desktops, with a range of power. The most powerful has 3 monitors connected. The next has 1, while a 3 rd doesn’t have any (I Remote Desktop to it). I run various flavors of...(read more)

by CalvinH at April 30, 2015 01:11 AM