Tag Archives: Tutorial

HTML5, Javascript and CSS3 training videos for Uniface developers on Uniface.info

The Web capabilities of Uniface have increased year over year. At the moment there are at least six different architectures to integrate Web technology in Uniface or build full Web applications in Uniface.  The HTML5 Widget, Uniface Anywhere and DSPs are obvious examples. In an upcoming blog post, I will go into more detail comparing all options.

Developing modern enterprise applications also requires more Web knowledge for Uniface Developers.

To facilitate this we made a special series of training videos on Web topics for Uniface developers. This series is available on Uniface.info and consists of Introduction and Advanced videos on HTML5, Javascript and CSS3.

The Introduction videos assume zero existing knowledge of the technology. The Advanced Topics can be played in any order and assume the Introduction as pre-requisite. Some videos come with demo material which is available as a download.

To make it easy, I’ve listed all the available videos:

HTML:

Hello World:  http://unifaceinfo.com/html-hello-world/

This session is an introduction to the Hyper Text Markup Language (HTML). We will be creating our first website and use a couple of HTML elements to display some simple text and an image.

Introduction: http://unifaceinfo.com/html5-introduction/

This session discusses the basics of HTML5. It introduces a lot of new HTML elements to give a clear structure to your website. Why are semantics are important?

Canvas: http://unifaceinfo.com/html5-canvas/

This session discusses the HTML5 canvas. We’ll create a simple Uniface graphic by ourselves, and have a look at some more complex examples.

SVG & Multimedia: http://unifaceinfo.com/html5-svg-multimedia/

This session is all about the HTML5 SVG, audio and video elements. We’ll discuss the differences between a Canvas and SVG, and see how we can incorporate a video and mp3 without using Flash or third party libraries.

Geolocation & Storage: http://unifaceinfo.com/html5-geolocation-storage/

This session is about using getCurrentPosition() to obtain the GPS coordinates of the user. Afterwards we’ll store this information in the localStorage object so it is remembered.

Javascript:

Introduction 1: http://unifaceinfo.com/javascript-introduction/

This session is an introduction to JavaScript. Its main characteristics will be discussed, and we will be looking at an example. Moreover we will have a quick glance at its connection with HTML.

Introduction 2: http://unifaceinfo.com/javascript-introduction-ii/

This session is part II of the introduction JavaScript session. We will be looking at some more useful functions, types, objects and arrays.

D3: http://unifaceinfo.com/javascript-d3/

This is a short session about D3. We’ll discuss some use cases and see how it works through the use of some examples. 

JSON: http://unifaceinfo.com/javascript-json/

This is a short session about JSON. We’ll quickly see what it is, how it works, and how you can actually use it.

Advanced Javascript: http://unifaceinfo.com/javascript-advanced/

This is an in-depth session about JavaScript. We’ll go through different ways of using events, and see how the only option of executing things in parallel in Javascript is using callbacks.

 

CSS3:

Introduction: http://unifaceinfo.com/css-introduction/

In this session we’ll explore the new possibilities of CSS3. It provides a lot of new features that make the life of the developer and designer a lot easier.

Advanced CSS3: http://unifaceinfo.com/css3-advanced/

This is a follow-up of the CSS3 – Introduction session. Transformations allow you to modify the appearance of any HTML to your liking. Be it rotated, translated or skewed. Transformations and animations make HTML elements move around and respond to events.

If you have a question about any of the videos just open a topic on the forum.

 

Uniface 64 bit deployment for Windows

During the deployment session from the Uniface Lectures, we covered Uniface 64 bit deployment for Windows in the morning session (not in the afternoon because it took to much time, the videos are available to watch on our YouTube channel though). 

We had a few really interesting questions, I’ve worked the answers into the text below and I dug up an old posting from the old Frontline site, and used that as the basis. 

The oldest Uniface PAM (Product Availability Matrix) I could find was from Uniface 6.1, and with that old version we  delivered 64 bit support on DEC Alpha hardware with Uniface 6.1. OpenVMS, and DEC Unix ports of Uniface. I remember seeing one of the DEC Unix workstations here in the Amsterdam Lab, running the Motif GUI and thinking how advanced it was, how fast it was and I wanted one. Always dangerous to wish for more, I ended up with a Mac on my desk a week later. 

