function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
FightinHedgepigFightinHedgepig 

JavaScript and a pageBlockTable

So I've got a VF page that uses a pageBlockTable to display Standard Rate, Discount %, and Discounted Rate for a series of items.  Both the Discount % and the Discounted Rate are editable.  I'd like to be able to let the user change one and have the other calculated for them (using the Standard Rate for the calculation).  I'd also like to do this on the page rather than in the database using triggers or other such methods, so the user has the option of canceling and abandoning any changes.

 

I've got a couple of JavaScript functions that look like they should do the trick, but they're not.  I'm pretty sure it's because they aren't properly referencing the row in the pageBlockTable, but I'm not certain.  Can anyone tell me how to fix this page so I can get what I'm after?

 

 

<apex:page controller="DiscountRateController" action="{!displayRecords}"> 
<script type="text/javascript">
  function updateRate(){
    rate=document.getElementByID("rate").value;
    discPct = document.getElementByID("discPcrnt").value;
    document.getElementByID("discRate").value = rate - (rate * (discPct/100)));
  }
  function updatePcrnt(){
    rate=document.getElementByID("rate").value;
    discRate = document.getElementByID("discRate").value;
    document.getElementByID("discPcrnt").value = (((rate - discRate)/rate) * 100);
  }
</script>
  <apex:form id="discountRates">
    <apex:pageBlock id="discountRatespb">
      <apex:pageBlockButtons >
        <apex:commandButton action="{!edit}" value="Edit" 
            rendered="{!NOT isEditable}" />
        <apex:commandButton action="{!save}" value="Save" 
            rendered="{!isEditable}" />
        <apex:commandButton action="{!cancel}" value="Cancel" 
            rendered="{!isEditable}" />
      </apex:pageBlockButtons>
      <apex:pageBlockTable value="{!selectedRates}" var="sR">
        <apex:column value="{!sR.Item__c}" />
        <apex:column id="rate" value="{!sR.Rate__c}" />
        <apex:column headerValue="Discount %">
          <apex:outputField value="{!sR.Discount__c}" rendered="{!NOT isEditable}" />
          <apex:inputField id="discPcrnt" value="{!sR.Discount__c}" 
            rendered="{!isEditable}" onchange="updateRate();"/>
        </apex:column>
        <apex:column headerValue="Discounted Rate">
          <apex:outputField value="{!sR.Discounted_Rate__c}" 
rendered="{!NOT isEditable}" /> <apex:inputField id="discRate" value="{!sR.Discounted_Rate__c}" rendered="{!isEditable}" onchange="updatePcrnt();"/> </apex:column> </apex:pageBlockTable> </apex:pageBlock> </apex:form> </apex:page>

 

Any hints would be appreciated.

 

 

Thanks,

Jonathan

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
Edwin VijayEdwin Vijay

Hello!!

 

Since you use a pageblocktable, you cannot refer elements directly by using the "id" attribute. Bacause, in your javascript function when you say 

document.getElementByID("rate").value;

there may be actually more than one column with the same id. Visualforce automatically assigns a dynamic id to components within a table. This was just to give you an insight of what actually is the problem...

 

To solve your problem, use something like this

 

 

 <apex:inputField id="discPcrnt" value="{!sR.Discount__c}" 
            rendered="{!isEditable}" onchange="updateRate('{!$Component.discPcrnt}','{!$Component.rate}');"/>

 

You can then refer them in your javascript function... Hope it helps

 

 

I have done  a somewhat similar work with javascript and you can find it here  http://www.forcetree.com/2010/04/expand-collapse-pageblock-table-columns.html

 

Cheers!!!

 

 

All Answers

Edwin VijayEdwin Vijay

Hello!!

 

Since you use a pageblocktable, you cannot refer elements directly by using the "id" attribute. Bacause, in your javascript function when you say 

document.getElementByID("rate").value;

there may be actually more than one column with the same id. Visualforce automatically assigns a dynamic id to components within a table. This was just to give you an insight of what actually is the problem...

 

To solve your problem, use something like this

 

 

 <apex:inputField id="discPcrnt" value="{!sR.Discount__c}" 
            rendered="{!isEditable}" onchange="updateRate('{!$Component.discPcrnt}','{!$Component.rate}');"/>

 

You can then refer them in your javascript function... Hope it helps

 

 

I have done  a somewhat similar work with javascript and you can find it here  http://www.forcetree.com/2010/04/expand-collapse-pageblock-table-columns.html

 

Cheers!!!

 

 

This was selected as the best answer
FightinHedgepigFightinHedgepig

That helped a lot, thanks!

 

I had a problem getting a value from the "rate" component in my JavaScript function, I assume because it was an output field rather than an input field.  Also, I had getElementByID instead of getElementById in the function.  Lovely.

 

I ended up with a call that looks like this:

 

 <apex:inputField id="discPcrnt" value="{!sR.Discount__c}" rendered="{!isEditable}" onchange="updateRate('{!$Component.discPcrnt}','{!sR.rate}', '{!$Component.discRate}');"/>

 

The third element is the target field, whose value I'm able to set from Javascript.

 

Again, thanks for the help on this.

Jonathan

 

 

Tal One1Tal One1

Hi Jonathan,

I am trying to build a dynamic data table with the same idea as yours (i.e. update the total price when the user changes the quantity and so on) and your post has been very helpful.

The problem is that when I use the value property of the input field objects I get it as string and can't do anything with it.

Can you please post the javascript function you used or point me in the right direction?

Thanks,

Tal

spatel_cespatel_ce

Hi,

 

Your marked answer worked for me, but I am stuck in same sitution where I am looking for Javascript. Here is my code that calls javascript function on click of image from PageBlockTable Column, but it seems like that it never calls that function.

 

Any help will be really appreciated.

 

Here is a code for my Visualforce page:

 

<apex:pageBlock id="Skulls">
            <apex:pageblocksection id="pbsSkulls" rendered="true">
                <apex:pageBlockTable id="pbtSkulls" value="{!lstSBones}" var="SB">
                    <apex:column >
                        <apex:commandlink onclick="callActionMethod('{!SB.Skulls__c}');" >
                            <apex:image url="{!$Resource.Plus}" height="20" width="20"/>
                        </apex:commandLink>
                    </apex:column>
                 </apex:pageBlockTable>
            </apex:pageblocksection>
         </apex:pageBlock>

         <apex:actionFunction name="readCell" action="{!readCellMethod}" reRender="resultPanel" >
             <apex:param name="SkillNExpertise" assignTo="{!clickedCellValue}" value="" />
         </apex:actionFunction>

         <script type="text/javascript">
            function callActionMethod(txtSkull) {
            readCell(txtSkull);
         }
         </script>

 

Here is Controller Code:

 

    public String clickedCellValue { get; set; }
    public String SelectedValue { get; set; }
        
    public void readCellMethod() {
        SelectedValue = 'Selected Value: ' + ClickedCellValue;
    }    

 

 Thanks,

Sawan

 

Tal One1Tal One1

I think you should use the onclick attribute of the <apex:image> instead placing the image between <apex:commandLink> tags. That should do the trick.

spatel_cespatel_ce

Hi,

 

I changed <apex:ActionFunction /> to <apex:ActionSupport /> and it works for me. Here is a post that I opened and got my answer. Though thanks for suggestion my friend.

 

-Sawan