How to angular-translate controller function objects - angularjs

I cannot find examples for how to translate objects inside of functions, only examples for translating html content.
Inside the function are system button labels that need to be translated. I have provided the actual en.json and th.json files to show what needs to be translated. I can find no examples for angular-translate that translate non-html objects like in this function. I have managed to get translation working on all other areas of my application, but not this function. The documentation http://angular-translate.github.io/docs/#/guide/03_using-translate-service does not provide a good example that fits my code. I have seen others ask this same type of question, and just be pointed to the documentation (i.e. https://github.com/angular-translate/angular-translate/issues/1466).
en.json
{
"CHOOSE_IMAGE": "Choose image source",
"CAMERA": "Camera",
"LIBRARY": "Library",
"CANCEL": "Cancel"
}
th.json
{
"CHOOSE_IMAGE": "เลือกที่มาของภาพ",
"CAMERA": "กล้อง",
"LIBRARY": "คลังรูปภาพี่ี",
"CANCEL": "ยกเลิก"
}
feedback.controller.js
...
function getImageSource() {
var deferred = $q.defer();
$ionicActionSheet.show({
buttons: [
{ text: 'CAMERA' },
{ text: 'LIBRARY' }
],
titleText: 'CHOOSE_IMAGE',
cancelText: 'CANCEL',
cancel: function () {
deferred.reject();
},
buttonClicked: function (index) {
if (index === 0) {
deferred.resolve(Camera.PictureSourceType.CAMERA);
} else {
deferred.resolve(Camera.PictureSourceType.PHOTOLIBRARY);
}
return true;
}
});
return deferred.promise;
}
...