For a number of releases we focused on Uniface server versions for 64 bit, think IBM AIX, HP-UX, Intel Titanium hardware and so forth.  

It was in 2012 that we delivered a 64 bit Windows server version, delivering it in Uniface 9.5.  

It took us a long time, and to be honest, I recall have a few conversations on the topic over the years, and from an out and out technical perspective, the view was that there were few perceived benefits when compared to the 32 bit version to justify the investment to make it happen. I should mention that we had done some clever things with compiler switches to enable memory addressing for a number of releases. 

A Windows 64 bit Uniface client was a different story, and was quite a significant project.  Clearly there were overlaps with the Windows Server (technically they share a lot of common source), but the GUI layer needed a lot of work. We had to refactor a lot of code, as we had a lot of legacy (technical debt) from older versions of Uniface. The name Uniface originated from Universal Interface, and it was possible to develop one Uniface app and deploy it on those old GUI platforms which we used to support thanks to the Uniface specific widgets such as the unifield.  (I’m sure some of us who have been around Uniface for a long time remembers Uniface on Mac, Motif, OS/2 and Windows 3.x.)  There was a lot of old code to clean up and/or remove, and we also have to keep those legacy widgets operational. 

A few additional challenges included our use of automated test tools which didn’t support 64 bit platforms, which also forced our journey to replace them and use Ranorex for our testing. (I’ve covered this in the forums and talked at a few user groups on this topic.)  

We delivered a Windows 64 bit client with Uniface 9.6 in December 2012. We’ve had some good feedback, I recall talking to a customer in the UK, and their comment was that it just seems more ‘fluid’. I talked about this with one of the architects, and the view is that this is probably as a result of the refactoring, possible the additional memory capabilities, but it’s great to get positive feedback. 

It’s available for deployment rather than development, as we have a few external pieces of functionality in the developer, for example the DSP Editor which are not available as a 64 bit product. 

The HTML control we delivered in Uniface 9.6 is also currently restricted to 32 bit. But this will change, it’s based on Chromium (sometimes know as CEF) from Google, and the sources were (finally) updated to 64 bit and we have been working on getting that into Uniface 9.7, and will be part of the Uniface 9.7.02 update which we are finalising. That was a challenge to get working, changes to threading models and API’s meant some rework and lots of testing, but it’s pretty well code complete. 

The Uniface 10 IDE uses that same HTML control extensively, so the move to CEF3, now opens the way to deliver a 64 bit developer. There will be a significant Uniface 10 release in September, but this is something for another posting next month.    

 

Drop it like it’s hot

What very few people know is that in the Import Repository Objects component there is a small section where you can drag and drop your export files from Windows Explorer.  After you drop them, the File name box is updated with the list of files that you dropped.

Uniface

The red section is where the drag-and-drop field is located.

Download for this drag n drop sample

Creating this element in your own component is pretty easy. Just follow these steps:

  1. Create a component. In this example I have created a component named DragNDrop
  2. Paint an entity. I used a non-database entity named DE in the DM application model.
  3. Paint a field. DROPTARGET
  4. Now set the properties according to the image below.

Uniface

We set the widget type to DropTarget indicating that this element will be able to receive elements using a drop event. Make sure you painted the widget large enough so that you can find it very easy on the component. In this setting the widget will have the same gray color as the rest of the component, making it impossible to find if you paint it too small. I painted it across the entire component so it is impossible to miss.

I have set the datatype to string since the result will of a type string. Made the interface a shorthand C* just because I do not know how long the string of filenames will be and the default of 40 characters will probably not cut it.

Now compile the component and test it by dragging something from Windows Explorer to the droptarget.

As you may have noticed that did not work at all. No worries you need to make one small change and it will work.

DoubleClick the droptarget widget to open the properties and then navigate to the widget properties. In the valrep list enter a value named “file” and leave the representation empty.

Uniface

When you compile it and test it again you will notice that the mouse pointer changes from the no-entry sign to a arrow with a plus sign when you hover over the drop target. You can drop it, but it will not do very much.

How to get to the goodies

Dropping something on the drop target will fire the value changed trigger. Here you can put the code to verify if the dropped elements are actually the files that you want and process them further.

