Rethinking smartUI Part 4-B

Forms Rest command

Some weeks ago I published a new video on Rethinking smartUI on Youtube. Now we have Rethinking smartUI Part 4-B discussing the main part of gathering and displaying thr documents data.

If you havn’t it seen yet, here is the short video. In this posts, we’ll go though the technical aspects of this new kind of approach to smartUI. This demo is a Document Pad (or short DocPad), displaying all document properties in a SCIFI GUI arrangement.

A warning at the beginning: To use this code with IE11 is a perfect way to test all js error messages. Use this code only with the newest browsers. Its tested with Chrome (V98), Chrome Canary (V98), FF Developer (95.0b4), Edge (95.0) and Firefox (93.0)

The other parts of this post were

Part 4-A The Javascript Part 1

Part 3 The Infrastructure and the CSS

Part 2 The HTML

Part 1 Overview

In the part 4A, we had discussed all the js responsible for the perimeter of the whdgetz. Not lets discuss the main part which is responsible to gather and displad this data:

docdisplay

A CSS Grid

As you can see, there are 6 panels arranged in a CSS grid.

For infos on the css, please review this post, the part 3 of this series.

So let’s start with the panel at top left.

The documents metadata

This is more or less the data which is related directly to the document. The documents node number was the output from the node picker . The nodepicker was closed by the done() callback.

Nodepicker

Here we are in the this function of the nodepicker. We extract the node from the callbacks arguments an get the id with the topmost arrow. We extract the name of the node and put this name inside the id #document.

The loadDescriptions function does the work.

loadDescriptions

The prelude is simply to select the first face “.face.one”

Prelude
Begin

If this is not undefined (remember, smartUI always makes 2 runs, so its always a goot idea to test if its defined) the create and modify dates are extracted and translated in a standard js data. For non-US readers it will be always a difference between p.ex 04-05-20 and 4.Mai 2020 (US and german dates for the Star Wars day May the fourth), thats why we translate the dates.

Also we need to get the users of the creation and the modification. But these are numbers, so we want to translate them to names.

Next, extract the server from the connection and construct the members REST command to get these names.

First view: The fetch command

fetch is new in js 6. In this older, antique times you would have used some ajax variants like xmlhttprequest or some similar methods which we will use in other calls for comparism.

Fetch command

Technically, we have to issue two REST calls to /member/ to get the names of the createuser and the modifyuser. We use the fetch command.

Remark: the famous async/await would be much more handy for that, but we wanted to limit the language scope to js6 for these posts.

Once we get the responses, we’ll put that names simply as innerHTML on the panel.

Technically, you can use all other avaliable methods to put text on the panel, from template-strings to create a and fill a text nodein the DOM. You can even invite handlebars to do this for you.

loadDocumentThumbnail

In the top middle panel we added the document thumbnail, which is created automatically during indexing on the server.

Thumbnail

We must enter the nodeid in the REST command /thumbnails/medium/content to get the medium resolution version of the thumbnail.

To show the diffence to the fetch comand, the old archaic XMLHttpRequest was used.

The receiving image is put into a div with the id “Thumbnail”.

Image Correction

In the case the user selects another document the old thumbnail would remain. So we remove the old image element.

Almost done, we need to put our otcsticket in the request header and to send the request to the server.

loadNodeData

In this function, we use exactly one REST call to get all data at once. This is done by the function /forms/update?id=xx whick will deliver all data for that nodeid at once. Expecially the categories take a while, so a css-fog was used to cloak the image of the approaching grid until the data was received (revisit the video). Then the css fog is cleared and trhe categories are displayed.

The call is also done with the old XMLHttpRequest to show the diffences to the modern fetch command.

Local functions were used instead of those in “this” to keep the scope clean.

forms/update

The categories and the attributes

Categories

Categories were returned in an object with their category name a title in the entry. To get the attributes we have to do a little bit more.

Attributes

We split the result into several arrays to extract the values. If we have “date” in the type field, we have to use our date translation also on that to display the dates correct.

Security Clearances

All security related data is on the fouth face, the one on the lower left.

