Today I learned

Share business templates, ideas, experiences, etc with fellow Servoy developers here

Today I learned

Postby Bernd.N » Sun Sep 04, 2016 3:01 pm

This is for sharing topics I learned which might be interesting for others.

Today I stumbled over an interesting site that lists all UTF-symbols, which can be used like characters when using UTF coding in the own database.
That might be an alternative to showing PNG-icons in some cases, which need much more space than a single UTF symbol. Examples:
http://www.w3schools.com/charsets/ref_utf_dingbats.asp

It is possible to just copy-paste the symbols from there, like ❏❌❔✞✔⋃◔

That w3schools offers also a huge range of tutorials, e.g. for JavaScript, SQL, AngularJS.
Example for JS object tutorial:
http://www.w3schools.com/js/js_object_definition.asp
Last edited by Bernd.N on Mon Sep 12, 2016 11:54 pm, edited 1 time in total.
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 544
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Example of Dataset Usage

Postby Bernd.N » Sun Sep 11, 2016 9:48 am

In https://forum.servoy.com/viewtopic.php?f=22&t=21438 Marc showed how to use a dataset.
I wrote some sample code for myself about how to use it as temporary data storage at runtime, without any associated database table.
It would not be necessary to put 5 empty rows into the dataset in the beginning, 0 would be fine too, that's just an example.

Code: Select all
function exampleOfJSDataSet(event) {

   var
      /** @type {JSDataSet<client_id:UUID, client_name:String>} */
      myDs = databaseManager.createEmptyDataSet(5, ['client_id','client_name']),
      i = 1;

   myDs.addRow([application.getUUID(), "Meier"]);
   myDs.addRow([application.getUUID(), "Müller"]);
   myDs.addRow([application.getUUID(), "Schulze"]);
      
   for (i = 1; i <= myDs.getMaxRowIndex(); i++) {
      
      myDs.rowIndex = i;
      
      application.output(i + " " + myDs.client_id + " " + myDs.client_name);
   }
}

The result is this list:
1
2
3
4
5
6 926C6E1F-B64D-4A48-8309-D29768F2E546 Meier
7 EE523581-A868-4136-B0C1-98F9A8F71B48 Müller
8 7E0075B6-52BC-44D0-8F4A-464F77A4F372 Schulze

Docs can be found at https://wiki.servoy.com/display/public/DOCS/JSDataSet
There is an example about addRow() where an index is in front as first parameter. That is not needed.

There are important remarks in the online-help of createDataSource, that you can get when typing myDs.createDataSource into a JS-file and then CTRL+space:
A temporary datasource cannot be removed because once created there may always be forms or relations that refer to it. When the client exits, all datasources used by that client are removed automatically. Most resources used by the datasource can be released by deleting all records: dataset.removeRow(-1) or databaseManager.getFoundSet(datasource).deleteAllRecords()
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 544
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Preventing of jumps in table forms

Postby Bernd.N » Thu Sep 22, 2016 11:04 pm

I use an own todo list table where I had two problems:
todo_list.png
todo_list.png (11.86 KiB) Viewed 13556 times

a) After using the +-button to add a line directly under an existing todo, the table changed in a way that the new record was shown at the top of the table, so the complete visible section was moved which gave a bad UX.
b) After clicking the done checkbox, which sorts the done todo to the end of the list, I wanted to stay on the next "not done" line, without any movement of the visible line section, quite similar to (a).

I now figured out how to do this, an insert of foundset.setSelectedIndex(1) did it.
(The td_priority is the number in the P. column, which I use to sort the todos.)

Code for (a):
Code: Select all
function btnAddUnderThisTodo(event) {

   addTodo(event, td_priority);
}

function addTodo(event, numberOfExistingTodo) {

   var
      /** @type {JSRecord<db:/bob/todos>} */
      rRec = scopes.utils.recordAdd(null, null, null, foundset);
   
   
   if (numberOfExistingTodo) {
   
      rRec.td_priority = numberOfExistingTodo + 1;
      
   } else {
   
      rRec.td_priority = 1;
   }
   
   rRec.td_done    = 0;
   
   rRec.todo_list_id = application.getUUID(_todoListFilter);
   
   databaseManager.saveData(rRec);
   
   sort();
   
   // BK Sep 22, 2016
   foundset.setSelectedIndex(1);
   
   foundset.selectRecord(rRec.todo_id);
   
   elements.td_name.requestFocus();
}


