Showing posts with label Alternative Approach of Explaining Things.. Show all posts
Showing posts with label Alternative Approach of Explaining Things.. Show all posts

Tuesday, September 4, 2012

ADF Business Components Extend Base Classes. Be cautious, All BC extend them. ADF BC

Hello,

NOTE: in this post, we are going to follow another approach of explaining things...
We are going to follow the first thing that it might come in mind. Then we are going to think it over and see the simplicity of things. This is an experimental way of approaching a matter and covers the case where things are not that clear in our mind regarding the best approach to follow. Sometimes I find people accepting solutions "as is" without considering to challenge them. With this approach, we are going to rethink some approaches in order to determine which is the simplest and best. Make sure that you read until the end. We are all busy and we want the solution fast. But, trust me, there is more into it than just accepting the solution.

This is another quick hint regarding extending business components base classes.

--wooow.. what do you mean by: "extending business components base classes"???

Well, with JDeveloper 11g you can set which classes will be extended by your business components..

--wooow.. what do you mean by "you can set which classes will be extended by your business components"??? (well, actually, this sentence must show a kind of mocking tone.. but I find it difficult to write it and not describe it.. )


Hmm.. I see.... Every Business Component (Entity, View Object, Application Module etc...) is described by an xml file.

For instance, in this example, we are going to create an ADF BC application that uses HR tables. Those tables are going to be Employees and Departments.

--wooow... what do you mean by "Employees and Departments "??

(I wonder... dude... where is my car??)
(--Just kidding..----- Oo --->)

For those of you who need a refresher about how to generate Business Components from tables, here is a refresher.

After we have generated the BC (do not ask me how... hit the link above.. above, not below..)

-woooow........................ just kidding..

Anyway, we have the ability to write some custom logic for all our View Objects, the ones already generated and the ones to be generated in the not so distant future, only once.

(where is the wooow now ha?)

-keep calm and carry on.. (I think there is a debate about that phrase, or poster.. something about copyright or something.. by the way I do not own anything of that phrase.. I do not own anything.. )
--wooow...

Lets say that we want to place some logging when executeQueryForCollection method is called on every View Object in our application.

-- I know! I know! I know! pick me, pick me pick me!!

okay... ( what the furniture aka wtf is that??)

--You extend the View Object's Class and you place the Logger there.

hoooray!! what about the rest 912783416293847162394817234912846434'1\234!@#$4#!@# View Objects??


---woooow...... what do you mean by that big number with characters that reminded me of Asterix and Obelix???

I mean, that there is a possibility to have more than a reasonable amount of View Objects to extend..
--soo? What is the problem? Are you lazy? is that it?

Yes, I do not want to keep extending and extending and going and going  (like that battery advertisement), repeating the same work over and over again... I want to be DRY

---woooow.. when did you got WET ??

....  "I have to return some video tapes" (which movie was it and which actor! the hidden challenge! Brought to you by dstas! The winner will get his/her name right here in this zupa fly post as the first correct answer! *No cookies involved* )

Alright..  lets do it in a different way..
Lets go to the Departments View Object! shall we?

--okay...

Do you see an java classes there?

--No.. there arent any....
Are you sure..
--Yeeah.. unless they are hidden.. are they hidden??

Yes! they are! you cannot touch this! Evil spirits and a big purple bear will hide the sunshine that goes through your morning orange juice glass and hits your spoon with which you eat your korn flakes!! No sunshine for you!!! (just kidding.. )

--wooow.. So lets generated them with JDeveloper.. It is simple dude.. Just press the pencil button and then check the darn check box! then press OK!! How difficult is that!!!!?????? See the screens below please dude.. you are killing me... you are really killing me dude..

oh God.. (choose whatever accent you want, but apply the "There is no salvation" tone please)



--There you go dude! It is ready..now apply your logger wherever you want..
Okay.. I will..
Oh wait a second.. what about Employees View Object? what should I do? I want to have the exact same logger there.. any hints?

-- Dude.. why are you blogging such dump staff?? Is not it obvious?? Just perform the same process. -----Good (oh no, I wanted to say Goood not good, it is a God with many oooo in order to emphasise the anger..)

