Internationalization in SAPUI5 - sapui5

I have problem with Internationalization in SAPUI5.
I have a folder i18n and it has a file i18n.properties and inside it has NAME=app name
SERVER= server name
I have a shell and inside onInit I have this code :
var oModel = new sap.ui.model.resource.ResourceModel({bundleUrl:"./i18n/i18n.properties"});
sap.ui.getCore().setModel(oModel, "i18n");
then I go to my View and and use it in my shell like this:
oShell = new sap.ui.ux3.Shell({
id:"main-shell",
appTitle:"{i18n>NAME}",
showPane:false,
showLogoutButton:false,
showTools:false,
});
this works fine.But when I go to another view and use it to get the server address it doesn't work for example i go to another controller and use it like this:
var URL="{i18n>SERVER}";
this code doesn't get resolved and stay the same as it is.

You are trying to bind the value to a varaible, what you need to do is read from the bundle directly, one way to get the value is
var URL = sap.ui.getCore().getModel("i18n").getResourceBundle().getText("SERVER");

Related

How to dynamically load a JAR file with Vert.x JavaScript?

Using Vert.x JavaScript (3.8.4), I want to dynamically load a JAR file at runtime. This is necessary because that file might not exist when my Vert.x application gets started. Ideally, I would like to be able to use code like this:
// load custom JAR file
requireJar("path/to/dynamic.jar");
// use class from dynamically loaded package
var instance = new com.mydynamicpackage.MyCustomClass();
How can I achieve this?
You might find this answer to be helpful:
How to access external JAR files from JavaScript using Rhino and Eclipse?
Another approach that is valid would be to provide the jar with other means, i.e. not via a javascript implementation, to check afterwards, if it is available and then deal with the case if it is not.
java.lang.Class.forName( 'com.mydynamicpackage.MyCustomClass' )
This will throw an error, if MyCustomClass does not exist.
Loading jars at runtime might not be a good idea if you cannot determine they are loaded from a not trustworthy source. This is at least true for the java world.
Based on this answer, I have created the following JavaScript function for dynamically loading a class from a JAR file:
var requireJavaClass=(function(){
var method=java.net.URLClassLoader.class.getDeclaredMethod("addURL",java.net.URL.class);
method.setAccessible(true);
var cache={};
var ClassLoader=java.lang.ClassLoader;
var File=java.io.File;
return function(classname,jarpath){
var c=cache[classname];
if (c) return c;
if (jarpath) {
var cl=ClassLoader.getSystemClassLoader();
method.invoke(cl,new File(jarpath).toURI().toURL());
cl.loadClass(classname);
}
return cache[classname]=Java.type(classname);
}
})();
The equivalent to the snippet I posted in the my question would be:
var MyCustomClass=requireJavaClass("com.mydynamicpackage.MyCustomClass","path/to/dynamic.jar");
var instance = new MyCustomClass();
So far, I have only tested this with Vert.x 3.8.5 running in JRE8, i.e. I can't say if this also works in older Vert.x versions or with JRE9+.

How to pass a parameter through to a Rest Service in Xpages

XPages Dojo Data Grid and Custom REST Service
*** Note: Mine is an XPINC application!
I've managed to get the above method working, but I want to pass a parameter through to the Rest Service in order to build a better return set.
In the above example it the script looks like this:
<script>
var jsonStore = new dojo.store.JsonRest(
{target:"CURRENT_PAGE_NAME_HERE.xsp/gridData"}
);
var dataStore = dojo.data.ObjectStore({objectStore: jsonStore});
</script>
But, I want to do something like this:
<script>
var jsonStore = new dojo.store.JsonRest(
{target:"CURRENT_PAGE_NAME_HERE.xsp/gridData?OpenXpage&para1=Value1&para2=Value2"}
);
var dataStore = dojo.data.ObjectStore({objectStore: jsonStore});
</script>
I've tried a number of methods, but no success.
Method 1 - Use Request/View/SessionScope variable
On the "CURRENT_PAGE_NAME_HERE.xsp" I've added a "xp:this.beforePageLoad" event to create Scope variable to hold para1 and para2 taken from the paramValues of the URL.
I thought a simple requestScope would store them so I could pick them up when the "CURRENT_PAGE_NAME_HERE.xsp/gridData" was called. However, the Rest Service is called in the "onClientLoad" event of the page and the Scope variables don't seem to be available at this time.
Method 2 - Inline Javascript
I've also tried "${javascript:viewScope.para1;}" to pass it through:
<script>
var jsonStore = new dojo.store.JsonRest(
{target:"CURRENT_PAGE_NAME_HERE.xsp/gridData?OpenXpage&para1=${javascript:viewScope.para1;}&para2=${javascript:viewScope.para2;}"}
);
var dataStore = dojo.data.ObjectStore({objectStore: jsonStore});
</script>
This didn't work.
Method 3 - Hardcoding
I have hardcoded the values.
<script>
var jsonStore = new dojo.store.JsonRest(
{target:"CURRENT_PAGE_NAME_HERE.xsp/gridData?OpenXpage&para1=Apples&para2=Oringes"}
);
var dataStore = dojo.data.ObjectStore({objectStore: jsonStore});
</script>
This works! But, only for Apples & Oranges
I'm starting to look at using an Environment Variable to pass the values, but this just seems to be more of a hack than a solution.
Any help or guidance would be appriciated.
Dan,
You may have a couple of things to check.
First thing is that you need to use # instead of $ to avoid
evaluating the expression on page load
In some cases you cannot inject SSJS into the CSJS - if this is "evaluated" at page load time. You could be hitting this.... An easy
way to check is to create a couple of local variables and assign the
values from your SSJS. That'll make it easy to debug in the browser.
I guess you could do something like this (and then you can set a breakpoint in your browser and see if the values are as expected).
<script>
var p1 = "#{javascript:viewScope.para1;}";
var p2 = "#{javascript:viewScope.para2;}";
var jsonStore = new dojo.store.JsonRest(
{target:"CURRENT_PAGE_NAME_HERE.xsp/gridData?OpenXpage&para1=" + p1 + "&para2=" + p2}
);
var dataStore = dojo.data.ObjectStore({objectStore: jsonStore});
</script>
If this does not work then I suggest creating a script block in the beginning of your page with a simple little "getter" method for each variable (or the entire arg. string) and then use the SSJS there.
Happy coding!
/John
As this is an XPINC appplication, I felt it was safe to just use an Environment Variable.
On the view action button that calls the XPage, I write the Environment variable down onto the system. Then when I open the Xpage in the client, the Rest Service is hardwired to:
var param1:String = session.getEnvironmentString("Param!");
I still think this feels more like a hack, but with Notes, I'm getting used to it. LOL