Code for (b) is:
Code: Select all
function onDataChangeDone(oldValue, newValue, event) {

   var iSelectedIndex = foundset.getSelectedIndex();
   
   td_end = new Date();
   
   sort();
   
   // BK Sep 22, 2016
   foundset.setSelectedIndex(1);
   foundset.setSelectedIndex(iSelectedIndex);
   
   return true;
}
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 544
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Direct call of a function from a button

Postby Bernd.N » Fri Sep 23, 2016 8:55 am

We put small i-buttons in our forms that show context-specific information. Until now I always created a form function for the onAction event to call a getDialog() function to show the information.
But that is not necessary when coding a second function that just calls getDialog, and has an event parameter as first parameter.
(getDialog() can not be called directly in the onAction as Servoy wants to put the event as first parameter)
A slight disadvantage is that a Ctrl-H-search of "formGetDialog" will not find that call any more, however the string for the parameter sDialogName can be found.

Sure I could put the event parameter already in the main getDialog(), but I want to avoid to change all existing calls now.
For Servoy newbies: after double clicking in the onAction event to set the function, it is not necessary to search it in the list. Typing of "formGet" will be sufficient and Servoy shows the function automatically.

In future, when I create a new generic function that could be called by different buttons, I will always put an event as first parameter for such situations. In case I don't have an event I still can use null as value for the event.

formGetDialog.png
formGetDialog.png (13.65 KiB) Viewed 13533 times

Code: Select all
/**
* Used to call a dialog directly in the onAction event
*
* @param {JSEvent} event
* @param {String} sDialogName
* @public
*/
function formGetDialog(event, sDialogName) {

   getDialog(sDialogName);
}

...
function getDialog(sDialogName) {
...
}
Last edited by Bernd.N on Mon Oct 03, 2016 12:42 am, edited 1 time in total.
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 544
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

SQL Tuning Explained

Postby Bernd.N » Mon Sep 26, 2016 12:47 pm

Well-written and available also in French and German
http://use-the-index-luke.com/
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 544
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Fast and professional wireframing

Postby Bernd.N » Thu Sep 29, 2016 6:38 pm

Although form development with Servoy is very fast, the rich UI of its developer might intimidate a customer that you invited to develop a form prototype together on your screen or with skype.
I once tried balsamiq, but I remember it needed more time than developing right away with Servoy.

That impression I didn't have when I tried pidoco today, it really has a fast UI/UX and I could start in a minute just by trying it.
Pricing is moderate with just 10 EUR/12 USD per month.
https://pidoco.com/en

pidoco.png
pidoco.png (148.29 KiB) Viewed 13422 times
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 544
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Re: Today I learned

Postby rafig » Thu Sep 29, 2016 6:55 pm

Here is another tool for doing quick UI design (for Mac or Windows)
http://www.mockupscreens.com
they also do a product for creating sample data (only Windows)
http://www.mockupdata.com

Rafi
Servoy Certified Developer
Image
rafig
 
Posts: 701
Joined: Mon Dec 22, 2003 12:58 pm
Location: Watford, UK

Separation of listbox values

Postby Bernd.N » Fri Sep 30, 2016 12:16 am

Until now I used an empty line to group listbox values.
But a "-" (minus sign) as display value is better.
Because it creates a full separating line, and the mouse cursor jumps over it automatically, thus creating a better UX.

listbox.png
listbox.png (2.76 KiB) Viewed 13406 times
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 544
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Nice Diff Online / Atlassian SourceTree

Postby Bernd.N » Sun Oct 02, 2016 11:23 pm

Linux and Unix users have diff to find differences between two (source code) files.
A nice online version for a quick and comfortable diff view can be found at https://www.diffchecker.com

BTW, when using Atlassian SourceTree as source code controller in a distributed development environment, one gets diff views for all changed files automatically with each commit.
In this online tutorial that can be seen in the right lower corner (red and green lines) at around 7:00 :
https://youtu.be/F-pwasIyec0?t=6m48s

Here's how to install SourceTree
http://www.dotzlaw.com/tutorials/servoy-tutorials/servoy-tutorial-git-sourcetree/
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 544
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Checkboxes convert boolean variables into integers

Postby Bernd.N » Mon Oct 03, 2016 12:29 am