Okay.. Lets pretend that I did that.. The great pretender.. Oh wait! I just got a message from the Boss via twitter (and received it more than 10 times since I am following, facebook, twitter, google+, LinkedIn and 10 other social or whatever else networks)  that  we have to create 300 View Objects more..

--Okay.. so?
....
Are you expecting me to generate all those java classes, are you?
--Dude, I know all hotkeys by heart (byHeart= ctrl+b+H)  in JDeveloper, I can work with out a mouse, I am a Ninja duper super masta gangsta waka mama loca Bosa Nova when it comes to using JDeveloper.. I can do it in a snap!

Okay.. I am not like that..
--Only the brave and the fittest and those with the Knowledge (The Horror, The Horror)  should handle such requests.

good God (spelled properly)..
Are You open to ideas?
--From you?? ahahaha... well, lets give it a try..

We could compete who is going to implement it faster, what do you say? You can throw all the ninja bomb smokes and asterisks you want.. what do you say?
--ahahahahahahah there is no way you can compete me on this!! Bring it on!

Here is my solution:

1) Create a new class that extends oracle.jbo.server.ViewObjectImpl;


-- 23 classes generated so far dude... I am on fire!!

2) Override the executeQueryForCollection method and place your logger (System.out for the simplicity here in this example)


--123 classes generated so far dude.... you are still in one class!! Not even a View Object.... I am even talking on the phone planning my next vacation dude!! That is what I call productivity with choice!!


3) go to your model project and right click-> properties. Expand "ADF Business Components Node" and select Base Classes. Then In the View Object value change the value from ViewObjectImpl to MyViewObjectImpl
--200 classes dude!!! What is that? What are you doing there?

Actually, I am done.
--What? yeah right..

Really, I am done.

--wooow... how did you do that? Just wait a minute... Is this applied to all View Objects???

The last screen shows which classes are going to be used by default by ADF when it comes to using the View Objects. By default oracle.jbo.server.ViewObjectImpl is going to be used for every View Object in our application.
--Aaaand how I am going to tell that a ViewObject extends my custom class properly???
It is very easy. Just go to your

All View Objects that do not have yet generated their java class, will use our new class.
In order to verify if this already done properly (There is a strange behaviour here see note below) Check the source of the xml file:


If there is no ComponentClass in the source file, the default ViewObjectImpl java class will be used.

========================================================================
NOTE: It seems that there is some "strange functionality in the versions tested 11.1.1.6.0 and 11.1.2.1.0" The change is not reflected until a View Object is edited. By edited I mean to check the Classes Extend of the view object.


You will see the custom class there, even though the ComponentClass tag is not generated in the xml source. By just doing this and the pressing ok the change will be reflected.
This a strange behaviour and it does not seem that right.
Another thing you can do is to manually set the ComponentClass tag to those View Objects that existed prior to extending the base classes.
========================================================================

All View Objects that already had their class generated, will not use it, unless we change the extension manually. All previous classes where extending the default one which was oracle.jbo.server.ViewObjectImpl.

All View Objects that will generate their class, will extend our custom class which is MyViewObjectImpl.java

--wooow.. that is smart... And what about my 200 classes? What should I do now?

Well since you generated them.. you will have to manually update the extends part to the custom ViewObjectImpl class that extends the oracle.jbo.server.ViewObjectImpl class

--woow... Thanks Dude.. That was really nice and fast!

Yeap. One thing to remember here is that a careful design is needed when it comes to extending base classes of BC.

One must always keep in mind that all BC (depending on what you extend of course) will use the Base class that you will define. So, for example, if you have a base class with abstract methods, all ViewObjects that have not generated their classes (and have properly set the ComponentClass tag in their source.), will throw an exception!!
You could see something like the following:

(oracle.jbo.JboException) JBO-29000: Unexpected exception caught: java.lang.InstantiationException, msg=null 

Cheers!


Saturday, April 28, 2012

Having a non BC Drop Down Select component with list items From BC Data Control. ADF 11g

Hi,

in this example we are going to  create an application where we will have a drop down list where it's value is going to be stored to a managed Bean.

