Show custom pop up warning message when user changes any value (text box/LOV) on page - oracle-adf

I have requirement to show custom pop up warning message when user changes any value (text box/LOV) on page and close tab/cancel button by mistake.
Option I tried are:
a) Within application we are using a complex task flow/RegionModel for 7 different scenario's. Also requirement is to display custom message - Hence could not use approach "unsaveddatawarning"
http://www.oracle.com/technetwork/developer-tools/adf/unsaveddatawarning-100139.html
b) Second option I tried was to have custom region controller:
CustomRegionController implements RegionController
Inside validateRegion(RegionContext regionContext) thought to find if page data is dirty
AdfFacesContext.getCurrentInstance().getDirtyPageHandler().isDataDirty();
or
DCBindingContainer dcBindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
DCDataControl cDataControl = dcBindings.getDataControl();
boolean dirtyFlag = cDataControl.isTransactionModified();
In both scenario it always gives true (seems due to common set of VO/View Link application module always gets dirty when data is being rendered on page load).
Last option I am left with is to invoke valueChangeListener for each element (textbaox, LOV, Check box). I do not like this option at all. Please suggest if there can be better way to handle this scenario.

Why is using a value change listener a problem? Have each input component call the same VCL method in the backing bean. If necessary you can get the component id from the vcl event object.

Related

adf declarative component custom methods queueEvent() not working

I am using Oracle ADF JDev 12.1.3
I have a custom declarative LOV component and one custom method "valueChangeEvent",
after user select some values from the popup, i will do some validations, if all validations are ok, then I need to raise "valueChangeEvent" event,
so that in the final jspx page additional logic's can be implemented,
My declarative component method definition as follows
<method-attribute>
<attribute-name>
valueChangeListener
</attribute-name>
<method-signature>
java.lang.Void method(javax.faces.event.ValueChangeEvent)
</method-signature>
<required>
false
</required>
</method-attribute>
In my custom LOV Component, i have one input text and button, I tried the following to invoke my custom method within the command button action, but it does not invoke the event at the main form, but no error shows
// get the component reference using Face Context ValueExpression
_this = getThisDeclarativeCompoent();
//try to queue the valueChangeEvent - but this does not work
_this.queueEvent(new ValueChangeEvent(_this, NewValue, OldValue));
Consuming application code is as follows
<af:declarativeComponent viewId="/ASGLOVBrowser.jspx" id="dc3" label="Modules" LOV_Name="MODULE"
bindingAttribute="#{bindings.ModuleId}" showDescription="true"
multiSelect="false" matchingField="CODE"
valueChangeListener="#{viewScope.DeclarativeTestBean.test_valueChangeEvent}"/>
appreciate if someone can help...
Value Change event is raised by the framework only, when input value changes, therefore you can't initiate the event without the value being changed either from UI or programatically.
So, you can get a reference of the input text UIComponent and change the value programatically:
RichInputText uiComp = <<<get reference>>>;
uiComp.setValue(newValue);

jQuery 1.7.2 and IE7 on() doesn't seem to fire for selects