In my component I have created an entity FILES in the DM application model and added a field named NM of type string and set its interface to C*. The component looks like this:

Uniface

Next I opened the value changed trigger of the DROPTARGET field and added the following:

variables
   string v_nm
endvariables
 
forlist v_nm in <$fieldname>.<$entname>
   if ($lfileexists(v_nm))
      creocc "FILES"
      NM.FILES = v_nm
   endif
endfor
 
sort "FILES", "NM"
 
; reset the background image
<$fieldname>.<$entname> = "image"

In the first line I declared a variables block holding a string variable named v_nm. In the fifth line the forlist command extracts a value from my droptarget field and inserts it in the variable. After I checked if it the file exists, I add a record to my FILES entity and adds the variable value to the NM field in the entity.

The reference to <$fieldname>.<$entname> will be replaced during compilation with the actual fieldname. In my case DROPTARGET.DE.

If you are using Uniface prior to 9.5.01 you cannot use the forlist command. You should use a combination of getitem, delitem. I am assuming you know how to do this, if not here is an example:

variables
   string v_nm
endvariables
 
while <$fieldname>.<$entname> != ""
   getitem v_nm, <$fieldname>.<$entname>, 1
   delitem <$fieldname>.<$entname>, 1
 
   if ($lfileexists(v_nm))
      creocc "FILES"
      NM.FILES = v_nm
   endif
endwhile
 
sort "FILES", "NM"
 
; reset the background image
<$fieldname>.<$entname> = "image"

Picture this

The last line in the previous code might have given it away, but I am using an image to highlight the droparea. On the drop event this value is being reset to the list of files, so after processing I need to reset it. Otherwise I will be left with a grey target or even worse, a target screaming “!format” at me.

In the same location where we created the file valrep just minutes ago, I have added a value “image” and a representation “@droptarget.png”. The @ symbol implies that we are loading an image file named droptarget.png from the project folder and displaying it in the widget. The properties now look like this:

Uniface

Just get your own cool looking image file and play around with the properties to get it right.

To make sure the image is loaded on startup of the component we need to add two more lines to our component. In the EXECUTE trigger we add:

DROPTARGET.DE = "image"
edit

My component finally looks like this:

Uniface

Download for this drag n drop sample

Re-inventing the Uniface customer events

Our Uniface customer event season has just started, and several of us have been busy preparing content which we will be delivering at various events around the world. We have decided to make some changes to the events which we (Uniface) run ourselves although we always make the content available to the various independent user groups such as Face to Face in the Netherlands and UnifaceBenutzerGruppe, or UBG in Germany

The thinking started last year (2014) at the US Event in Las Vegas, where we ran the ever popular ‘Speed Networking sessions’ which are a cross between round table discussions and speed dating. One of the topics was ‘The Future of the NAUUG’, chaired by Zulayka. (NAUUG being North American Uniface User Group). 

The feedback we got was interesting, and we’ve taken a lot of it onboard. The primary points being that there was a desire for the content to be more technical, and code, techniques and techie stuff is the most interesting. (We also see that technically oriented blog posts on Uniface.info are generally the most popular.)

Uniface
Uniface

The result is that this year, the user events that we are running are Developer Conferences, with a focus on the technical content. We’ve also been working hard on the technical content, which will cover a variety of topics, such as UX, integration, development techniques, etc and will include getting into the code, with the source code being made available for future reference, use and enhancement. The sessions are delivered by various members of the Uniface technical team, and it should add up to be a really compelling reason to attend the events. 

We have Developer Conferences already scheduled for the UK, France and the US which is always our biggest event over three days, and this week a few of us are in Japan, with one event in Tokyo and one in Osaka (both of which are sold out), and I’m sure we will have more events in 2016. The technical content is available to be used at the other customer events which we don’t run ourselves, for example some of the Uniface team are in Israel this week and we usually have events in Latin America and Australia, although we’ve not booked anything at this time. 

Where to put your code

As a Uniface developer, I’ve seen a lot of Uniface applications first hand. On more than one occasion I encountered a situation where developers put all their code in the component. This happened for a number of reasons—access to the model or the library was constricted, there wasn’t enough time in the project to do it correctly, or just unfamiliarity with Uniface. I cannot speak on behalf of project managers or architects, but I can tell you how I code my projects.