The list Source is going to be from a Data Control that comes from Business Components.
Countries for example, from HR Schema.

The goal here is to demonstrate that is possible to have a list of Values component that belongs to "a" DataControl(in our case, we are using a ManagedBean) and uses a list of possible values from another DataControl(In our case, HR Schema, Countries View Object).

Download Sample Application.

NOTE: in this post, we are going to follow another approach of explaining things...
We are going to follow the first thing that it might come in mind. Then we are going to think it over and see the simplicity of things. This is an experimental way of approaching a matter and covers the case where things are not that clear in our mind regarding the best approach to follow. Sometimes I find people accepting solutions "as is" without considering to challenge them. With this approach, we are going to rethink some approaches in order to determine which is the simplest and best. Make sure that you read until the end. We are all busy and we want the solution fast. But, trust me, there is more into it than just accepting the solution.


The case scenario here is pretty simple:

One attribute,
Hold the value in a ManagedBean,
Get the List of Possible Values from a View Object.
We simply create the Business Components:


An Empty Page:

Then, we will have to create the Select One choice Component

From the component palette in JDeveloper, we locate the Select One Choice component and we drop it into the page we created previously.


When we drag and drop it into the page, JDeveloper will show a dialog that will require the following information:

The first screen, requests us to determine whether this Select One Choice will have a binded list or a static list.


And of course, the common properties, such as the value holder.



(Lets think out loud a bit here)
We are dropping a select one choice into a page..
Where is the value held?? uh.. in a managed bean.. (in the example at least..)
-really?? where is that??
-uh.. we have to create it??
-YES! But why did not we do it before dropping the component?
-uh... we did not think that we havent finished with the "model" part..
-Yes, we are used to the bindings and we thought that everything will be generated automatically... Here it is not the case.. Alright, lets create a java class..

-what about this wizard? The one of the Select One Choice?
-Cancel it..
-Are we forgetting something??
-no! it's cool.. We got this, it is the java class missing.. the bean..
-ok.. (dont hold your breath just yet...)


Great,
now?
-now... now, we will place the setter and the getter to the Select One Choice component...
-ok.. so? how are we going to do it?
-Simple, we will add #{javaClass.lovValue} in the value property of  the Select One Choice.
-Are not we  forgetting something?
-uh..... no..
-ok.. lets proceed then..
-oh wait a minute! we are working with JDeveloper! lets do it declaratively!!
-yes! lets go.

Lets drop the Select One Choice once more..
(The same  procedure again.. If only we had thought of this earlier.. We would have solved several wizards and clicks..... anyway)

So, after doing the same process again, we select the value and expression builder:


a closer look:




