0

I am using PrimeFaces 5.0 (unable to upgrade due to other issues). I have a SelectOneMenu. I bound an onchange event to it, so that when user changes it, I can use confirm() to prompt user to confirm the action. When user clicks no, I need to put the old value back.

The menu looks like this:

<p:selectOneMenu 
    id="referenceTable" 
    widgetVar="referenceTable"
    style="width:45%"
    value="#{maintRefTabUi.selectedReferenceTable}"
    onchange="changeReferenceTableDropdown();"
>
...snip...

The function looks like this:

function changeReferenceTableDropdown() {
    if (DirtyFlag.isDirty) { 
        if (confirm('You have unsaved changes. Do you want to discard your changes and switch to another reference table?')) { 
            DirtyFlag.resetDirtyFlag(); 
            changeReferenceTable(); 
        } else {
            // Pick one below

            // Attempt 1: The .value property is reverted, but displayed value isn't 
            document.forms['tableSelectForm'].reset();

            // Attempt 2: Same as attempt 1
            PF('referenceTable').value = PF('referenceTable').preShowValue.val();

            // Attempt 3: The dropdown box is reverted, but onchange got fired twice
            PF('referenceTable').selectValue(PF('referenceTable').preShowValue.val());

            // Attempt 4: .value and visually reverted, but if you click the dropdown box, the selected value jumps back to the discarded value
            PF('referenceTable').revert();

        }
    } else { 
        changeReferenceTable(); 
    }
}

I am unable to find anything regarding .selectValue() and onchange() event firing twice. Because JavaScript setting .value won't fire onchange(), .selectValue() firing onchange() might be a bug.

Is there a way to supress onchange()? I also tried onchange=null; and putting it back afterwards, but it didn't work (onchange still gets fired).

Or is there a way to make SelectOneMenu update its display according to .value?

KC Wong
  • 1,373
  • 1
  • 10
  • 23

2 Answers2

0

I ended up doing this:

In the setter associated with the SelectOneMenu, I saved the old value in another member variable.

In the onchange() event of the SelectOneMenu, if user cancelled then I call a new method in the bean to restore the old value, then update the SelectOneMenu.

More trips to server instead of blocking it on client-side, but at least it gets the job done.

KC Wong
  • 1,373
  • 1
  • 10
  • 23
0

why do you not use the Primefaces confirm dialog?

http://www.primefaces.org/showcase/ui/overlay/confirmDialog.xhtml

I could imagine, that your problem will be obsolete because you must not rely on javascript code.

I hope this helps!

  • I tried; using the confirm dialog have the same problem that the SelectOneMenu will be using the new value even if user cancelled. It's the onchange() event, so the change is already applied in the client-side SelectOneMenu. If only I could use a onclick event on the SelectOneMenu! – KC Wong Jul 22 '16 at 09:07
  • Might this help..? http://stackoverflow.com/questions/18787653/invoke-action-method-on-click-of-hselectonemenu – chaeschuechli Jul 22 '16 at 09:13
  • The linked article recommends using a valueChangedListener... so it's handed over to the bean already. I want to block it on client-side and if user cancelled, retain the old value in the dropdown box. – KC Wong Jul 22 '16 at 09:19