The first rule of Uniface is that you do not copy and paste! (Very obvious movie reference!) If you find yourself in a situation that you think you need to copy code: stop! You are probably better off removing the code from its original source, putting it in either the application model or the library, and then reusing it in both the original component and the component where you wanted to paste it.

Single field implementation

Consider the following:

if (HEIGHT.PERSON < 0)

HEIGHT.PERSON = 0

endif

 

A person can never have a height that is smaller than 0 meters. Maybe there are people with a negative size, but I have never seen one. So if someone enters a negative value we reset the value to 0. If you were to put this in a component, than you need to copy and paste it the next time you need it. Remember the first rule? So where would you put it? The most logical place would be in the trigger of the modeled field HEIGHT in the PERSON entity. Creating an entry on entity level and then calling it from the leave field trigger would score equally well. This way the inheritance in Uniface will provide this piece of code in every component you use the field on.

Multiple field implementation

On record level

But what about two fields in the same entity? The formula for the Body Mass Index of a person would be:

BMI.PERSON = WEIGHT.PERSON/$sqrt(HEIGHT.PERSON)

The content of BMI is calculated by dividing the WEIGHT by the square root of a person’s HEIGHT. In order to calculate the BMI we need the value of two different fields in the entity PERSON.

If you thought about putting it in the modelled entity you’d be correct. I would create an entry that can be reused in (for instance) the value changed triggers of the WEIGHT and HEIGHT field or call it from a collection operation if you wanted to update all the BMI’s in some type of batch.

Between entities

Here is a classic. The total amount of an order is calculated by multiplying the price by the number of items in an order line, and then adding that to the total of the order. :

forentity "ORDERLINE"

   TOTAL.ORDER += PRIZE.ORDERLINE * NUMBERITEMS.ORDERLINE

endfor

 

The second rule of Uniface (you can actually here the voice of Brad Pitt, can’t you?) is that you never make a reference to another entity from a modelled entity. If you do, you need to include the referenced entity on every component you use the modeled entity on or the compiler will keep wagging its finger at you.

So we can’t reference the TOTAL.ORDER field in the trigger of the ORDERLINES entity. The only logical place is to put it in in a component. In this case, I would put it in a service that can be called from other locations as well. I can even activate that service in the modelled trigger of the ORDER entity.

What if it is a non-database entity?

Non-database entities come in two distinct flavors. The modelled ones and the non-modelled ones. An example of a modelled non-database entity is the entity containing a list of buttons containing default behavior that you can reuse when creating components. With these particular non-database entities the same rules apply as for the modelled database entities.

Non-modelled entities are created on the fly on a component. In this case there is only one place to put your code. The component level.

And non-database fields?

Non-database fields, have the same distinct flavors. They are either modelled (for instance a button that shows detailed information about a certain record of a modelled entity) or the non-modelled ones. If the non-database field is in the application model, code it there, otherwise code it in the component.

When I mention the component, there are actually three levels where to place your code. In the triggers of the component, in the triggers of the non-database entity, or in the triggers of the non-database field. Based on the previous rules you should be able to determine the correct position.

There is no entity or field reference

Once more for good measure:

 

if ($status < 0)

   return $status 

endif 

This code contains no field references and is of a more technical nature. This is an example of the smallest form of error handling in Uniface. If you intend to use it only once, the component is the best place to put it. If you need it in other places, you should move the code to the library and include it where required.

Can I use A Global Proc, instead of an Include Proc?

I have not used a Global Proc since the introduction of Include Procs. In my mind it is a deprecated feature of Uniface. From a component based development perspective Include Procs are better (but that is for another story). Besides using Global Procs for error handling purposes has one drawback. What happens when your Global Proc fails? Where are you going to catch that?

Let’s Summarize

Description Logical place
Code references exactly one field in one modeled entity Trigger level of the modelled field
Code references more than one field in one modeled entity Trigger level of the modelled entity
Code references more than one modeled entity In the component, preferably a service.
Code references a non-modeled entity If a non-modeled entity is used more than once, it should be defined as a modeled non-database entity. If it is a very specific non-modeled entity, it can be only in the component.
Code does not reference a field or an entity. Include proc. Never in a global proc. Component only, when it is really specific.