-where is it??
-where is what???
-The bean..
-what bean?
-the bean!! the managed bean!! the javaClass we created! where is the bean!!! (oh... JDeveloper and it's wizards.. Declarative development they say.... what do they know.... I will put the EL on my own and everybody is going to be happy..


-Good.
-Uh.. I think we forgot something here...
- No we did not..
-Are you sure??
-yes yes.. We got this..
-ok... (....)
-press finish..


-It kind of looks weird.. Does not it?
-What do you mean?
-The Value has errors.. It is strange... maybe it something from the IDE wrong.. (As usual... somebody else's fault)

-WELL, it is not actually strange.... (do you remember inversion of control??)
-oooh... we have to set up the managed Bean... I totally forgot  about that!
-it happens..
-well actually, I was confused because with JDeveloper wizards produces everything by default when making actionListeners and valueChangeListeners...

-well yes.. but we should not forget the basic principals.. dont you think?

OK after setting the managed Beans:



There is no more errors, plus, we are able to see the bean in the wizard.. (Wizards, do know in the end.. )



OK.. everything seems to be ok..
-Lets Run The Page!!!!!

-are we ok with everything??
-yes yes!!
-Maybe it would be better to do a small recap before deploying and running the application..
-Lets see,

  • Generate BC: done.
  • Create java Class: done.
  • Declare it as a Managed Bean: done.
  • Drop the SOC into the page: done.
  • Map the Selected Items: OMG!!! we totally forgot about that!!!!!!! OMG! OMG!
  • map the value property:done..
-Ok.. Ok.. what do we do now? Do we drag and drop the SOC again? Do we do it everything from the beginning??
-no.
-But it is easier..
-yes. But we have to learn how to fix things..


-.....

lets open the page with and see the source code of the SOC (in the page select source tab):





What do we see here?
-We see that the select items is empty.. This is quite correct since, we, forgot to finish the JDeveloper wizard with all the needed values properly.
So, we have to do it manually now..

We have to know how to do it manually as well, simply because we have to. Wizards are good, but we really need to know what actually happens.

Ok. here is what we have to do:

  • Create a page Definition
  • Add a list in the page Definition
  • update the code of the SOC in the jspx


ok, the page Definition creation is very easy"
right click on the page and then  select Go To page Definition.. JDeveloper will tell you that there is no page Definition and will ask whether to create it or not. Create it of course. After that, we have an empty page Definition:




 Then, we have to add the list:

 Select the last option. All other options do not suit us, simply because, we do not navigate, we do not have any other Base Data Source to update:



After pressing ok, we have to declare the iterator that will fetch the list of values for this SOC:


 Then , we have to select a Display Attribute.
 The value of this attribute will be shown in the SOC. This is the value the user will see.


Press ok and we are done with the creation of the list. the pageDefintion code is now updated with the following:


Ok.
All we have to do now is to update the SOC with this list.
We locate the jspx and we view the source code. We locate the SOC and we change the value property of the f:selectItems components to:



For those of you rushing to say that there is no items property in the SOC. Look closer. 
The select items is a separate component. Further more, here is a screen with the declarative way:




Finally, we are done:


Download Sample Application.

Regards.

Sunday, March 18, 2012

af:serverListener and af:clientListener usage. Prevent User input to an input text component while an operation of another component is in progress. No glasspane, no splash screens. ADF 11g

Hi,

In this example we are going to create a small application that will demonstrate the following scenario:

We are going to have a radio Group and an InputText.


We are going to prevent the user from entering any value to inputText while the operation from the radioGroup is ongoing.

Download Sample Application.

In order to keep things simple and demonstrate the usage regardless the services behind, we are not going to have any  Business Components in this example.

Requirement:
We want to prevent users from editing the input text field while the operation of the radioGroup is ongoing.


Basically is not only that. We want to show to the user that there is an operation going on. But we do not want to show any popup ups or grey out the whole screen.

why?
Simply because our operation might take less time than the time needed to show a popup in our screen.
For example, it might take 1 to 1,5 seconds. So, if we were to use a popup, The second it would be shown, it will have to hide itself again..

Not very convenient is it? I know..

So for that reason, we are going to think it over a bit..


NOTE: in this post, we are going to follow another approach of explaining things...
We are going to follow the first thing that it might come in mind. Then we are going to think it over and see the simplicity of things. This is an experimental way of approaching a matter and covers the case where things are not that clear in our mind regarding the best approach to follow. Sometimes I find people accepting solutions "as is" without considering to challenge them. With this approach, we are going to rethink some approaches in order to determine which is the simplest and best. Make sure that you read until the end. We are all busy and we want the solution fast. But, trust me, there is more into it than just accepting the solution.


What can we do out of the box:


Well, we can have a af:clientListener to the radioGroup, in order to invoke  evt.preventUserInput(); through a javascript method.










Ok, so far, our main issue is resolved.. the user is not able to change any data to our inputText component..

But the user, is not a software engineer (at least in this fictional scenario..) and thus, she/he is not able to understand the phrase:


"you are not able to insert any data or change for that second, because you have changed the radioGroup choice  and this might take a few seconds to finish the operation. For that reason we block you from making any changes. Furthermore, if you had made any changes, those changes, will be lost because we are refreshing the input Text for several reason that are not so important to you right now."

"oh.. ok.. "

(she/he is going to forget it if she/he will not work on it for a month.. Then we will have the same discussion again.)

In order to avoid this rather unpleasant discussion, we have to make some indication in the application that there is an operation going on and the user is not able to make any changes..

I know!! we have the status indicator! It is easy to implement, fast to implement, it does not get any better than this!! This is the one! It is out of the box! a simple drag and drop! and viola!!

Well, this is a good thought!... But how are we going to apply this?

We will drag and drop it next to the input text.. Is it so difficult to understand that? It is easy, I can show you if you have difficulties in understanding the meaning of drag and drop...

Yeah sure.. lets arrange a meeting for that.. :)

What I am trying to say here is, that status indicator is good but does not indicate that the user is not able to make any changes to the components.

That is why a lot of implementations are applying the popup behavior, it is an indication that there is a process going on and the user is not able to make any changes to the application data nor able to press any other buttons.

I see, but if we are going to make the users understand that they cannot touch this ( have a break hit the link.. there are a lot of things going on in your head every day... I have 2 gold fish in an aquarium.. they do not remember anything for more than a second.. you cant blame them.. how many things can go through their heads..! :)   hammer time! watch the video.. )