I have a table of rows where are dynamically added, but for some reason the on() event doesn't seem to fire when I change the value of a select.
For simplicity, I wrote the following jsFiddle. This is a VERY simplistic example of what I am doing. I do have to note that I was unable to verify if the jsFiddle failed the same way in IE7 because jsFiddle does not seem to work in IE7 at all.
The basics of my code are this...
First, the page loads with 1 or more of these rows, which represent a complex "subform" to be posted to Spring MVC. The subform has a group of 5 SELECT tags that have an event handler attached at the top TABLE as such:
$('#parentTable').on('change', 'div.additional div[class^="additional"] select', function() {
// ...enable/disable siblings according to value
}
At the bottom of the table is an Add button. When the user clicks it, I take the last visible row, clone it, use regex to fix the index on the name/id, and set all the fields blank and disables except one field, which is used to do a lookup. This all has the appearance of working.
The user enters a value in the lookup field, clicks Lookup, which performs an AJAX call, filling in the subform then calling the change on the selects to set their default state like so:
$subTable.find(':input:not(:button)').change();
This fires the above on() as expected. However, if I physically click on the resulting SELECTs and change their values the on() event handler is not called.
I have verified that the resulting cloned table row looks/smells/feels correct, at least from using IE8's Developer Tools (I have IE8 in IE7 compatibility mode for testing, because IE7 has VERY limited testing and the problem seems to be present there too). When I run this in Chrome it works perfectly fine, however I am aware the clone is technically working differently.
Any help would be appreciated.
Update
I tried swapping the selector to drop the class attr as suggested below:
$('#parentTable').on('change', 'div.additional div select', function() {
// ...enable/disable siblings according to value
}
And I tried all caps like the referenced post:
$('#parentTable').on('change', 'div.additional div[class^="ADDITIONAL"] select', function() {
// ...enable/disable siblings according to value
}
The first worked the same way, the second did nothing at all (disabled all on() change handling).
Will continue to play with this until I get it working. There has to be something simple going wrong here.
Update 2
I tried adding a class to all the `SELECT`s, and added the following two:
$('select.addedClass').on('change', function() {
alert("Select change:" + $(this).val());
});
$('#parentTable').on('change', 'select.addedClass', function() {
alert("Select change 2:" + $(this).val());
});
Here is the process I performed:
Reloaded page, both alerts fire for the single row there
Added a row
Performed AJAX lookup, which calls $addedTable.find(':input:not(:button)').change(); as described above, both events fire
Change the value of one of the selects, neither alert fires.
I would expect the first to fail, since the event listener is connected directly to the SELECT and not a higher level parent, but the second one fails the same way. So, in the Developer Tools, I tried to run the following:
$('#order.itemList1.additionalLine1').change()
Which is the ID of one of the selects I added, and still nothing fired. It's as if the event handler is ignoring all added SELECTs.
To make sure the select was working on the on(), I did this in the console after I added the new row:
$('#parentTable').find('div.additional div[class^="additional"] select').each(function() {
alert($(this).attr('name') + '(' + $(this).prop('id') + ')' + ' : ' + $(this).val());
});
Update 3
I ended up putting in a horrible hack that, for IE7 only, drops and re-adds the change handler directly on the SELECTs. It's ugly, but I have to support IE7, so...
I am leaving this open to see if anyone has a better solution, or might know why it's not working.
The problem isn't the change event, or the delegation on select elements.
It's the attribute selector:
div[class^="additional"]
IE7 and below don't do attribute selectors.
I've done a bit of searching and a few people seem to think this can be solved using case-specific syntax.

Extjs mask() with message

I am able to mask() then unmask() a chart before and after it's rendered with : chart.mask() then chart.unmask().
But I want to add a loading message while it's masked, how can I do it? I'm using Extjs 4.1 with MVC.
Ext.Component (from which chart inherits) and Ext.dom.Element both have a mask method. But Ext.dom.Element's one accepts a msg argument.
That means you can achieve what you want with this kind of code:
chart.el.mask('My message');
Now there are a couple more things to take into account.
The most important is to ensure that the element is defined before calling its mask method. In effect, due to possible load delays or render deferrings, it might happen that some events or methods are called on components that have been destroyed or not yet rendered.
The second thing is that with this method, you won't have the loading CSS class by default. You can pass it as the second argument to mask if you want it; the class is 'x-mask-loading'.
With all that, the code should rather look like this:
var maskEl = chart.getMaskTarget() // this one's marked as private... maybe we shouldn't use it
|| chart.getEl();
if (maskEl) {
maskEl.mask("Loading...", Ext.baseCSSPrefix + 'mask-loading');
}
Unmask similarly. The check that the element still exists will be even more important there, because the chance that the component has been destroyed (e.g. window or tab closed) before the load is done is even greater.

Webshims - Show invalid form fields on initial load

(Follow on questions from Placeholder Hidden)
I'd like my form to validate existing data when it is loaded. I can't seem to get that to happen
I jQuery.each of my controls and call focus() and blur(), is there a better way than this? I tried to call ctrl.checkValidity(), but it wasn't always defined yet. When it was, it still didn't mark the controls.
I seem to have a timing issue too, while the focus and blur() fire, the UI does not update. It's as if the Webshims are not fully loaded yet, even though this fires in the $.webshims.ready event.
I also tried to call $('#form').submit(), but this doesn't fire the events as I expected. The only way I could make that happen was to include an input type='submit'. How can I pragmatically case a form validation like clicking a submit button would?
Here's a jsFiddle that demonstrates the problem. When the form loads, I want the invalid email to be marked as such. If you click the add button it will be marked then, but not when initially loaded. Why?
Focus and blur in the control will cause it to be marked.
BUT, clicking ADD will too (which runs the same method that ran when it was loaded). Why does it work the 2nd time, but not when initially loaded?
updateValidation : function () {
this.$el.find('[placeholder]').each(function (index, ctrl) {
var $ctrl = $(ctrl);
if( $ctrl.val() !== "" && (ctrl.checkValidity && !ctrl.checkValidity()) ) {
// alert('Do validity check!');
$ctrl.focus();
$ctrl.blur();
}
});
}
I see this in FF 17.0.5. The problem is worse in IE9, sometimes taking 2 or 3 clicks of ADD before the fields show in error. However, I get errors on some of the js files I've liked 'due to mime type mismatch'.
This has to do with the fact, that you are trying to reuse the .user-error class, which is a "shim" for the CSS4 :user-error and shouldn't be triggered from script. The user-error scripts are loaded after onload or as soon as a user seems to interact with an invalid from.
From my point of view, you shouldn't use user-error and instead create your own class. You can simply check for validity using the ':invalid' selector:
$(this)[ $(this).is(':invalid') ? 'addClass' : 'removeClass']('invalid-value');
Simply write a function with similar code and bind them to events like change, input and so on and call it on start.
In case you still want to use user-error, you could do the following, but I would not recommend:
$.webshims.polyfill('forms');
//force webshims to load form-validation module as soon as possible
$.webshims.loader.loadList(['form-validation']);
//wait until form-validation is loaded
$.webshims.ready('DOM form-validation', function(){
$('input:invalid')
.filter(function(){
return !!$(this).val();
})
.trigger('refreshvalidityui')
;
});

icefaces htmlselectbooleancheckbox uncheck not working

I am using icefaces 1.8.2 and i have a HtmlBooleanCheckbox on my page that I need to uncheck when certain circumstances are met.
the checkbox on the page is like this
<ice:selectBooleanCheckbox id="accepttermscheckbox"
binding="#{managedBean.termsAgreement}"
validator="#{managedBean.validateAgreement}">
</ice:selectBooleanCheckbox>
and the binded object is a property of the managed bean with proper getter and setter
private HtmlSelectBooleanCheckbox termsAgreement;
i can check the checkbox in code, validator works fine and all the stuff i do with it are ok too but I just cant find a way to uncheck it on the server side.
I tried:
termsAgreement.setValue(Boolean.FALSE)
termsAgreement.setValue(null)
termsAgreement.setSelected(false)
but nothing works. Even if I debug it it shows value = null but when the page renders it still appears checked.
Once I check it I just cant get it unchecked unless I click it manually on the page.
funny thing is that
termsAgreement.setValue(Boolean.TRUE)
works fine.
Anyone any tips how I can uncheck it server side on the binded object?
Thank you in advance for help.
You are facing a common issue faced by ICEfaces/JSF developers.
First of all, you need to understand how JSF lifecycle works.
Following is a good article to read.
http://www.ibm.com/developerworks/library/j-jsf2/
For your case, bind a value to <ice:selectBooleanCheckbox>.
For example value="#{managedBean.termsAgreed}".
<ice:selectBooleanCheckbox id="accepttermscheckbox"
binding="#{managedBean.termsAgreement}"
validator="#{managedBean.validateAgreement}"
value="#{managedBean.termsAgreed}">
</ice:selectBooleanCheckbox>
Do not try to change the value from the component. Always change value from the value binding. In this example, you must change the value termsAgreed.
If your action/actionListener is not immediate, i.e `immediate="false", which is the default value, then changing the value in server-side will check/uncheck checkbox component.
If you are using immediate="true", then you must call resetValue() method in your component, HtmlSelectBooleanCheckbox:
termsAgreement.resetValue();
Ideally, you shouldn't call setValue() methods in components. You will understand it when you understand the JSF lifecycle.
Hope this will help!

Resources