Security Clearances

Here, all security levels and markings were displayed inside a span.

Records Management Data

here we extract and fill the data on the lower middle panel.

Records Management

The Versions Data

Here, the REST commend has a problem. Versions are not included in the answer of the REST command, at least in the Content Server versions 21.3 and 21.4. So let’s ionform the user on this fact and display a local language string of this fact.

Tip: Maybe there will be a patch to fix this in the near future.

Versions Data

So we had all parts discussed.

We offer a one day remote training to understand the javascript code. If you are already a sophisticated Javascript Developer, you can get the free Sources also from https://github.com/ReinerMerz/reinerdemo (a public repository on Github).

Warning: This is only the sourcetree of the project, so you have to insert this in your own project file.

The data returned from the formsupdate?id=nn REST command

The whole data structure is send back in response to a forms/update?id=nnn REST call. Some of these entries take quite a while, so try using some css to cache this.

Forms Rest command

Have fun on discovering the endless possibilities of Dashboards and other Contentserver smartUI extensions using javascript6 and css3.

The sky is the limit.

Rethinking smartUI Part 4-A

Rethinking smartUI

Three weeks ago I published a new video on Rethinking smartUI on Youtube. Now we have Rethinking smartUI Part 4-A discussing Javascript. If you havn’t it seen yet, here is the short video. In this posts, we’ll go though the technical aspects of this new kind of approach to smartUI. This demo is a Document Pad (or short DocPad), displaying all document properties in a SCIFI GUI arrangement.

This is Part 4-A of a multipart post covering Javascript of DocPad. For the css refer to part 3 of Rethinking smartUI.

Warning: This is a lot of js code, so I subdivided this Part 4 into Part 4-A and 4-B (getting all documents infos with 1 Rest call). Part 4-B will be published next week.

We offer a one day remote training to understand the javascript code. If you are already a sophisticated Javascript Developer, you can get the Sources also from https://github.com/ReinerMerz/reinerdemo (a public repository on Github).

Warning: This is only the sourcetree of the project, so you have to insert this in your own project file.

The post parts until now

Part 4-A The Javascript Part 1

Part 3 The Infrastructure and the CSS

Part 2 The HTML

Part 1 Overview

But first to Rethinking smartUI Part 4-A.

The Javascript auxiliary files

Using the model factory

The idea of a model factory is to combine several functions in one.

a. Create a model and return it.

b. Load server data into this model for use in the main constructor function

A typical factory looks like this:

// the factory for the model
define([
‘csui/utils/contexts/factories/factory’, // Factory base to inherit from
‘csui/utils/contexts/factories/connector’, // Factory for the server connector
‘ademo/widgets/docpad/impl/docpad.model’ // Model to create the factory for
], function (ModelFactory, ConnectorFactory, DocpadModel) {

‘use strict’;
var DocpadModelFactory = ModelFactory.extend({
propertyPrefix: ‘docpad’,
constructor: function DocpadModelFactory(context, options) {
ModelFactory.prototype.constructor.apply(this, arguments);
var connector = context.getObject(ConnectorFactory, options);
// Expose the model instance in the property key on this factory instance to be // used by the context
this.property = new DocpadModel(undefined, {connector: connector});
},
fetch: function (options) {
return this.property.fetch(options);
}
});
return DocpadModelFactory;
});

The main Javascript files

The lang.js file(s)

The language system consists of those strings which are pupposed to change per language.

define({
helloMessage: ‘Hello {0} {1}!’,
waitMessage: ‘Please wait’,
seldoc: ‘Select a Document’,
printdoc: ‘Print the selected Document’,
pickerTitle: ‘Select a Document’,
selectPickerButtonLabel: ‘Select’,
descNodeID: ‘Node-ID’,
desDescription: ‘Description’,
desCreated: ‘Created’,
desModified: ‘Modified’,
……more …..
});

The standard model from Backbone.js