Ok, so, what should we do?

.... (thinking)...
....(thinking)...
....(taking a zip of morning's coffee and rethinking)...
...( I need to throw away that coffee)...
...(thinking)...

I know!!
We will disable the input component!! (Do not hold your breath just yet... we are still thinking here)

Yee! Now we are talking.. Lets have a new cup of coffee.. and start developing..

WAIT!

 take a light coffee.. it is getting late..

Yes. We shall prevail!!

Disable the component. ok.  I still have some questions though..


  • How are we going to disable it?
  • When are going to disable it?
  • For How long are we going to disable it??
  • Is there is a way to re-enable it??
One thing at a time..

How are we going to disable it?

Can we do it in the javascript function? something like component.setDisabled(true) or something??
Well, no.
Why not?
Well, those properties are secured and are specially treated. Please see the relevant post of Frank Nimphius here

In short (please read the article above), we cannot just disable our input component, unless we will unsecure it. We do not want to unsecure it. We will try to find another way. Remember, we just want to make sure that the user understands that she/he cannot change anything while the process is ongoing.

oh.. I see. So, what can we do?  Cant we just cancel the event and proceed with the disabling the component. Yes we could. But this would also cancel the new value setting.

What we want is to, disable the input text, proceed with everything the radioGroup has to do and when this everying is done.. we want to enable back the input text.


OK, we could do the following: We could cancel the event, invoke the serverListener and do the setting there! Then we will enable it! All in one method!! (Do not just jump around now... We are still thinking here...).  So basically, we are going to do all in one method right? Right! But how are going to do that? We want to refresh the UI somewhere in between....

Oh.. Actually yes.. we want to:


  • Disable
  • process the process
  • Enable
Hmm... If we are going to do everything in one java method, how are we going to have this interaction with the UI?

Maybe we could invoke some javascript from the java method and then maybe we could invoke something else there.... (think of the maintenance here...)


It is already complicated as it is..  Dont you think?

Perhaps it is time to start rethinking here..



Rethinking

Let us see what we have here: We need to understand what to do and when.

First of all, we have realized that disabling the input text is not that easy as our initial thought... Especially with our case where we want to jump around, disable, process, enable and generally do funky stuff in our UI..

So perhaps we could take things slow..

Lets see our approach:

We are going to use an af:clientListener with a valueChange type in our RadioGroup. We are going to do this because we want to use a javascript method and "do something with the inputText". This javascript method is additionally going to prevent the user from any input as long as the operation in in progress. Then, we are going to use an af:serverListener and we are going to "undo that something that we did to the inputText" The  serverListener is going to be invoked via the  AdfCustomEvent.queue method. This method is going to be called from the clientListener java function.

Regarding the "do something with the inputText" We could start as a first implementation to hide it and after the process to make it visible.


Lets see what we can do with the component:
  • We can find it by id
  • We could hide it immediately.  Simply by calling component.setVisible(true) in our javascirpt method.
  • We could call a java method in our bean in order to show it again. Why should we make this last part? Simply because we will have to wait for the whole process to finish and go again into the Render_Response phase where the component will be refreshed through the partial trigger and it will be visible again. For those that are going to argue 

Simple is not it?

Lets see the amount of code we are going to write for this first implementation:

JavaScript:



Is not much right?

page Code:



As you will see the code is fair simple.


Java Code:


This is just the server Listener method.

At this point.. we are ready for our initial thought.

If you run this first implementation you will see that the input component is hidden while the process is there and becomes visible when it is done.

Why is this happening just like that?

Well, the clientListener is hiding the inputText. This is javascript and happens immediately.
Then, the clientListener is calling the serverListener method which in turn changes the visible property of the inputText.
This change is "visible" to the user after the refresh part that happens with the partial trigger.
It does not actually matters if the AdfCustomEvent  takes place first or last. After all, is a visibility change.

Yeah that is great! But what about the Disable part? We still want to disable the component as long as the operation lasts.

Well, given the fact that we cannot set the property from the javascript method, it adds up a complexity by itself. Furthermore, to unsecure the component is not a recommended approach. Thus, we will have to find other ways of making sure the user understands that the component is blocked for a time being.

Visibility is something that can work very well and with the minimum effort of development.
Now, if you want you can still "play" with this property and show/hide additional components.

For example, we could hide the inputText and show another component, lets say an output text that would have a small message. In the serverListener method we then just switch back the visibility properties.


To me, the visibility property is something that can be used in many ways and is rather easy to be applied.

Download Sample Application.

Regards.

References:
http://www.oracle.com/technetwork/developer-tools/jdev/1-2011-javascript-302460.pdf
https://blogs.oracle.com/jdevotnharvest/entry/using_af_serverlistener_as_a
http://docs.oracle.com/cd/E15523_01/apirefs.1111/e12046/oracle/adf/view/js/component/AdfUIComponent.html
http://docs.oracle.com/cd/E17904_01/apirefs.1111/e12419/tagdoc/af_serverListener.html
http://docs.oracle.com/cd/E12839_01/apirefs.1111/e12046/oracle/adf/view/js/component/rich/input/AdfRichInputText.html#getReadOnly__


Tuesday, March 6, 2012

Group Detail VO records as SelectOneRadios and the power of LOV (List of Values) and View Criteria. ADF 11g

Hi,

This is an example demonstrating the usage of selectOneRadio component.

Download Sample Application.

User Requirement:

We want to be able to change the manager of a department  by selecting one of the already existing Employees in a form of radio Buttons. This will enable us the functionality to always see every information we want and select accordingly.


Model: We are going to use the HR schema.
We are going to generate the following tables

  • Department
  • Employees


Thoughts:
How are we going to create the radio buttons?? All we have is a master detail relationship between Departments and Employees.


Our BC generation with the help of  the JDev wizard. As you will see below, all unneeded stuff for this case are removed.



Basically we want to change the managerId of the Departments table.. (how about an LOv?)


NOTE: in this post, we are going to follow another approach of explaining things...
We are going to follow the first thing that it might come in mind. Then we are going to think it over and see the simplicity of things. This is an experimental way of approaching a matter and covers the case where things are not that clear in our mind regarding the best approach to follow. Sometimes I find people accepting solutions "as is" without considering to challenge them. With this approach, we are going to rethink some approaches in order to determine which is the simplest and best

I know! We can use the selectOneRadio UI Component!  (Do not hold your breath just yet... we are still thinking here!  :F  )
Each Employee will be represented as a selectOneRadio! (How about an LOV?)
Great.
This means that we are going to create our af:table with our Departments:



select Single Row::



Then, create another column inside that table:



OK, we now have our own departments table. All we have to do is to drop the Employees in the new Column:



From the attributes wizard we can expand the  choice list and select multiple items:




By now, according to plan (Still, do not hold your breath just yet... we are just following one thought.. Unfortunately these thoughts are the ones that come in mind first...... so lets see where this leads us...)


And how are we going to actually set the new value of the selected Employee as a the new managerId?

UUh.. we are going to override the setter of... uuh.. I do know just yet.. I have to thing about it.
OK..
Lets see the out of the box behavior of our application.. Lets just run the application.

The that we developed here is the following:

As you will see, we have the same employees for every Department!!!

After we change the row of the Departments, all of the sudden, we new Employees!!!



Obviously, this is not that good.....

Why is this happening? It should not be happening.... should not it?
Well, it should and it does so..

The detail here (Employees) is refreshed after the change of the current row of the Master (Departments). That is why we see the radiogroup change after we select a new row.

We make the new row current. The framework queries (or gets the appropriate collection) the detail.
This is the out of the box functionality.

Can we make it work?  Yes, we have to make several changes in order to make this working..

But is it not already  complicated as it is?????

Are we really considering in continuing towards this approach? This approach already produced many issues to think of . Not to mention that we have not yet figured out how are we going to update the managerId of the Department..

At this point, we have a very clear indication that the above approach is not the appropriate one.




Re-thinking:


Ok. lets start over..
What do we exactly want?
We want to be able to "appoint" an employee as a manager for a specific Department.
We want to do that, by selecting the appropariate Radio Button.
Furthermore, as the user or someone else would say:

" I would like to be able to see a table with all the departments and inside each Department, I would like to see a list of all employees and be able to see which of them is the manager and be able to choose and change the Manager"

Ok... I know, it might not be that detailed in many cases.... but lets follow it..

As we saw earlier, the first approach, the one that came to mind was not that easy to implement. for that reason we dropped it and we will Re-think everything in order to find a better solution.

How about LOVs???

We could create an LOV in the managerId attribute of the DepartmentsView...
This LOV will represent only the Employees of the specific Department.

What do we gain by this??

  • The Framework handles the setting and the getting of the managerId.
  • we ensure that the appropriate employees will be shown in the list of employees.
  • We ensure that all employees will be grouped together and will be treated as a group. This means that only one will be always selected.

How are going to do the following?

  • How are we going to create the LOV?
That is easy. We will locate the managerId Attribute in the DepartmentView and then we will create the LOV. Just follow the screens below:

locate the attribute:


Add the new accessor:




Select the corresponding Attribute:




go the UI Hints tab and select the type of the LOV to Radio Group



Then select the attributes you want to be visible  in each row of the List Of Values:



 Click ok.

We have now created our List Of Values and set its type to Radio Group. I was not that easy was not it?


Next Question:


  •  How are we going to filter the Data to the corresponding Department?

this is quite Simple, we will create a view Criteria to EmployeesView. Just follow the screens below:

Locate the EmployeesVie



in the Create View Criteria Wizard, add an Item:




locate the managerId and select it. Then select Bind Variable and press the green sign.
In the new window, change the name of the bind Variable and change also the type to Number. Since we are creating a Bind Variable to bind an Attribute it must have the same type. Click ok in both dialogs.




and there you go. the View Criteria is created:


 Next Question:


  • How are we going to set the appropriate DepartmentId value for every department??
That is even more easy.. All we have to do is to "enable" the View Criteria we have created. 
After the creation of the LOV in the DepartmentsView, a ViewAccessor was created in that DepartmentsView:





If you select the accessor and click on the pencil button you will see that we can have access to the View Criteria!




In order to always apply the View Criteria we have created. we will have to shuttle it on the right. with this way the View Criteria will be on the Selected side. Below you see that we also have access to the Bind Variables of that View Criteria. The value column is empty. In Order to set the proper value, we have to provide the name of the Department Id attribute of the DepartmentView, which is "DepartmentId". We verify this by checking the Attributes of the DepartmentsView.






Next Question:

  • How are we going to represent this properly.
That is even more easy!! We will simply drag and drop the DepartmentsView onto the page and select af:table.

As you can see below, while drag and drop as shown in our previous thought the managerId is already set as a Select OneGroup:



After fixing a bit the layout. Once we run the page we will see the following:







One Last Question:

  • Do we need the hierarchy represented in the Application Module?
Nope.. we dont. all we need is the DepartmentsView shuttled in the Application Module. Since we will be using the LOV, we do not need to have additional View Objects in our Application Module. So, we can remove the EmployeesView from our Application Module and keep only the DepartmentsView.



NOTE: This is a purely illustrative example of the benefits of using List Of Values. This is not a  real example and for that reason it might not fit your needs in terms of data.


Download Sample Application.


Regards.

LinkWithin

Related Posts Plugin for WordPress, Blogger...