How to change a file name of a google form bu Apps script

For a google spreadsheet it is easy to change the filename by using this script:
var file = SpreadsheetApp.openById(Idfile);
file.rename("new name");
Logical to me for change file name of a form:
var form = FormApp.openById(Idform);
form.rename("new name");
However this does not work!
Who knows the solution to change a filename of a google form by using apps script?
How about this method?
DriveApp.getFileById(id).setName("new name");
This method can also rename Spreadsheet.
Reference :
setName(name)

When does a model get updated after the model data has changed?

There is a method named updateBindings(true?) in openui5. But I'm not sure when I have to invoke it. Sometimes, setting the modified data to a model causes view changes, which indicates the underlying model data actually gets changed. Sometimes it won't work.
The first example demonstrates that the model doesn't get changed without updateBindings(true).
http://jsbin.com/hulavutoha/edit?html,css,output
The second example derives from the first one. But the model gets updated even without updateBindings(true).
http://jsbin.com/lepuladivu/edit?html,css,output
So, what's the difference between the two examples? When do I need to invoke updateBindings(true) on a model so that it will get updated? What's the intent of the parameter true passed to updateBindings()?
If you add a console print in your formatter function
formatter : function(books) {
console.log("go!!!");
return books[0];
}
you can see that in the first example the function is not executed.
This because if you change a leaf property the linked conponent in thew view (using data-binding) receive the change event only if it bind exactly the leaf property.
P.S.
Instead to use getData
var data = oModel.getData();
data.books[0] = "my book";
oModel.setData(data);
you can use getProperty
var data = oModel.getProperty("/");
data.books[0] = "my book";
//oModel.setProperty("/", data);
In this mode the last line is not required

Dynamically setting view directory

I am making a customer portal application using ZF. And the portal needs to work for different company brands. So I need to use all of the same backend code/controllers/etc, but dynamically change the view directory based off of the hostname.
Right now my view directory structure looks something like this:
/application/views/scripts/brand1/
/application/views/scripts/brand1/index/index.phtml
/application/views/scripts/brand1/error/error.phtml
/application/views/scripts/brand2/
/application/views/scripts/brand2/index/index.phtml
/application/views/scripts/brand2/error/error.phtml
/application/views/scripts/brand3/
/application/views/scripts/brand3/index/index.phtml
/application/views/scripts/brand3/error/error.phtml
and so on.
I am using the addScriptPath() function in bootstrap.php like so
protected function _initView()
{
$view = new Zend_View();
$view->doctype('XHTML1_STRICT');
$view->env = APPLICATION_ENV;
$view->addScriptPath(APPLICATION_PATH . '/views/scripts/brand1');
$view->addHelperPath(APPLICATION_PATH . '/views/helpers');
...
}
However when this is run, it is looking for all views using /views/scripts/brand1/(action).phtml instead of looking for views using the correct scheme /view/scripts/brand1/(controller)/(action).phtml
tl;dr is it possible to dynamically choose the view directory and have it work like the default /views/scripts/(controller)/(action).phtml behavior?
I knew I would find the answer after I posted here. In case anyone else encounters the same problem, the solution was using:
$view->setBasePath(APPLICATION_PATH . '/views/brand1');
And then modifying the directory structure to:
/application/views/brand1/scripts/...