define([
‘csui/lib/backbone’,
‘csui/utils/url’
], function (Backbone, Url) {
‘use strict’;

let DocpadModel = Backbone.Model.extend({
defaults: {
name: ‘Unnamed’
},

constructor: function DocpadModel(attributes, options) {
Backbone.Model.prototype.constructor.apply(this, arguments);

// Enable this model for communication with the CS REST API
if (options && options.connector) {
options.connector.assignTo(this);
}
},
// Computes the REST API URL using the connection options
// /auth returns information about the authenticated user
// usage of => not possible because of “this” is used for urls
url: function () {
return Url.combine(this.connector.connection.url, ‘/auth’);
} ,

parse: (response) => response.data

}];

return DocpadModel;

}];

 

Remark: The Arrow Function at parse is pure js6. But let me quote developer.mozilla.com here

An arrow function expression is a compact alternative to a traditional function expression, but is limited and can’t be used in all situations.

Differences & Limitations:

(Endquote)

This means, its not possibe to use when any limitation will take place, like in the constructor.

The docpad.view.js

The stages of docpad.view.js

Get infos via the Bootstrap model

constructor: function DocpadView(options) {
options.model = options.context.getModel(DocpadModelFactory);
Marionette.ItemView.prototype.constructor.call(this, options);
this.listenTo(this.model, ‘change’, this.render);
}

First, we initiate the model (and read the data) via a standard model using the model factory. Then we call the constructor in the prototype with the cs options. Lastly we listen to a change of the data and (in case) we rerender the widget.

Load the photo

The user data contains (eventually) a photo of the user. This is loaded and inserted in the DOM with the function loadPhoto. Here the js6+ fetch function is exposed to get the photo and insert it into after the element woth the .photo class in the dom.

