0

In my application, I have some dialogs with dataTables that user can edit values, so I'm using primefaces rowEditor... Sometimes I have required fields in dataTable as you can see in this screen:

dataTable with required fields

In this screen, the user isn't required to fill all rows, so, if I put required=true, all fields including the ones that are deactive, show required validation message. This way if the user clicks on OK button, he can't close the popup cause there is a lot of required fields validation error. I tried use a parameter in required attribute this way:

<f:facet name="input">
    <h:selectOneMenu value="#{cfop.idTipoTributacao}" required="#{param['EDITAVEL']}"
                                             style="width: 100px;">
        <f:selectItems value="#{selectTipoTributacao.itens}"/>
    </h:selectOneMenu>
</f:facet>

but unfortunately I didn't found a way to pass this parameter when user clicks on save button of p:rowEditor. Is there a way I can make these fields required only when they are in edit mode?? I'm usgin primefaces 2.2.1 with MyFaces

brevleq
  • 2,081
  • 10
  • 53
  • 97

3 Answers3

2

The following workaround worked for me:

Add this to your JSF page:

<script type="text/javascript">
function validateIfEditing()
{
    var isEditing = false;
    var checkmark= $(".ui-icon-check");
    jQuery.each(checkmark, function() {             
        if ('' == this.style.display) {
            isEditing = true;   
        }
    });
    if (isEditing) {
        $("#form\\:notImmediate").click();          
    }
    else {  
        $("#form\\:immediate").click(); 
    }
}
</script>

Then modify your OK/Save button:

<p:commandButton id="okButton" value="OK" onclick="validateIfEditing();"/>
<p:commandButton id="immediate" action="#{controller.save}" immediate="true" style="display:none"/> 
<p:commandButton id="notImmediate" action="#{controller.save}" update="form" style="display:none"/>

Effectively, this is a javscript check that occurs when the user clicks OK/Save to see if the user is in "edit mode". The edit mode check checks to see if any check mark icon is visible; if it is visible, then the user must be in edit mode (this workaround would need to be modified if you use the check icon elsewhere on the page). If the user is in edit mode, then the form is submitted with immediate="false", so validation will occur. If the user is not in edit mode, then the form is submitted with immedidate="true", so no validation will occur. For the "notImmediate" button click, the update attribute is set to update="form" so that the form can be updated with any error messages associated with any validation errors.

BestPractices
  • 12,738
  • 29
  • 96
  • 140
  • Note, alternatively, you might consider not using required="true" and instead write your own Validator or add validation logic to your Action method that is able to handle whether you're in edit mode or not in edit mode. – BestPractices Jul 02 '12 at 18:38
  • this approach is a little confusing... so I've prefered create my own component – brevleq Jul 04 '12 at 20:54
0

I solved the problem creating my own composite component... This way I have more control over when validation happens.

cellEditor:

<c:interface>
    <c:attribute name="id" required="false" targets="celula"/>
    <c:attribute name="desabilitado" required="false" default="true"/>
    <c:facet name="entrada" required="true"/>
    <c:facet name="saida" required="true"/>
</c:interface>
<c:implementation>
    <h:panelGroup id="celula" layout="block" styleClass="hrgi-celula">
        <h:panelGroup layout="block" styleClass="hrgi-celula-entrada" style="display: none">
            <c:renderFacet name="entrada" required="true"/>
        </h:panelGroup>
        <h:panelGroup layout="block" styleClass="hrgi-celula-saida">
            <c:renderFacet name="saida" required="true"/>
        </h:panelGroup>
    </h:panelGroup>
</c:implementation>

rowEditor:

<c:interface>
    <c:attribute name="action" method-signature="void method(java.lang.Object)"/>
    <c:attribute name="indice" required="true"/>
    <c:attribute name="update" required="false" default=""/>
</c:interface>
<c:implementation>
    <h:outputScript library="js" name="hrgiRowEditor.js" target="head"/>
    <h:panelGroup layout="block">
        <h:panelGroup id="painelBotaoEdicao" layout="block" style="display: inline">
            <h:graphicImage library="img" name="pencil.png" onclick="ativarCamposEditaveis('#{cc.clientId}');"
                        style="cursor: pointer;"/>
        </h:panelGroup>
        <h:panelGroup id="painelBotoesSalvamento" layout="block" style="display: none">
            <h:commandLink id="botaoSalvar" style="float: left;" onclick="definirIdRowEditor('#{cc.clientId}')">
                <h:graphicImage library="img" name="check.png"/>
                <f:param name="#{cc.attrs.indice}" value="true"/>
                <p:ajax event="click" update="@form #{cc.attrs.update}" process="@form" listener="#{cc.attrs.action}"
                    oncomplete="desativarCamposEditaveisQuandoSucesso(xhr, status, args, this);"/>
            </h:commandLink>
            <h:graphicImage library="img" name="cancel.png" style="float: left; cursor: pointer;"
                        onclick="desativarCamposEditaveis('#{cc.clientId}');">
            </h:graphicImage>
        </h:panelGroup>
    </h:panelGroup>
</c:implementation>

the only problem is that I can't update just one row in table... Perhaps I will create another component...

brevleq
  • 2,081
  • 10
  • 53
  • 97
  • Following link might be useful for your problem, http://forum.primefaces.org/viewtopic.php?f=3&t=6015 – Jitesh Dec 10 '12 at 12:26
0

Or

<p:commandButton id="okButton" value="OK" onclick="return $('.ui-icon-check:visible').length == 0"/>
MJ Vakili
  • 2,798
  • 1
  • 19
  • 25