Because Sencha Touch lacks an official way doing internationalization I'm writing my own small set of utility methods. I don't won't to embed another lib like jQuery to use already existing i18n plugins. At the moment I'm in trouble figuring out the best way.
Currently I've a class implemented as a Singleton. In the constructor I determine the language and load the corresponding language file.
At the moment I'm using Sencha methods and define a model and load the data (json) into a store. I think it's kind of convenient. Here a snippet from the constructor where I load the data:
Ext.define('Translation', {
extend: 'Ext.data.Model',
idProperty: 'key',
fields: [
{name: 'key', type: 'string'},
{name: 'translation', type: 'string'}
],
proxy: {
type: 'ajax',
url: 'res/translation-'+lang+'.json',
//appendId: false,
reader: {
type: 'json',
}
}
});
_store = Ext.create('Ext.data.Store', {
model : 'Translation',
autoLoad: true
});
The problem here is that the load is async (no way doing a synchronous call with sencha?!) which means that the application may start to load before this stuff is finished. I need the data because the views rely on it.
Ext.Loader.setConfig({enabled:true});
Ext.application({
name: 'MyApp',
controllers: ['Ctr1', 'Ctr2'],
models: ['Model1', 'Model2],
init: function() {
},
launch: function() {
}
});
The only solutions I've found so far would be
use a callback and wrap the app initialization inside.
Don't use Sencha and do the ajax request stuff manually.
Don't use Ajax at all. Put translations for all languages into a javascript file, include it in index.html and make sure the utility class has access to the object.
There is already an i18N extension have a look here.
https://github.com/elmasse/Ext.i18n.Bundle-touch
There is no easy way to do this with Sencha Touch. Your best bet would be to make an synchronous Ajax request for a json file with translations, and then let your application launch after that.
See this post this could help : sencha touch i18n basics
And my answer,, maybe it could help you.
For your own strings (not talking about native touch component) you could do something like this.
1) In your index.html in the head section, load a LocaleManager.js file (whatever the name) before the
<script id="microloader" type="text/javascript" src="sdk/microloader/development.js"></script>
In your localeManager, depending on your browser's language load the resource file corresponding to your language (myStrings-fr.js | myStrings-en.js )
You can do something like this to get the language in the browser:
window.navigator.language || window.navigator.userLanguage || window.navigator.browserLanguage || window.navigator.systemLanguage
2) Create your resources files with your translated string
It should look like this for the english version (myStrings-en.js) :
var myStrings = {
MyPackage1: {
myString1: 'Seach...'
}};
It should look like this for the french version (myStrings-fr.js) for example :
var myStrings = {
MyPackage1: {
myString1: 'Recherchez...'
}};
3) In your sencha touch code, for example for a searchfield place holder value
xtype: 'searchfield',
id: 'searchToolbarItem',
placeHolder: myStrings.MyPackage1.myString1
Hope it will help.
Another solution could be to modify the build process of your sencha touch app and create localized versions of your app when building it. So there would be one version per language. Then depending on the brower language you would load the right version of your app when loading the app in the browser.
Related
I'm having an issue here when attempting to build an integration to our partners. They're gonna submit an image URL as a GET-variable, which I obviously don't want to print straight up. The submitted image URL is submitted back to our servers with AJAX to be sanitized, returned and then updated.
What I want to do here is when the model loads, I want to display a placeholder image, and when the sanitation check is done by the server, it will return the URL (the same or another placeholder) that is to be set as the template image source.
Now, the problem is that I don't get how to make Ember listen for the update of this event. I'm trying to use observes, but apparently, this isn't available in the route. Here's my current code:
ROUTE
MyApp.PartnerRoute = Ember.Route.extend({
imageUrl: "/img/placeholder.png";
getImageUrl: function(imageUrlToCheck) {
instance = this;
$.ajax({
url: "/ajax/get-image-url",
type: "post",
data: {
"imageUrl": imageUrlToCheck
},
success: function(response) {
if(response.status === 0) {
instance.set("imageUrl", response.data.imageUrl);
}
}
});
},
// Ember update property.
imageUrlDidChange: function() {
this.get("imageUrl");
}.observes("imageUrl"),
model: function(params) {
this.getImageUrl(params.imageUrl);
return {
heading: "Welcome!",
imageUrl: this.imageUrl
}
}
});
VIEW
<script type="text/x-handlebars" data-template-name="partner">
<h1>{{heading}}</h1>
<img {{bind-attr src=imageUrl}} />
</script>
I get the error message:
Uncaught TypeError: Object function () {
this.get("imageUrl");
} has no method 'observes'
I'm not at all sure as of how to make this happen. Am I going about this the wrong way? Any help is appreciated.
Thank you for your time.
Best regards,
dimhoLt
PS. I've extracted the applicable pieces of code from much bigger objects, so if there are any typos, missing commas etc, it's due to the copy-paste and is not applicable to the actual code.
EDIT:
Worth noting is that because of legacy functionality I haven't yet rewritten, I was forced to turn off Ember extended prototypes. This is, I guess, the major cause of the issue.
Since I wrote this, I've also gone over to using a fixed model instead of attempting to work directly with the route.
You need to use a setter
http://emberjs.jsbin.com/OxIDiVU/117/edit
model: function(params) {
var model = {
heading: "Welcome!",
imageUrl: this.imageUrl
};
this.getImageUrl(params.imageUrl).then(function(result){
Em.set(model, 'imageUrl', result.imageUrl);
});
return model;
}
These are my first steps with the Firefox AddOn SDK. What I'm trying to create is a simple 'settings dialogue'. I thought about a html page containing forms for the values and a submit button. Following the first mozilla tutorials I created a widget:
var widget = require('widget').Widget({
label: 'Settings',
id: 'settings',
//panel: text_entry
contentURL: data.url('images/stgfavicon.ico'),
contentScriptFile: data.url('scripts/submit.js'),
onClick: function() {
tabs.open(data.url('forms/settings.html'));
}
});
But since settings.js is not the contentScriptFile I got no communication between settings.html and settings.js. Is it possible to get this done without some (complex looking) messaging system? And how to save the values best? A JSON file?
Some links/examples/API names would help me a lot. :)
That's because you're trying to attach your script to the widget (which is not an HTML file). You need to attach it to the actual html file after the tab opens.
tabs.open({
url: data.url('forms/settings.html'),
onOpen: function onOpen(tab) {
tab.attach({ contentScriptFile: data.url('scripts/submit.js'); });
}
});
I haven't tested that out so there may be an error.
You should also look at the simple-prefs module if these are settings that aren't going to be adjusted frequently.
I have a view with a generate button. When I click It I am navigating to a Generate method of a controller using ajax call.
generate = function () {
$.ajax({
url: "/franchise/Generate",
type: "POST",
data: { id: omega.franchiseInfo.Id(), imagesPath: omega.franchiseInfo.ImagesPath() },
});
}
Here is my Generate method:
public ActionResult Generate(int id, string imagesPath)
{
// some logic here
var zipFileName = #"D:\FranchiseGeneration\MyZipFile.zip";
using (var zip = new ZipFile())
{
zip.AddDirectory(#"D:\FranchiseGeneration\Test", "Generation");
zip.Save(zipFileName);
}
return File(zipFileName, "application/zip", "MyZipFile.zip");
}
MyZipFile.zip is created on my hard drive as specified. I expect the user to be prompted to download the zipped file ... but nothing happens. I am rather new to Mvc3 and I am not sure what I am doing wrong. Any suggestions with code samples are welcome. Thank You!
It's an ajax call, it doesn't make sense to return a File in an ajax call... ajax stands for Asynchronous JavaScript and XML.. ok with json ad some other text based things, but to work with binary files you'll need some exta works.
In you scenario, I think the best thing to do (the simplest one) is to perform a normal postback, not ajax (or even a simple GET would work).
It is not possible to trigger a file download via an ajax request like this.
There are other ways to make something like it happen though.
http://johnculviner.com/post/2012/03/22/Ajax-like-feature-rich-file-downloads-with-jQuery-File-Download.aspx
I'm using underscore and backbone on a multi page site with a couple of underscore templates on each page. On my main view(cshtml) I load one javascript template like this http://cl.ly/GpFT and on my second view(cshtml) I use the same script setup but the javascript template is missing and then I get an error like this http://cl.ly/Gnrc
When I minify my scripts this will cause the script to abort. Is it possible to solve this in a nice way or do I need to load exactly the templates and scripts needed for each and every page?
You don't tell us what your views look like so I'll assume that you're doing something like this:
var V = Backbone.View.extend({
template: _.template($('#some-id').html()),
//...
});
and your views are raising TypeErrors when you're loading them. If there is no #some-id in the DOM, then you'll be saying _.templates(null) and that doesn't make any sense. An easy way around this to compile the template in the view's constructor instead:
var V = Backbone.View.extend({
initialize: function() {
this.template = _.template($('#some-id').html());
//...
},
//...
});
I just started using the FireFox Builder to build a simple addon. I realised that I cannot get direct access to the window object.
What I want to do is to get the window object and pollute it with some classes and functions so I can call them from the page itself.
Below is the current code:
// This is an active module of the ritcoder Add-on
require("widget").Widget({
id: "widgetID1",
label: "My Mozilla Widget",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function(evt){
var tabs = require("tabs");
var activeTab = tabs.activeTab;
var notifications = require("notifications");
notifications.notify({
title: "Jabberwocky",
text: "'Twas brillig, and the slithy toves",
data: "did gyre and gimble in the wabe",
onClick: function (data) {
console.log(data);
// console.log(this.data) would produce the same result.
}
});
activeTab.window.a=20; //this fails
context.alert('yesx');
}
});
How do I do this? Inject some code into the active page so that it can be called.
regards,
You need to use tab.attach() to run a content script in the tab's context, and then use unsafeWindow to add properties the page's script can see. (You should also read the introduction to Content Scripts.)
The Addon SDK doesn't provide a direct access (without the content script) to the page from the add-on's code because it tries to be forward compatible with the plans to make web pages run in processes separate from the browser's and the add-on's process.