loadPhoto: function () {
let server = this.model.connector.connection.url;
server = server.substr(0, server.search(“api/v1”));
let url = server + this.photo_url;
let ticket = this.model.connector.connection.session.ticket;
fetch(url, {method: ‘GET’, headers: {“OTCSTicket”: ticket}})
.then(response => response.blob())
.then(function (myBlob) {
const URL = window.URL || window.webkitURL;
let photo = URL.createObjectURL(myBlob);
let img = document.createElement(“img”);
img.classList.add(“photo”);
img.src = photo;
document.querySelector(“#photo”).appendChild(img);
setTimeout(() => {
URL.revokeObjectURL(photo);
}, 100); // cleanup
}
);
},

       
Using the Node-Picker

The Node-Picker is a standard function in the sdk, so we use it.

The file ‘csui/dialogs/node.picker/node.picker’, // the csui node picker

is required at the beginning of the docpad.view.js file under the local name of NodePicker like this:

define([
‘csui/lib/underscore’, // Cross-browser utility belt
‘csui/lib/marionette’, // Marionetter
‘csui/lib/moment’, // the date/time lib in csui
‘ademo/widgets/docpad/impl/docpad.model.factory’, // Factory for the data model
‘csui/dialogs/node.picker/node.picker’, // the csui node picker
‘i18n!ademo/widgets/docpad/impl/nls/lang’, // Use localizable texts
‘hbs!ademo/widgets/docpad/impl/docpad’, // Template to render the HTML
‘css!ademo/widgets/docpad/impl/base’, // base Stylesheet needed for this view
‘css!ademo/widgets/docpad/impl/adv’, // adv stylesheet for this app
‘css!ademo/widgets/docpad/impl/print’ // print style sheet
], function ( _, Marionette, Moment, DocpadModelFactory, NodePicker, lang, template)

The picker is started by pressing the big button, this actually calls showThePicker. Types of 144 (only Documents) and on the enterprise volume are among the start conditions.

The title and other strings are extacted from the appropriate lang.js language file(s). The command nodePicker.show() at the beginn of the chain displays the nodePicker

showThePicker: function () {
if (undefined === this) {
return;
}
let btn = document.querySelector(“.btn”);
btn.classList.remove(“animate-large”);
btn.classList.add(“animate-large-backward”);

let nodePicker = new NodePicker({
connector: this.model.connector,
selectableTypes: [144],
dialogTitle: lang.pickerTitle,
selectButtonLabel: lang.selectPickerButtonLabel,
startLocation: ‘enterprise.volume’
});
nodePicker.s how()
.fail(function () {
console.error(“Picker fails to show”);
})
.done(_.bind(function (args) {
document.querySelector(“.printbtn”).classList.remove(“hide”);
document.querySelector(“#content”).classList
.replace(“hide”, “display”);
let node = args.nodes[0];
let id = node.attributes.id;
this.docname = node.attributes.name;
document.querySelector(“#document1”).innerHTML = this.docname;
this.loadDocumentThumbnail(id); // load the thumbnail and display it
this.loadDescriptions(node); // load node data and display it
this.loadNodeData(id); // inquire form update data and display it
}, this)
);

},

The callback in the .done clause simply extracts the node id and the name from the results and stores them in the docpad “this”.

In the next week part “Rethinking smartUI Part 4-B” we’ll discuss the REST Commad how to get all document data (nearly) at once.

Rethinking smartUI Part 3

The upper PART

Two weeks ago I published a new video on Rethinking smartUI on Youtube. If you havn’t it seen yet, here is the short video. In this posts, we’ll go though the technical aspects of this new kind of approach to smartUI. This demo is a Document Pad (or short DocPad), displaying all document properties in a SCIFI GUI arrangement.

This is Part 3 of a multipart post covering the technical start of DocPad and the associated CSS

The post parts until now

Part 4-A The Javascript Part 1

Part 3 The Infrastructure and the CSS

Part 2 The HTML

Part 1 Overview

A. The technical infrastructure

Die DocPad is started via the index.html, found in the test folder of the docpad. This is because of its much easier to test modifications via index.html compared to installing the finished widget in the content server and trying it then.

The first part of index.html

The first part of index html

The whole page is more or less standard. We habe 4 areas of interest in the first part. Dont forget, nuc was introduced in 21.2. In older versions nuc was not existant.

  • A. Here, you see the config is moved to the nuc area
  • B. Change A will also require to add the nuc-extensions to the list of dependancies for csui. Thed whole js code is loaded by the “ademo” extension.
  • C. My machine is on a VM. This means, if you put this on your machine, you’ll have to enter your url and your support directory (called supportPath) in the configuration.
  • D. I’ve used my ticket to provide the login. You can use username and password to login the more convential way or also provide a ticket of youfself here. The displayed ticket won’t work at your site.

The second part of index.html

Part 2 of index html

Here we have this points of interest

  • A. The require parts of needed modules. It is a docpad.mock.js in the list of modules, but its not recommended to use the mockup facility because there is lot of traffic from and to the server. Its much easier to add a real content server behind that index.html.
  • B. Standard procedure. Instanciate the widget with the context, display it in the region and fetch the context from the server. As mentioned, its easiere to use a real server as data source so switch the mockup off.
  • C. The marionette region is associated with the id=”widget” of this div, so the widget is displayed here.

At the end there is immediate function starting with

(function() {
var ws = new WebSocket('ws://' + window.location.host + '/jb-server-page?reloadServiceClientId=1');

This is inserted by Webstorm (my JS IDE) to allow auto-reload of changed files. You can ignore that, other IDEs will solve that differently.

B. The CSS

The CSS

Here, all css files used in the docpad are listed in the require.js list of required modules. For demo purposed and to keep things simple, I used 3 css files:

base.css

This file contains the basic css instructions to style the .hbd template shown at the top of list.

adv.css

contains the more advanced css instructions for docpad

print.css

is the print style sheet to provide a proper output on paper.

Disclaimer: The css instructions selected do not impose or propose any styles to be followed, instead they are used for pure demo purposes here.

The base.css File

Here the main functionality of the css is found. One of the feature of css3, the variables, is used. In the pseudo element :root all variables used in different rules are defined.

css setup

At the end of the snipped you’ll see a media query, saying the following is used tor screen display.

Lets discuss several stages:

The header + the footer

Header
Footer

These two structures exploit the standard userinfo with REST from the content server in a standard backbone model. “Hello xxxxxx” is a structure from the hello world demo with the word “hello” and the signed in user. The photo is downloaded from the content server and dosplayed.

The bottom structure simply prints out other user data on the screen .

Points of interest:

Font used

The nice digital effect is build with the font “digital-7”

The header is done with

The header

Ther photo is inserted at the position of the .photo class in the size of 80×60 pixel. Then the photo gets this nioce rounded look using border-radius.

the footer conststs of three divs, which are positioned in 3 columns

The footer

The divs have the classes .boxcell and .leftbox and are descendants of the .footerbox

The document display

The document display consists of six divs and are positioned using a css grid.

docdisplay

They have numbers, the numbers range from one (“card1”) to 6 (“card6”). The css part is (shown here only a fraction):

Cards

They are all children of the cube, using the display mode grid and displaying the 6 cards in two rows and threee columns.

cube

Using the diffent REST methods in the js code, these cards were filled by the standard methods of DOM interaction from js. This will be the main theme of next weeks post, the js code of “Rethinking smartUI” Part 3.

Rethinking smartUI

Rethinking smartUI

Yesterday I published a new video on Rethinking smartUI on Youtube. If you havnt seen yet, here is the short video. In this posts, we’ll go though the technical aspects of this new kind of approach to smartUI. This demo is a Document Pad (or short DocPad), displaying all document properties in a SCIFI GUI arrangement.

This is Part 1 of a multipart post covering all aspects of this Docpad.

The post parts until now

Part 4-A The Javascript Part 1

Part 3 The Infrastructure and the CSS

Part 2 The HTML

Part 1 Overview

Part 1: Overview

This demo is supposed to do this:

  • Demonstrate the usage of html5, javascript 6 and css3. Especially how to use this modern components inside the smartUI framework. For example, the famous parse function in the standard demo widget will change this way:

js5
parse: function (response) {
// All attributes are placed below the data key
return response.data;
}

js6
parse: (response) => response.data

  • Compare the methods of getting data via REST using the methods
    • Model (as usual in Backbone)
    • XMLHttpRequest (the good old XMLHttpRequest as used since long)
    • Fetch (the modern javascript 6 method to get REST data)
    • Not used: async/await. Despite the fact that async/await is very handy, this appeared in javascript 8 and is beyond the scope of the demo.
  • Exploit the power of css by using
    • different display methods as Grid and Table
    • use panels in a cube. Origionally this was planned as moveable 3D cube. In this case, all metadata were written on the sides of the cube. Here is a very good technical description how to do it. Unfortunately the cube idea seems to be very impractical for the demo and was dropped
    • “burning borders”, fog and animations as element of the UI
    • provide an additional print style sheet to make this screen infos printeable in a normal way
  • Except some Icons of Bootstrap, nothing is to be used from Bootstrap. These Icons can be replaced by those in the fontawesome font
  • JQuery is not used
  • These Content Server REST commands are used
    • The log in is done in the index.html page, but when used as a dashboard widget the user is already logged in. If a separate login panel is required (p.ex. for a stand aloane dashboard on a tablet) then its necessary to provide a login via post […]/v1/auth
    • then the user info is retrieved via get […]/v1/auth
    • if the user has stored a photo in his profile, then the photo is retrieved by get […][photo-url] and then inserted in the DOM.
    • Then the standard Node-Picker Control is called. All Node-Picker interactions with the server are managed by this control. As a result, the nodeid of the selected Document is returned.
    • Next, the DAPINode infos of the selected node are retrieved by get […]/v1/nodes/{id}
    • for the “created_by” and “modified_by” there is only a nujmber returned, the userid. For this two cases, the username is retrieved from the server by get […]/v1/members
    • Its always nice to exploit the thumbnail of the document to the user. This is done by get […]/nodes/{id}/thumbnails/medium/content
    • To get all other data , a special trick is used. The command get […]/v1/forms/nodes/update returns all categories and the othere nodeinfos using one REST call. This commmand takes a while to execute, so the user is entertained using some css animations.

In the next week, we explore the infrastructure of this Docpad demo.

smartUI – Printing

Print in smartUI

The support for smartUI – printing is new in smartUI 21.3.

Technically you’ll find a new command in the “Sent To” dropdown menu

The new print command

Then you get a list of the files to print and a list of all available printers

List of Printers

Happy printing.

Requirements: Content Server Browser Web extension and ebterpriseconnect_framework_21.3_x64.msi installed.

smartUI Goodies for Webreport Fans

One of the smartUI goodies for webreports

In the rich universe of Opentexts smartUI there are even some goodies for the webreport addicts. Besides the standard webreport widgets there are two controls witch are used happily and heavily by webreports designers, named Parameter.Prompt and Status.Screen. These are the true smartUI Goodies for Webreport fans.

smartUI support
Need smartUI support?

Especially two controls are of interest for the seasoned webreport developer.

For tests, I’ve used a senseless webreport

A senseless webreport just for demonstration

This is a dummy webreport with several parameters. At the top right corner you see the execution result. Just for demonstration purposes, this has been kept simple and stupid.

But what if…….. the webreport is supposed to be run under the new and amazing smartUI? In this case we have two controls to help.

Parameter.Prompt

This control senses, if the webreport does have one or several parameters and allows to alter the parameters before the webreport is started.

PArameter.Prompt, a special service for all the webreport addicts

Here, all parameters can be changed. A click on “Run WebReport” will start the webreport if activated.

The js code is easy

JS code for the parameter prompt control

Status.Screen

can be used to start the webreport and to display some End-Messages. A standard situation is displayed here

A webreport has finished and the End-Messages are displayed

For example, if a html file is defined as output under the folder “webreports”, then this infos can be displayed at the status screen.

The js code is easy

A smartUI goodie for webreport fans in JS: status.screen

Both controls can be combined to a widget to start and execute webreports.

If you need some more sophisticated, its easy to override those controls with custom controls.

That were the smartUI Goodies for Webreport Fans.

Happy playing with webreports, but dont forget: Webreports will make a machine not faster!

The new DEMO widget

Demo Widget for Learning By Doing workshop

We made it. We finished a simple widget for smartUI to demonstrate a lot of features of smartUI inside our new workshop “Learning by Doing”.

This is a remote workshop and during 2 days you get the source code of the widget and learn, how this widget is developed from the standard hello widget.

The widget features

  • Usage of Glyphicons in binf
  • programmable multi line tooltips in binf
  • Navigationbars in binf with commands behind the targets
  • expanding and collapsing of structures using binf
  • a dateselector on an input type=date field
  • switching a label to an input field and vice versa
  • rendering the logged in user photo from a content server behind
  • use a nodepicker to select a document and render the thumbnail
  • add a user select control after the widget is rendered
  • delete the “copy” command in smartUI
  • display messageboxes and global messageboxes
  • use a standard slide in and use a wizard slide in with several views

See here a short video (20min) of the features

And dont forget to register for the next workshop “smartUI Learning by Doing”

The new smartUI Nuc. A closer look.

The new NUC package in smartUI

Disclaimer: The discussed topic is on Content Server 21.2 smartUI SDK and may change anytime without notice after today (I dont hope so, but….)

The new package nuc in the smartUI SDK is the

(quote) nucleus of the nucleus (endquote)

and something like “the Best of the best, Sir” (Men in Black I)

What is nuc?

Lets take a look at the lib/src folder in an initialized 21.2 project. To see the images larger, right click and open the image in a new tab.

Nuc, The Nucleus of the Nucleus

The nuc consists of these folders:

utils

This folder was located in the csui package in ancient time. Nowadays it has moved to nuc.

If you compare that to the csui/utils(21.1), you’ll discover a few differences

And also csui/utils(21.2)

If you use requirejs paths to elements, which are not in csui/utils(21.2), you should check these references and edit them to point to the proper element if needed.

models

This folder was located in the csui package in ancient time. Nowadays it has moved to nuc.

If you compare this with the csui/models(21.1), you’ll notice a few differences.

And also compared to the csui/models(21.2) there are differences:

A closer look reveals, that the csui/models(21.2) is not identical to csui/models(21.1) and therefore you are supposed to correct manually any requirejs paths in your js code, if you have to require those models moved from csui/models to nuc/models.

lib

This folder was located in the csui package in ancient time. Nowadays it has moved to nuc. The folder contains

If you compare that with lib at csui (21.1) and also with that lib folder existing in the csui (21.2), you’ll discover, that csui/lib(21.1) is the same as csui/lib(21.2), whereas nuc contains a subset of the entries of 21.1. At least on 21.2 the csui/lib references seem to work perfect, so that those in nuc/lib could be ignored.

grunt-tasks

This folder was located in the csui package in ancient time. Nowadays it has moved to nuc. It contains that:

If you compare that with the grunt-tasks at 21.1, you’ll discover a surprisingly large amount of additional documentation files. The old 21.1 csui/grunt-tasks had only the README.md, whereas there are a lot of additional md’s on 21.2 nuc/grunt-tasks available.

bundles

this is a new folder consisting of a couple of pre-defined bundles. These Defines([]) are quite handy to use. Nothing special here.

Amending the tabbed perspective

Tabs in the header: Playing hide&seek

In the tabbed perspective there is a nice game of hide and seek implemented. This gives you excellent entertainment, but you can amend this to simply display tabs as usually in any non-gaming environment. All examples here are displayed using the index.html from the /lib/src/csui/perspectives/tabbed.text/index.html. (Version 21.1)

The described way tabbed perspectives behave in smartUI is not a bug, its a feature.

The initial game

It goes like this:

The not so hidden hide&seek tab mode

If you have defined a header and several tabs, filled with standard data, you’ll see this initially. But when you click on any but the first header, the game is activated.

Hide&seek mode activated

A simple click on the tab name activates the hide &seek mode. The tabs try to hide and you are supposed to seek for them. This is really a nice and entertaining game.

The conservative Amendment

But what if you want to switch off this challenging mode?

Deactivating the hide&seek mode to allow the more conservative tab display

The build in hide&seek mode can be switched off by commenting this two lines in the tabbed.perspective.view.js.

A reload of the test page gives you by clicking to the second or thirth tab this:

The converwative Tab Display.

Although you switched of the hide&seek mode, you can now use the SDK to display the tabs in a more conservative way.

The smartUI SDK is very versatile and can be used for several purposes, even for conservative tab displays.

The only thing to decide for you is how to change that in the smartUI. Either spawn this into your own perspective or map your changed .js file over the standard requirejs path, this is up to you. You can even try to clear the cs-collapse.css and cs-toggling.css classes using the csui-stype-override-kit (I have not tested that for side-effects).

Happy tabbing.

New in 21.1: Multilingual Metadata Support

Multilingual Metadata in 21.1

Finally, Multilingual Metadata Support is implemented in Content Server 21.1. Before that version there was only Support available here.

The Users Point of Vue

Multilingual Metadata can be added/edited at the Property Panel of a document. The first screenshot gives the entry of the name, the second gives the entry of the Description field.

Multilingual Metadata in 21.1
Multilingual Metadata in 21.1

Only Names and Descriptions are supported for Multilingual Metadata. For more fields or even Category Attributes in multiple languages, refer to an OpenText Partner like CASSIA.

The Programmers Point of Vue

The Name and Description fields show at least two multilingual text pickers. These are found in the SDK in /lib/csui/controls/multilingual.text.picker and in /lib/csui/dialogs/multilingual.text.picker. Unfortunately there is no Documentation and no index.html. Lets take a look on that control:

The Controls

The left screenshot is from dialogs, the right is from controls.

Multilingual Text PIcker

This is embedded in the header.view.js from the dialogs/node.picker and will only be activated, if Metadata Languages are enabled. The mixin allows the form to be displayed as a Bootstrap Popover.

Mixin Start

Changes in that area require the changed multilingu<al text picker and also the changed paths to be followed for that changes. Therefore require a spawn of the whole nodestable widget to reflect that changes. This is acually not recommended.

Happy MLM