2

I want to have a little validation when user enter value into apex:inputText it compares it with apex:column, if difference is more than 10%, it would alert the user.

Probably it would be triggered using onblur and would change style of apex:column, but I am not sure how can I compare them two?

Many thanks,

~dzh

EDIT: Code excerpt

<script type="text/javascript">
function a(){
var price=document.getElementById('{!$Component.quotedConsumption.Rec.AQQ}').value;
alert(price);}
</script>
     <apex:column headerValue="Current annual Consumption" value="{!Rec.AQ}" id="currentConsumption"/> 
         <apex:column headerValue="Annual consumption quoted for" >
          <apex:inputtext value="{!Rec.AQQ}" required="true" onblur="a()" id="quotedConsumption"/>
         </apex:column>

The error I am getting in console:

Uncaught TypeError: Cannot read property 'value' of null 
  • Hi @dzh, can you provide us with some code that you have tried already and details of where you are stuck. – BarCotter Feb 24 '14 at 14:56
  • @BarCotter Updated the body. Getting stuck to the fact that value is not being populated. Also tried getElementById('{!$Component.quotedConsumption}') – dzh Feb 24 '14 at 16:30
  • So strange, this is what appears in JS source var price=document.getElementById("").value; – dzh Feb 24 '14 at 17:24
2

I think you can do this with jQuery. Use the .closest method to find the row you are in and then get the value from the other field. Something like this (warning, I didn't test this code in a browser).

<apex:includeScript value="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" />
<script type="text/javascript">
  j$ = jQuery.noConflict();
  function checkValues(e) {
    thisRow = j$(e).closest('tr'); //edited
    var currentConsumption = thisRow.find('[id$="currentConsumption"]').text();
  }
</script>

<apex:column headerValue="Current annual Consumption">
  <apex:outputText value="{!Rec.AQ}" id="currentConsumption" />
</apex:column>
<apex:column headerValue="Annual consumption quoted for" >
  <apex:inputtext value="{!Rec.AQQ}" required="true" onblur="checkValues(this)" id="quotedConsumption"/>
</apex:column>
  • Many thanks for this tip, it helped me to build a working version! – dzh Feb 25 '14 at 13:17
1

I found a work around for your issue using the below code

<script type="text/javascript">
function a(obj){
var price = obj.value;
alert(price);}
</script>
         <apex:column headerValue="Annual consumption quoted for" >
          <apex:inputtext value="{!Rec.AQQ}" required="true" onblur="a(this)" id="quotedConsumption"/>
         </apex:column>

hope it works out.

  • heh, it does work, however, how do I find out the value of adjacent apex:column ? – dzh Feb 24 '14 at 18:34
1

Big thanks to codebandit, Mark Pond and mostly Daniel Hoechst. All of your answers helped to build this!

Here's JavaScript that worked for me:

<apex:includeScript value="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" />
<script type="text/javascript">
 j$ = jQuery.noConflict();

 function compareValues(element) {

                thisRow = j$(element).closest('tr');
                var currentConsumption = thisRow.find('[id$="currentConsumption"]').text();

                // get the references to these two DOM elements and create vars for calculation
                var thisElement = element,               
               // compareToElement = document.getElementById(compareTo),
                quotedValue = parseFloat(thisElement.value),
                currentValue = parseFloat(currentConsumption),
                largerValue = null,
                smallerValue = null,
                percentDifference = null;

            // make sure we have got values to work with
            if (!isNaN(quotedValue) && !isNaN(currentValue)) {

                // find the larger and smaller values
                largerValue = Math.max(currentValue, quotedValue);
                smallerValue = Math.min(currentValue, quotedValue);

                // calculate the percentage difference between these numbers, force the parse as base-10
                percentDifference = parseInt((largerValue - smallerValue) / ((largerValue + smallerValue) / 2) * 100, 10);

                // alert the user of the difference value
                if (percentDifference > 10) {
                    alert('Warning: The quoted value differs more than 10% of current consumption!');
                }

            } else {
                // one of the elements is null
                alert('One of the elements to compare is null or isn\'t a number.');
            }
        }
</script>

And VF:

<apex:inputtext value="{!Rec.AQQ}" required="true" onblur="compareValues(this)" id="quotedConsumption"/>
1

You can use the {!$Component.whateverName} within the column markup and when the table is rendered, this reference is relative to the row where the markup occurs.

You can pass this id value as a string as well as the reference to the current input element to the function and then retrieve the DOM element from there and perform the math on the values to find the percentage difference between the two values.

Relevant documentation: Best Practices for Accessing Component IDs

Your page markup will look something like this:

<apex:page id="thePage">
    <script type="text/javascript">
        function compareValues(element, compareTo) {

            // get the references to these two DOM elements and create vars for calculation
            var thisElement = element,
                compareToElement = document.getElementById(compareTo),
                quotedValue = parseFloat(thisElement.text),
                currentValue = parseFloat(compareToElement.value),
                largerValue = null,
                smallerValue = null,
                percentDifference = null;

            // make sure we've got values to work with
            if (thisElement && compareToElement && !isNaN(quotedValue) && !isNaN(currentValue)) {

                // find the larger and smaller values
                largerValue = Math.max(currentValue, quotedValue);
                smallerValue = Math.min(currentValue, quotedValue);

                // calculate the percentage difference between these numbers, force the parse as base-10
                percentDifference = parseInt((largerValue - smallerValue) / ((largerValue + smallerValue) / 2) * 100, 10);

                // alert the user of the difference value
                if (percentDifference > 10) {
                    alert('More than 10% difference: ' + percentDifference);
                } else {
                    alert('Less than 10% difference: ' + percentDifference);
                }

            } else {
                // one of the elements is null
                alert('One of the elements to compare is null or isn\'t a number.');
            }
        }
    </script>

    <apex:pageBlock>
        <apex:pageBlockTable id="thePageBlockTable">
            <apex:column headerValue="Current annual Consumption">
                <apex:outputText value="{!Rec.AQ}" id="currentConsumption" />
            </apex:column>
            <apex:column headerValue="Annual consumption quoted for" >

                <!-- the Component.currentConsumption reference is relative to _this_ row in the table -->
                <apex:inputtext value="{!Rec.AQQ}" required="true" 
                    onblur="compareValues(this, '{!$Component.currentConsumption}')" id="quotedConsumption"/>

            </apex:column>
        </apex:pageBlockTable>
    </apex:pageBlock>
</apex:page>
  • Hi, many thanks for this reply. I can see you've put a lot of effort into constructing the logic of this. Unfortunately it didn't work fully, as onblur call is rendered literally: <input id="j_id0:j_id3:j_id4:j_id5:0:quotedConsumption" type="text" name="j_id0:j_id3:j_id4:j_id5:0:quotedConsumption" onblur="compareValues(this, '{$!Component.currentConsumption}')"> I did however use your logic to build a complete solution that worked for me! – dzh Feb 25 '14 at 13:16
  • The reason that you received the literal string in the onblur is because there was a typo in my example. {!Component vs {!$Component – Mark Pond Feb 25 '14 at 20:37
  • Yes, I have noticed and fixed that before posting here. Note that result includes $. – dzh Feb 26 '14 at 10:59
  • 1
    Yours had a typo as well, which is why it was rendered literally. '{$!Component.currentConsumption} the exclamation point and dollar sign are reversed. Glad you got it sorted out. – Mark Pond Feb 26 '14 at 18:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.