17

We are building large ASP.NET applications for the intranet use in multiple languages/cultures. We utilize the Globalization with RESX files and use GetResourceText on the server side to get the localized texts.

Lately we are doing more and more client side logic with JQuery.

How do I get the RESX texts to be used in Javascript?

  • e.g. texts used for validation, dynamic messages etc.

All our Javascripts are in .JS files, we do not want to mix HTML in the ASPX page and Javascript blocks.

Thanks for your help.

PeterFromCologne
  • 10,213
  • 9
  • 36
  • 46
  • Microsoft provides a client-side localization as part of the ASP.NET AJAX framework. You should take a look at http://msdn.microsoft.com/en-us/magazine/cc135974.aspx and http://www.asp.net/web-forms/tutorials/aspnet-ajax/understanding-asp-net-ajax-localization – Ilya Volodin Jan 22 '12 at 17:38

7 Answers7

6

Unfortunately, in an external JS file the server side code is not being processed by the server. However I have seen a workaround where you can set your translated values in hidden fields on the page - this way your javascript will be able to read the values in.

For example:

 <%-- This goes into your page --%>
 <input type="hidden" id="translatedField" name="translatedField" value="<%=Resources.Resources.translatedText %>" />

and use this inside your javascript file:

 // This is the js file
 $(document).ready(function() {
  alert($("#translatedField").attr("value"));
 });

You will be able to separate the values and still see it in your external JS file.

There is also another workaround that creates a .aspx file that only outputs Javascript instead of HTML. Check out the link below:

Using server side method in an external JavaScript file

Community
  • 1
  • 1
Deano
  • 2,805
  • 3
  • 29
  • 42
  • Thank you for your answer! I was thinking of a more generic way, not just passing one individual text to the Javascript. The link you put is interesting, I tried this method as well, but in my group we consider it to be "dirty" to use an ASPX page to create a Javascript "file". I am hoping for yet another method... :-) many thanks! – PeterFromCologne Jun 29 '11 at 12:28
  • This is horrible. Like beyond horrible. Consider a page with hundreds of these. What will it do to DOM? Sure we're spoiled by modern browsers that render very quickly. But for many purposes, this is very, very bad. The link you posted is heaps better. – zaitsman Oct 12 '14 at 07:02
  • If you've only got a few things to translate, and that's all there are ever going to be, then it's very concise and efficient as well as easy to maintain. If things start to grow beyond a handful of translated items, then I agree, it needs to be moved to something like the web config idea. – ouflak May 20 '15 at 07:21
  • This feels very hacky. Not ideal when you need to translate a lot of items – JSON Mar 27 '20 at 14:32
2

Always separate functionality from human readable strings.

If you're creating jQuery-plugins you should be able to pass an array of localized strings as parameter when you call your different jQuery functions. The array could be defined as inline javascript directly on the page calling the different jQuery plugins or you could load the from external resource in the format /scripts/localization/strings.js?ci=en-US and register a Generic ASP.Net Handler in web.config that would respond to scripts/localization/strings.js

The DatePicker control is a fine example of how to localize text for the jQuery datepick control - this js file is dynamically created from resource files (resx) and when included on a page it will make sure the calendar control will have danish text.

Pauli Østerø
  • 6,878
  • 2
  • 31
  • 48
2

Create a HttpHandler (.ashx file), and return JSON with your text resource strings.

You may also "publish" it to global namespace, i.e.

Response.Write("window.Resources=");
Response.Write((new JavaScriptSerializer()).Serialize(strings));

set up HTML like:

<script src="Resx.ashx?lang=en-US" />

<button class="LogoutButtonResourceId OtherButtonClasses">(generic logout text)</button>
<a href="#"><span class="SomeLinkTextResourceId OtherClasses">
     (generic link text)
</span></a>

and apply texts like this:

$(document).ready(function() {
  for(var resId in Resources){
    $("."+resId).html(Resources[resId]); 
  }
});
wizzard0
  • 1,883
  • 1
  • 15
  • 38
0

I know it's to late but want share my experience in this task)

I use AjaxMin. It can insert resx key values into js file on build event. It's not common way but it keeps html without unneeded script blocks and can be done during minification process if you have it.

It works like this:

ajaxmin.exe test.js -RES:Strings resource.resx -o test.min.js

Also you need to do the same for ech locale if you have many. Syntax to write resource keys in js (and also css) is written here:

Js localization

Css localization

Denis Agarev
  • 1,531
  • 4
  • 17
  • 34
0

How about injecting it as part of a javascript control initialization? what i do is as follows:

I have a self-contained javascript control - call it CRMControl, which has an init method called setupCRMControl, to which i pass a settings object. When i initialize it, i pass an object containing all the resources i need inside javascript as follows:

CRMControl.setupCRMControl({
numOfCRMs: 3,
maxNumOfItems: 10,

// then i pass a resources object with the strings i need inside
Resources: {
   Cancel: '@Resources.Cancel',
   Done: '@Resources.Done',
   Title: '@Resources.Title'
 }
});

Then, inside this javascript control:

var crmSettings = {};
this.setupCRMControl(settings) {
    crmSettings = settings;
};

and whenever i want to show a resource, i say (for example, show an alert saying 'Done'):

alert(crmSettings.Resources.Done);

You can call it "R" to make it shorter or something, but this is my approach. Maybe this may not work if you have a whole bunch of strings, but for manageable cases, this may work.

Roman Jaquez
  • 2,499
  • 1
  • 14
  • 7
0

If you don't want to use ASP.NET to generate your main JavaScript, here are two other options:

  1. Use ASP.NET to generate a script file that contains variable-to-string assignments, such as var mystring = 'my value';. Your main script would then reference the localized text with variables names rather than as embedded values. If that's still too "dirty" for you, you could encode the strings as JSON rather than as variable assignments, using an HttpHandler rather than straight .aspx.

  2. Have your JavaScript code issue an Ajax call to retrieve an array or list of localized strings from the server. The server-side part of the call would retrieve the text from your resx files.

RickNZ
  • 18,448
  • 3
  • 51
  • 66
0

Have you considered using $.ajax in combination with ASP.NET WebMethods? It's hard to suggest a more concrete solution to this problem without understanding how your JavaScript/jQuery would consume/process the resources. I assume that they're organized into logical groups (or could be) where you could return several resource strings that belong on a single page.

Assuming that, you could write a very simple C# class -- or use a Dictionary<string, string> -- to return data from your ASP.NET WebMethod. The results would look something like:

[WebMethod]
public Dictionary<string, string> GetPageResources(string currentPage)
{
    // ... Organizational stuff goes here.
}

I always separate out my AJAX calls into separate .js files/objects; that would look like:

function GetPageResources (page, callback)
    $.ajax({ // Setup the AJAX call to your WebMethod
        data: "{ 'currentPage':'" + page + "' }",
        url: /Ajax/Resources.asmx/GetPageResources, // Or similar.
        success: function (result) { // To be replaced with .done in jQuery 1.8
            callback(result.d);
        }
    });

Then, in the .js executed on the page, you should be able to consume that data like:

// Whatever first executes when you load a page and its JS files
// -- I assume that you aren't using something like $(document).ready(function () {});
GetPageResources(document.location, SetPageResources);

function SetPageResources(resources) {
    for (currentResource in resources) {
        $("#" + currentResource.Key).html(currentResource.Value);
    }
}
jwheron
  • 2,553
  • 2
  • 30
  • 40