Date: Fri, 29 Mar 2024 08:18:23 +0000 (UTC) Message-ID: <1457020002.10975.1711700303583@911f0a1bad02> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_10974_81787047.1711700303583" ------=_Part_10974_81787047.1711700303583 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
This directive helps provide dynamic tab sequences on the client= . All it needs is a set of so called 'design' values on DOM nodes inside yo= ur document (<input ... sablo-tabseq=3D"2" ...) and an optional config a= ttribute (<div ... sablo-tabseq-config:{container: true} ...).
Based on only these two things that you can add to a new custom componen= t as needed, the sablo-tabseq directive will generate and dynamically manag= e the "tabIndex" attributes for all the DOM elements displayed in the brows= er that use this directive.
IMPORTANT
One must always have in the DOM structure a top-most sablo-tabseq elemen= t marked with
<someTag ..= . sablo-tabseq=3D"1" sablo-tabseq-config=3D"{root: true}"/>=20
. This can be for example the <body> tag.
IMPORTANT
sablo-tabseq requires you to include a full jQuery lib in your page, bef= ore angular.js. It will not work with angular shipped jQLite only (because = it relies on jquery trigger() which is not available in jQLite). Servoy alr= eady does this, so this note is only relevant for sablo users.
For example:
<!DOCTYPE h= tml> <html ng-app=3D"myApp" sablo-tabseq=3D"1" sablo-tabseq-config=3D"{root: = true}"> <head> <title>Tabseq</title> <link href=3D"css/style.css" rel=3D"stylesheet" /> <script src=3D"../lib/jquery-1.11.1.js"></script> <script src=3D"../lib/angular-1.3.0-beta.2/angular.js"></scrip= t> <script src=3D"controllers/impl.js"></script> </head> <body ng-controller=3D"myController"> <mycustomcomponent sablo-tabseq=3D"model1.tabSeq"></mycust= omcomponent> <div sablo-tabseq=3D"20" sablo-tabseq-config=3D"{container: true= , reservedGap: 50}"> <input sablo-tabseq=3D"1" value=3D"a"/> <input sablo-tabseq=3D"-2" value=3D"b"/> <input sablo-tabseq=3D"1" value=3D"c"/> </div> <mycustomcomponent sablo-tabseq=3D"model2.tabSeq"></mycust= omcomponent> </body> </html>=20
Here we have two custom web components 'mycustomcomponent' (could be any= thing, for example you could replace them with inputs as well) and 3 inputs= that are meant to have a specific tab traversal sequence.
Let's assume that
model1.tabSeq = =3D=3D=3D 30 model1.tabSeq =3D=3D=3D 10=20
In this case this case the wanted tab sequence is: [last custom componen= t, input field 'a', input field 'c', first custom component]. And indeed wh= en you would run this example, the tabIndex attribute will automatically ge= t set like this (ignoring the fact that mycustomcomponent would probably be= expanded by angular depending on what that web component does):
<my= customcomponent sablo-tabseq=3D"model1.tabSeq" tabIndex=3D'53'></mycu= stomcomponent> <div sablo-tabseq=3D"20" sablo-tabseq-config=3D"{container: true= , reservedGap: 50}"> <input sablo-tabseq=3D"1" value=3D"a" tabIndex=3D'2'/> <input sablo-tabseq=3D"-2" value=3D"b" tabIndex=3D'-1'/> <input sablo-tabseq=3D"1" value=3D"c" tabIndex=3D'2'/> </div> <mycustomcomponent sablo-tabseq=3D"model2.tabSeq" tabIndex=3D'1'= ></mycustomcomponent>=20
Notice that I intentionally used 10, 20, 30 as 'design' tab indexes for = the 2 custom components and the parent div of the inputs. This is just to s= how that only their order matters, as at runtime the real tabIndex that is = generated by sablo-tabseq directive and used by the browser will start from= 1 and increase accordingly.
Also notice that "-2" is a special 'design' value that = means 'this tag should be skipped completely by tab sequence'. It will alwa= ys generate a "tabIndex=3D'-1'" for that DOM element and for any child DOM = elements that it might have using sablo-tabseq directive.
"0" is a special 'design' value as well and it means 't= his tag should use default tab sequence'. It will remove "tabIndex" attribu= tes for that DOM element and for any child DOM elements that it might have = using sablo-tabseq directive.
Duplicate 'design' tab indexes on the same level are permitted and will = generate duplicate tabIndex attribute values (it lets the browser decide wh= ich one gets focus first).
Another thing to notice is the div's configuration as tab sequence conta= iner (sablo-tabseq-config=3D"{container: true, reservedGap= : 50}). This means that child DOM elements of that div are considered to be= traversed by tab sequence at the 'design' tab index value of that div/cont= ainer. So at runtime all child DOM elements of that div will get a tabIndex= value that sets them between the parent div's siblings, according to the '= design' tab index value of the parent and it's siblings. Also notice the ch= ild 'design' values are not related to the ones on the container level. The= y only logically make sense as compared to the ones on the same level - in = this case the 'input' siblings.
About 'reservedGap': it is an optional configuration op= tion; it will work without it as well. It tells sablo-tabseq that it should= 'reserve' a number of tabIndexes for that container on top of the ones it = currently needs. That can help later on, if more elements are added to that= container and it needs more tabIndexes assigned - it can just use them wit= hout recalculating the tabIndexes of the parents (so less calculations to b= e done in the browser) - at least for a while, until it runs out of reserve= d indexes.
For example let's say (that div is actually an angular expanded smarter = custom web component) that at runtime decides to add 10 more input children= in the div. Only the tabIndex values inside the div will be updated as nee= ded, because of the reservedGap:
<my= customcomponent sablo-tabseq=3D"model1.tabSeq" tabIndex=3D'53'></mycu= stomcomponent> <div sablo-tabseq=3D"20" sablo-tabseq-config=3D"{container: true= , reservedGap: 50}"> <input sablo-tabseq=3D"1" value=3D"a" tabIndex=3D'3'/> <input sablo-tabseq=3D"-2" value=3D"b" tabIndex=3D'-1'/> <input sablo-tabseq=3D"1" value=3D"c" tabIndex=3D'3'/> <input sablo-tabseq=3D"0" value=3D"new1" tabIndex=3D'2'/> <input sablo-tabseq=3D"2" value=3D"new2" tabIndex=3D'4'/> <input sablo-tabseq=3D"3" value=3D"new3" tabIndex=3D'5'/> (...) <input sablo-tabseq=3D"10" value=3D"new10" tabIndex=3D'12'/&= gt; </div> <mycustomcomponent sablo-tabseq=3D"model2.tabSeq" tabIndex=3D'1'= ></mycustomcomponent>=20
But then, if you add 80 more inputs (a real life example could be a tabl= e having all sorts of components that can grow depending on data model cont= ent) then one sibling of the parent div will be updated as well, as the ini= tial reservedGap is not enough:
<my= customcomponent sablo-tabseq=3D"model1.tabSeq" tabIndex=3D'143'></myc= ustomcomponent> <div sablo-tabseq=3D"20" sablo-tabseq-config=3D"{container: true= , reservedGap: 50}"> <input sablo-tabseq=3D"1" value=3D"a" tabIndex=3D'3'/> <input sablo-tabseq=3D"-2" value=3D"b" tabIndex=3D'-1'/> <input sablo-tabseq=3D"1" value=3D"c" tabIndex=3D'3'/> <input sablo-tabseq=3D"0" value=3D"new1" tabIndex=3D'2'/> <input sablo-tabseq=3D"2" value=3D"new2" tabIndex=3D'4'/> <input sablo-tabseq=3D"3" value=3D"new3" tabIndex=3D'5'/> (...) <input sablo-tabseq=3D"90" value=3D"new90" tabIndex=3D'92'/&= gt; </div> <mycustomcomponent sablo-tabseq=3D"model2.tabSeq" tabIndex=3D'1'= ></mycustomcomponent>=20