2

I have an XPage which uses JQuery dialog and client-side validation to validate the input the user processes. The problem is that when I click Add button client-side validation works, but properties from those fields 'cannot ' be found on server side. When the user clicks 'Open dialog' button the dialog shows up and Here's my button where the magic happens(only one property, just for example):

<xp:button id="save_part_btn" value="+Add" style="float:right;">
             <xp:eventHandler event="onclick" submit="true"
                refreshMode="complete">
                <xp:this.action><![CDATA[#{javascript:
                    /*          
                    var estdoc:NotesDocument=database.getDocumentByUNID(doc_source.getDocument().getParentDocumentUNID())
                    var estPartdoc:NotesDocument=estdoc.getParentDatabase().createDocument()

                    Ignore it

                    estPartdoc.replaceItemValue('Form','Estimate_Cost_Part')
                    estPartdoc.replaceItemValue('Predoc',estdoc.getUniversalID())
                    estPartdoc.replaceItemValue('$OSN_IsSaved','1')
                    */

                    estPartdoc.replaceItemValue('TSNB_All',getComponent('input_tsnb_all').getValue())

                }]]></xp:this.action>

                        <xp:this.script><![CDATA[ 

                            var isValid = true;
                            var result = "";

                            function isStringEmpty(string2Check) 
                            {
                                return string2Check == "" || string2Check[0] == " ";
                            }

                            function isNumberCorrect(number2Check) 
                            {
                                return /^[1-9]\d*(,\d{1,3})?$/.test(number2Check.toString());
                            }


                            if(isStringEmpty(document.getElementById("#{id:input_tsnb_all}").value)) 
                            {
                                wholeValid = false;
                                result += '-The field cannot be empty\n'
                            }
                            else if(!isNumberCorrect(document.getElementById("#{id:input_tsnb_all}").value)) 
                            {
                                wholeValid = false;
                                result += '-The field is not correct\n'
                            }

                            if(!isValid)    
                            alert(result) 
                            return isValid;  

                ]]></xp:this.script>
            </xp:eventHandler>
</xp:button>

Client-side validation works perfectly - when the user's input is incorrect alert message gets displayed. However, input_tsbn_all cannot be found on the server side and the document with this property can't not be created. Actually it does, but the input_tsbn_all's value in null. What is the problem?

Markup for the property is:

<xp:tr>
    <xp:td><xp:label value="All:"/></xp:td>
       <xp:td>
          <xp:inputText id="input_tsnb_all"
                            disableClientSideValidation="true"
                            styleClass="doc_field_textinput"  size="40" >
            <xp:this.converter>
                    <xp:convertNumber pattern="0.000"></xp:convertNumber>
            </xp:this.converter>
            </xp:inputText>
    </xp:td>
</xp:tr>

My JQuery code:

    var dialogAddPartDiv = $('.dialogAddPart'); 

      $('.addButton').click(function() 
      {
        dialogAddPartDiv.dialog('open');
      });

      dialogAddPartDiv.dialog(
      {
      create: function (event, ui) {


                    $(".ui-corner-all").css('border-bottom-right-radius','8px');
                    $(".ui-corner-all").css('border-bottom-left-radius','8px');
                    $(".ui-corner-all").css('border-top-right-radius','8px');
                    $(".ui-corner-all").css('border-top-left-radius','8px');

                    $(".ui-dialog").css('border-bottom-left-radius','0px');
                    $(".ui-dialog").css('border-bottom-right-radius','0px');
                    $(".ui-dialog").css('border-top-left-radius','0px');
                    $(".ui-dialog").css('border-top-right-radius','0px');

                    $('.ui-dialog-titlebar-close').css('margin', '-25px -20px 0px 0px').css('border', 'solid 2px').css('border-radius', '15px').css('border-color', '#05788d');
                    $('.ui-dialog-titlebar-close').css('width', '25px').css('height', '25px');
                },

        autoOpen: false,
        modal: true,
        beforeClose : function(event) 
        {
            if(!confirm("This won't be saved. Continue?"))
            {
            return false;
            }
            else 
            {

            }
        },
        width:600,
        resizable: false
      });
document.getElementsByClassName('ui-dialog-titlebar-close')[0].setAttribute('title', 'Close it?');

And the hidden div is just declared on the page like this: <xp:div styleClass="dialogAddPart">

1 Answers1

1

You need to bind your input to a object property that persists through request. A silly example could be exploiting the viewScope object that is a Map.

<xp:inputText id="input_tsnb_all" value="#{viewScope.myInput}">
    ...

What you would later on do in the code would be to look up the viewScope.myInput variable to do what you want with it, rather than finding the component in the ViewRoot tree.

My best advice for you is to encourage you to build up some JSF fundamentals in order to understand why things are done this way.

Alas, XPages makes it for the worst possible iteration of JSF where to learn things in the right way. Most of it pushes an underlying concept - the old Notes developer mindset - that prevents you from working the framework in the way it is intended, that is MVC.

I'm not going to tell you to avoid doing that because much of what you see on the Internet about the topic is that old fashioned soup. But if you care, even a little, take a not too new JSF book and learn from there. Or, for free, you might want to have a look here. Of course, you will need to mediate what you read with what is actually available in XPages since, as I sad, XPages is an interpretation of JSF in its own right.

shillem
  • 1,260
  • 7
  • 12
  • What does `#{viewScope.myInput}` mean in this context? I mean how do I access it on a server side? – Robert Baratheon Jan 19 '18 at 09:49
  • With horrible SSJS you will access it literally as it's written: `destPartdoc.replaceItemValue('TSNB_All', viewScope.myInput);` With Java it's different: `((UIViewRootEx) facesContext.getViewRoot()).getViewMap().get('myInput');` – shillem Jan 19 '18 at 09:51
  • Why is it horrible? – Robert Baratheon Jan 19 '18 at 10:05
  • For starters, it creates confusion as to what is done/possible on the server side and what on the client side. It's JavaScript in the syntax but not in the context. Secondly it encourages the bad practice of mixing logic with presentation; XPage source code done this way looks ugly as hell and very difficult to read. Thirdly, it's not type safe and therefore you are more prone to typing errors and catching them only when the code runs rather than at compile time. I would continue my rant but comments are limited in characters so I stop – shillem Jan 19 '18 at 10:11
  • Hmmm, interesting, even the horrible way doesn't work :)))))))))))))))))))))))))))))))))))))))) – Robert Baratheon Jan 19 '18 at 10:35
  • That has nothing to do with the use of JQuery dialogs – shillem Jan 19 '18 at 10:54
  • Actually, no. When I just made it not as dialog, just as plain div(not hidden, of course), it worked correctly. – Robert Baratheon Jan 19 '18 at 11:01
  • The problem is elsewhere, in how you handle its lifecycle - what the dialog buttons do etc... But in and of itself it can't be. – shillem Jan 19 '18 at 11:49
  • Technically I don't have any buttons in the dialog, the div holds it – Robert Baratheon Jan 19 '18 at 12:25