Whenever possible I use boolean variables, as it creates nice code when they are involved.
The reason is you can just write
Code: Select all
if (_bBooleanVariable) { ...

and you do not have to compare it to another value, as it is already true or false, which is most elegant.

Today I created a form variable
Code: Select all
var _bMyProjectTemplates = true;

as the data provider for a checkbox that is intended to toggle a filter between records of the current user and all records.
(The underscore is our default notation for form variables, to prevent to shadow any field names.)

The problem was that the initial true value did not render the checkbox as checked.
So in this case, I had to use an integer and switched the code to
Code: Select all
var _iMyProjectTemplates = 1;


While writing this, I had the feeling that a checkbox will always turn a boolean var into an integer, as JavaScript is not strongly typed, and checked that with an application.output in the onDataChange - and indeed, that is the case, so no wonder this was not working: a checkbox converts a boolean var silently into an integer, without complaining ... :idea:

Fortunately one can still write
Code: Select all
if (_iMyProjectTemplates) {
...
}

as a 1 evaluates to true and a 0 to false in JavaScript.
Last edited by Bernd.N on Tue Mar 14, 2017 11:21 am, edited 1 time in total.
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 544
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Regex Tester

Postby Bernd.N » Mon Oct 03, 2016 4:32 pm

I wanted to clean up the data structure of a table regarding fields that are not used any more.
So I needed to lookup all code with STRG-H-search for field names that I guessed are deprecated, for example "pe_bookable".
That found a lot of lines where another field "pe_bookable_by" showed up.
But I could not google a regex like "Find string1 but not string2".

Good news is I stumbled over a nice regex testing tool, where I could stuff all lines from the first search, and then highlight those without pe_bookable_by, as that regex is well documented in the web:
^((?!pe_bookable_by).)*$
http://www.regexpal.com/15

The tool furthermore nicely explains the meaning of every single expression in the complete regex, just by holding the mouse over the symbols:

regexpal.png
regexpal.png (117.07 KiB) Viewed 13292 times
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 544
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Configuring Eclipse Shortcuts

Postby Bernd.N » Tue Oct 04, 2016 10:47 am

In Servoy Developer, Ctrl+Shift-L is the command I use the most, as an alternative to search objects in the Solution Explorer.
When I wondered today how to define keyboard shortcuts in Eclipse, I found out that pressing Ctrl+Shift-L twice shows the shortcuts, and a third Ctrl+Shift-L will show the shortcut configurator.
To get an overview about the current key assignments, it is possible to sort the binding column by header mouseclick. Conflicts (double assignments) will be shown.

Now I do not longer have to press three keys to open the js of a form, as I decided F5 is best for this so much needed function.
And F8 starts the client now, also replacing a three-key-kombination I could never keep in mind... :)
Last edited by Bernd.N on Mon Oct 10, 2016 11:52 am, edited 2 times in total.
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 544
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Setting namedFoundSet to empty

Postby Bernd.N » Thu Oct 06, 2016 10:51 am

Regarding the business partner table form of our application, I just asked myself:
Why should that table initially load 200 records onShow, thus stressing the network, when those records are not really relevant for a user as they have about 7.000 business partners.
Why not wait until the user searches a business partner name or a city name?

I guess that's the intention of the form property namedFoundSet = -empty-, as that prevents the inital loading of the first 200 records.
Now comes the hard part, to communicate this to some hundred users before the next update, to prevent a flood of emails to the 1st level helpdesk that all business partners are gone.... :)
Luckily we have already an "All" button that shows all records again.
And I will also show an information about this new behaviour in onShow(firstShow) that the user can suppress with a checkbox, so the helpdesk should be fine.
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 544
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Re: Today I learned

Postby sbutler » Thu Oct 06, 2016 4:49 pm

There is also an API call not well known:

Code: Select all
databaseManager.setCreateEmptyFormFoundsets()


That will do all form foundsets by default. You can run it onSolutionOpen.
Scott Butler
iTech Professionals, Inc.
SAN Partner

Servoy Consulting & Development
Servoy University- Training Videos
Servoy Components- Plugins, Beans, and Web Components
Servoy Guy- Tips & Resources
ServoyForge- Open Source Components
User avatar
sbutler
Servoy Expert
 
Posts: 758
Joined: Sun Jan 08, 2006 7:15 am
Location: Cincinnati, OH

Empty Foundset also on detail forms

Postby Bernd.N » Thu Oct 06, 2016 5:48 pm

That's interesting and should speed up things even more.

I think I will try emptyFoundset also on further detail forms.
An option would then be to just load one single record to a detail form, in order to not show a complete blank detail form on firstShow.
It could be the last record a user used on last login.
That record PK could be stored on logout in a tiny help table with userID and tableName and a composite index of both, should be fast.
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 544
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Next

Return to Sharing Central

Who is online

Users browsing this forum: No registered users and 0 guests