Well, apparently all the necessary information are in the docs. But let me do your work..
You have to inject $translate service in your controller. Assuming you have your translations already loaded the most convinient way to translate your labels is to use $translate.instant() method. What does it do?
According to docs http://angular-translate.github.io/docs/#/api/pascalprecht.translate.$translate it:
Returns a translation instantly from the internal state of loaded translation. All rules regarding the current language, the preferred language of even fallback languages will be used except any promise handling. If a language was not found, an asynchronous loading will be invoked in the background.
So your code should look like that:
feedback.controller.js
...
function getImageSource() {
var deferred = $q.defer();
$ionicActionSheet.show({
buttons: [
{ text: $translate.instant('CAMERA') },
{ text: $translate.instant('LIBRARY') }
],
titleText: $translate.instant('CHOOSE_IMAGE'),
cancelText: $translate.instant('CANCEL'),
cancel: function () {
deferred.reject();
},
buttonClicked: function (index) {
if (index === 0) {
deferred.resolve(Camera.PictureSourceType.CAMERA);
} else {
deferred.resolve(Camera.PictureSourceType.PHOTOLIBRARY);
}
return true;
}
});
return deferred.promise;
}
...
Or you can use asynchronous loading with:
feedback.controller.js
....
$translate(['CAMERA',
'LIBRARY',
'CHOOSE_IMAGE',
'CANCEL']).then(function (translations) {
$ionicActionSheet.show({
buttons: [
{ text: $translate.instant('CAMERA') },
{ text: $translate.instant('LIBRARY') }
],
....
Hope it helps.

Use filter function
.controller(["$filter",....],function($filter,....){
var translateFilter=$filter("translate");
...
buttons: [
{ text: translateFilter('CAMERA') },
{ text: translateFilter('LIBRARY') }
]
...
})
or when translations isn't loaded already
.controller(["$q","$translate",....],function($q,$translate,....){
var translateFilter=$filter("translate");
$q.all({
CAMERA:$translate('CAMERA'),
LIBRARY:$translate('CAMERA')
}).then(function(translations){
...
buttons: [
{ text: translations.CAMERA },
{ text: translations.LIBRARY }
]
...
})
})

Related

Set selected value in Select2 using angularjs

I have a Drop down in my Anjularjs Application implemented using 'ui.select2'
I had initialized it as below
<input type="text" ng-model="objCas.iProjectId" id=" iprojectid" ui-select2="iProjectIdOption" />
And My Js Implementation is getting data from remote server with pagination and filter
var app = angular.module('CASApp', ['ui.select2', 'checklist-model']);
app.controller('CASController', function ($scope, $http) {
$scope.iProjectIdOption = {
placeholder: "Click to choose the Project...",
allowClear: true,
initSelection: function (element, callback) {
},
ajax: {
url: "/Prj/dummy/Ajaxlist",
quietMillis: 0,
type: "POST",
data: function (term, page) {
return {
q: term,
page: page,
listType: "ProjectDetails"
}; // query params go here
},
results: function (data, page) { // parse the results into the format expected by Select2.
// since we are using custom formatting functions we do not need to alter remote JSON data
var more = (page * 30) < data.total_count; // whether or not there are more results available
return {
results: $.map(data.items, function (item) {
return {
text: item.text,
id: item.id
}
}),
more: more
}
},
cache: true
}
}
}
}
Everything works fine .I am able to use all the features and post the values also. But problem is with setting the already selected values at time of edit
Tried
$Scope.objCas.iProjectId= {"text":"2010 / 256 - / dummytext","id":240}
$Scope.objCas.iProjectId=2;
$scope.iProjectId.selected = {"text":"2010 / 256 - / dummytext","id":240}
Get the select2 element object and apply the following code:
angular.element("#select2_id").select2('data', { "text": "text", "id": [id]});
HTML code: no need of id
<input type="text" ng-model="objCas.iProjectId" ui-select2="iProjectIdOption" />
js code:
use only this for default biniding
$Scope.objCas.iProjectId= {"text":"2010 / 256 - / dummytext","id":240}
example code:
link: http://embed.plnkr.co/K66Pf0/
replace script.js file:
// Code goes here
var myAppModule = angular.module('MyApp', ['ui.select2']);
myAppModule.controller('MyController', function($scope) {
$scope.select2Options = {
initSelection: function (element, callback) {
},
ajax: {
url: "./data.json",
data: function (term, page) {
return {}; // query params go here
},
results: function (data, page) { // parse the results into the format expected by Select2.
// since we are using custom formatting functions we do not need to alter remote JSON data
return {results: data}
}
}
}
console.log("$scope.select2Options-",$scope.select2Options.initSelection);
$scope.testModel={ "id": 4, "text": "Fourth", "color": "red" }
;
});
you can view default selected value in dropdown.

How to call a Layout from itself to make an instance

I have a Layout(SubMenu100) that have an event to call other Layout(SubMenu200), but it also make a onClick trigger that will create an instance if layout(SubMenu100) and call itself, but I don't know how to get an instance like the next code.
this.SubMenu100 = new SubMenu100();
I try to put it in Define vars but get me an error.
define([
'backbone.marionette',
'underscore',
'logger',
'tpl!apps/templates/SubMenu100.html',
'i18n!apps/nls/Messages',
'apps/views/SubMenu200',
'apps/views/SubMenu100'
], function (Marionette, _, Logger, Template, i18n, SubMenu200, SubMenu100) {
launch: function (e) {
$("#title_wrapper_div").click(this.callMe);
},
callMe: function () {
if (this.subMenu100 === undefined) {
this.subMenu100 = new SubMenu100(); // <- here
}
window.App.vent.trigger("dashboard:showView",this.subMenu100, "", "", "", "");
}
}
So, this is the question, How can I create an instance of SubMenu100 inside within itself?
If launch is called with context of SubMenu100, you can do this.callMe.bind(this) then you should be able to do new this() inside callMe.
But for simplicity you could do this :
define([
'backbone.marionette',
'underscore',
'logger',
'tpl!apps/templates/SubMenu100.html',
'i18n!apps/nls/Messages',
'apps/views/SubMenu200'
], function(Marionette, _, Logger, Template, i18n, SubMenu200) {
var SubMenu100 = Class SubMenu100 {
launch: function(e) {
$("#title_wrapper_div").click(this.callMe);
},
callMe: function() {
if (this.subMenu100 === undefined) {
this.subMenu100 = new SubMenu100();
}
window.App.vent.trigger("dashboard:showView", this.subMenu100, "", "", "", "");
}
}
return SubMenu100;
});
Note that every launch will create new event handler potentially on the same element (unless something else is doing proper cleanup) and this can lead to bugs. I don't recommend using global jQuery selectors in backbone components.
If you want to create instances of SubMenu100 and SubMenu200 I'd create a higher level component in charge of that:
require([
// ^ ------ this is NOT SubMenu100 definition
'apps/views/SubMenu100',
'apps/views/SubMenu200',
], function (SubMenu100, SubMenu200) {
// this is NOT SubMenu100 definition
launch: function (e) {
$("#title_wrapper_div").click(this.callMe);
},
callMe: function () {
if (this.subMenu100 === undefined) {
this.subMenu100 = new SubMenu100();
}
}
});

Extjs 4 to 6 migration classes

We have js files writen in Extjs 4. I have to migrate theese to Extjs 6. Almost everything is fine, but when we create own classes (extended extjs classes), we have a problem. (Unfortunately there's no mvc, just classes and create). In the ext-all-debug:
create: function(config, defaultType) {
if (typeof config === 'string') {
return Ext.widget(config);
}
if (config.isComponent) {
return config;
}
if ('xclass' in config) { // **config is true**
return Ext.create(config.xclass, config);
}
return Ext.widget(config.xtype || defaultType, config);
},
The config is true except an object, and we got the following error message in the console: "Cannot use 'in' operator to search for 'xclass' in true"
What is the problem with our classes or creating?
This is a class:
Ext.define("My.component.TrunkListGrid", {
extend: "My.component.Grid",
// config
viewConfig: {
enableTextSelection: true
},
initComponent: function () {
// ...
Ext.apply(this, {
// ...
});
this.callParent();
this.addListener('render', function () {
// ...
}, this);
}
});
This is a create:
var g = Ext.create('My.component.TrunkListGrid', {
// config
});
I think, I have to call something another way...
Oah, I found it! We used the buttons: true in the config

Load default static translation files before getting overriding translation maps

I'm new to angular-translate (I'm not a God in Angular itself though).
Say I have a set of translation JSON files already available, in English and Italian. Those contain the translations I should use by default.
i18n/locale-en_GB.json
{
"market.marketplace.title": "Marketplace",
"market.marketplace.descr": "Here is a description",
"market.available.items": "Available items"
}
i18n/locale-it_IT.json
{
"market.marketplace.title": "Marketplace",
"market.marketplace.descr": "Ecco una descrizione",
"market.available.items": "Oggetti disponibili"
}
If that was all, I would of course simply use the static file loader:
.conf
...
$translateProvider.useStaticFilesLoader({
prefix: 'i18n/locale-', // Template paths to translation files
suffix: '.json'
});
...
The problem is that I also have to take into account the results of a REST Call that I have to run at the very beginning (say translation service configuration time), which could override some of the default translations.
I tried to use a custom loader:
.conf
...
//$translateProvider.useStaticFilesLoader....
$translateProvider.useLoader('customLoader', {});
...
.factory
.factory('customLoader', function ($q, $http, MyRESTService, translationService) {
return function (options) {
var deferred = $q.defer();
MyRESTService.getLanguageMaps(
function success(response) {
var langMap = response;
/* langMap would be something like:
var langMap = [
{
"en_GB": {
"market.marketplace.title": "NEWENGLISHTITLE",
"market.marketplace.descr": "NEWENGLISHDESCR"
}
},
{
"it_IT": {
"market.marketplace.title": "NEWITALIANTITLE",
"market.marketplace.descr": "NEWITALIANDESCR"
}
}
];
*/
deferred.resolve(langMap);
},
function failure(err) {
deferred.reject(err);
}
);
return deferred.promise;
};
})
But I can't seem to find a way to load my "default" translations (from static files) first, and then merge with results from my REST API.
Furthermore, the only way I could find to make this customLoader work was to specify only one JSON as translation map, i.e. I can't make it use the first object as English map and second object as Italian map.
E.g.
/* If resulting configMap layout is like this, translations are displayed but only second JSON Object is used */
var configMap = [
{
"market.marketplace.title": "ENGLISHTITLE",
"market.marketplace.descr": "ENGLISHDESCR"
},
{
"market.marketplace.title": "ITALIANTITLE",
"market.marketplace.descr": "ITALIANDESCR"
}
]
/* This way does not work */
var configMap = [
{"en_GB",
{
"market.marketplace.title": "ENGLISHTITLE",
"market.marketplace.descr": "ENGLISHDESCR"
},
},
{"it_IT",
{
"market.marketplace.title": "ITALIANTITLE",
"market.marketplace.descr": "ITALIANDESCR"
}
}
]
I can decide how results will be given, as I still have to implement the REST call.
I hope I made myself clear enough! Can somebody help here?

Calendar Pro - How to config to use src path not in extensible-all-debug

I using extensible-1.5.1 and i run app in
extensible-1.5.1/examples/calendar/TestApp/test-app.html
I try to custom Event Form window by add a new textfield into this form. Here is form default
But i can't find file to edit.
I think that in extensible-1.5.1\src\calendar\form\EventWindow.js. But when i remove src folder then project still working and nothing change?
How to do that thanks
Edit
I found that in extensible-all-debug.js file. But that file is really complex
How to config to use data in extensible-1.5.1\src\ like calendar at extjs example
You are correct in that the class you need to use is Extensible.calendar.form.EventWindow. However, instead of editing that file, you should extend that class and make your own version of it. You can use that file as a guide, and override the getFormItemConfigs function to modify the form as you need it:
Ext.define("MyApp.view.EventWindow", {
extend: "Extensible.calendar.form.EventWindow",
modal: true,
enableEditDetails: false,
initComponent: function()
{
this.callParent();
},
getFormItemConfigs: function() {
var items = [/*your form items here */];
return items;
},
//... other stuff here maybe...
});
Then, you can override the Extensible.calendar.view.AbstractCalendar to use the class you just made:
Ext.define("MyApp.view.AbstractCalendarOverride", {
override: 'Extensible.calendar.view.AbstractCalendar',
getEventEditor : function()
{
this.editWin = this.ownerCalendarPanel.editWin;
if(!this.editWin)
{
//Change this line:
this.ownerCalendarPanel.editWin = Ext.create('MyApp.view.EventWindow', {
id: 'ext-cal-editwin',
calendarStore: this.calendarStore,
modal: this.editModal,
enableEditDetails: this.enableEditDetails,
listeners: {
'eventadd': {
fn: function(win, rec, animTarget) {
//win.hide(animTarget);
win.currentView.onEventAdd(null, rec);
},
scope: this
},
'eventupdate': {
fn: function(win, rec, animTarget) {
//win.hide(animTarget);
win.currentView.onEventUpdate(null, rec);
},
scope: this
},
'eventdelete': {
fn: function(win, rec, animTarget) {
//win.hide(animTarget);
win.currentView.onEventDelete(null, rec);
},
scope: this
},
'editdetails': {
fn: function(win, rec, animTarget, view) {
// explicitly do not animate the hide when switching to detail
// view as it looks weird visually
win.animateTarget = null;
win.hide();
win.currentView.fireEvent('editdetails', win.currentView, rec);
},
scope: this
},
'eventcancel': {
fn: function(win, rec, animTarget){
this.dismissEventEditor(null, animTarget);
win.currentView.onEventCancel();
},
scope: this
}
}
});
}
// allows the window to reference the current scope in its callbacks
this.editWin.currentView = this;
return this.editWin;
}
});
This may not give you exactly what you need, but hopefully it puts you on the right track.

Resources