<!--

    Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.

    This program and the accompanying materials are made available under the
    terms of the Eclipse Public License v. 2.0, which is available at
    http://www.eclipse.org/legal/epl-2.0.

    This Source Code may also be made available under the following Secondary
    Licenses when the conditions for such availability set forth in the
    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
    version 2 with the GNU Classpath Exception, which is available at
    https://www.gnu.org/software/classpath/license.html.

    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0

-->

<!-- jdbc/jdbcConnectionPoolNew2.jsf -->


<!initPage
    getRequestValue(key="form2:validate" value="$attribute{form2-validate}");
    setComponentRequired(id="form2:sheet:generalSheet:dsProp:datasource" required="$attribute{form2-validate}" )
    setResourceBundle(key="i18n" bundle="org.glassfish.admingui.core.Strings")
    setResourceBundle(key="i18njdbc" bundle="org.glassfish.jdbc.admingui.Strings")
    setResourceBundle(key="help_jdbc" bundle="org.glassfish.jdbc.admingui.Helplinks")
/>

<!composition template="/templates/default.layout"  guiTitle="$resource{i18njdbc.jdbcConnectionPool.Step2PageTitle}"
        guiTemplateOnLoad="document.onkeypress =stopRKey;"
>
<!define name="content">
    <event>
    <!beforeCreate
        getRequestValue(key="cancelPage" default="jdbc/jdbcConnectionPools.jsf" value=>$page{cancelPage});
        setSessionAttribute(key="noValidation" value="#{null}")
        setPageSessionAttribute(key="step2" value="#{true}" );
        setPageSessionAttribute(key="step1Page" value="jdbcConnectionPoolNew1.jsf" );
        setPageSessionAttribute(key="selfPage" value="#{request.contextPath}/jdbc/jdbcConnectionPoolNew2.jsf");
        setPageSessionAttribute(key="parentPage" value="#{request.contextPath}/jdbc/jdbcConnectionPools.jsf");
        setPageSessionAttribute(key="childType" value="jdbc-connection-pool");

        setPageSessionAttribute(key="tableList" value="#{sessionScope.wizardPoolProperties}");
        setPageSessionAttribute(key="convertToFalseList" value={"ping" "isConnectionValidationRequired" "failAllConnections" "allowNonComponentCallers" "nonTransactionalConnections" "isIsolationLevelGuaranteed"});
        //set the following for including buttons.inc
        setPageSessionAttribute(key="edit" value="#{false}" );
        setPageSessionAttribute(key="showDefaultButton" value="#{true}" );
        setPageSessionAttribute(key="showCancelButton" value="#{true}" );
        setPageSessionAttribute(key="hasPropertySheet" value="#{true}" );
        setPageSessionAttribute(key="hasPropertyTable" value="#{true}" );
        setAttribute(key="DSList" value="#{wizardPoolExtra.DSList}" );
        setAttribute(key="DList" value="#{wizardPoolExtra.DList}" );

        setPageSessionAttribute(key="childType" value="jdbc-connection-pool");
        setPageSessionAttribute(key="parentUrl", value="#{sessionScope.REST_URL}/resources");
        setPageSessionAttribute(key="rest-api" value="true");
    />
    </event>

            <sun:form id="form2">
#include "/common/shared/alertMsg_1.inc"
            <sun:hidden id="validate"  value="TRUE" />
                <!-- Page Title -->
                <sun:title id="propertyContentPage" title="$resource{i18njdbc.jdbcConnectionPool.Step2PageTitle}"
                    helpText="$resource{i18njdbc.jdbcConnection.step2PageHelp}">
#include "jdbcConnectionPoolNew2Buttons.inc"
                 </sun:title>

#include "/jdbc/poolPropertyNew.inc"
#include "/common/shared/propertyDescTable.inc"

                 <sun:title >
#include "jdbcConnectionPoolNew2Buttons.inc"
                 </sun:title>

	<sun:hidden id="helpKey" value="$resource{help_jdbc.jdbcConnectionPoolNew2}" />
            </sun:form>
#include "/common/shared/changeButtonsJS.inc"

<f:verbatim>
<script type="text/javascript">
    function disableTableField() {
        var methodType = document.getElementById("$pageSession{valMethod}");
        if (methodType.getSelectedValue()  != 'table'){
            disableComponent('$pageSession{tableTextField}', 'select');
        }else{
            enableComponent('$pageSession{tableTextField}', 'select');
        }
    }

    function isEmpty(value) {
        if (value == null || value == '') {
            return true;
        }
        return false;
    }
    function isClassNamePresent(dsName, driverName, dsNameFieldId, driverNameFieldId, reqMsg) {
        var datasource = document.getElementById(dsNameFieldId).value;
        var driver = document.getElementById(driverNameFieldId).value;
        if (!isEmpty(dsName) || !isEmpty(driverName)) {
            datasource = dsName;
            driver = driverName;
        }
         if (isEmpty(datasource) && isEmpty(driver)) {
            showAlert(reqMsg);
            return false;
        }
        return true;
    }

   function stopRKey(evt) {
        var evt = (evt) ? evt : ((event) ? event : null);
        var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
        if ((evt.keyCode == 13) && (node.type=="text"))  {return false;}
    }

    </script>
</f:verbatim>

</define>
</composition>


