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
ministe_2003ministe_2003 

Set value of map with PageBlockTable

I'm getting an odd error when trying to set a value in a map from a pageBlockTable.  Here's my Map:

 

prodList = *select some PricebookEntry records*

for(PricebookEntry pe : prodList){
  prodQty.put(pe, 0);
}

 

So I'm querying PricebookEntry records and then creating a map where the PBE is the key and an integer is the value.  This is so I can assign the number of rows of each PricebookEntry that I want.  This is the pageBlockTable I've written:

 

<apex:pageBlockTable value="{!prodQty}" var="p" columns="6">
  <apex:column headerValue="Quantity">
    <apex:inputText value="{!prodQty[p]}" />
  </apex:column>
  <apex:column headerValue="Product Name" value="{!p.Product2.Name}" />
  <apex:column headerValue="Product Code" value="{!p.Product2.ProductCode}" />
  <apex:column headerValue="Product Family" value="{!p.Product2.Family}" />
  <apex:column headerValue="Currency" value="{!p.CurrencyIsoCode}" />
  <apex:column headerValue="Requires Sub Group" value="{!p.Product2.Requires_Sub_Group__c}" />
</apex:pageBlockTable>

 Which displays the table nicely.  The first column is an input text field where I can enter the number of each row I want (They're all defaulted to zero, as per the Map initialisation code) and the rest of the columns display the specified PricebookEntry field.

 

The problem comes when the user tries to progress.  After entering the values they want, they press a "Select" Command Button and this returns errors like this:

 

Value '01uXXXXXXXXXXXXXXX' cannot be converted from core.apexpages.el.adapters.SObjectELAdapter to common.apex.runtime.SObjectRow 

Where the Id is a PricebookEntry Id - this error is repeated for every PricebookEntry that I display in the table.

 

The error is not related to the work I'm doing when the user clicks the Select - even if I call an empty method when the user clicks this button, this error still displays.  It's something to do with the inputText column in the table, ie

<apex:column headerValue="Quantity">
  <apex:inputText value="{!prodQty[p]}" />
</apex:column>

 I know this because the error doesn't display if I don't have this column in my table.

 

I'm sure I've done something like this in the past at a previous company but I can't get it working this time.  All I want to do is update the value assigned to the relevant PricebookEntry's row in the map so I know how many of each row to create.  I've never encountered this error before and it doesn't show up in debug logs so I'm stumped.  Does anyone know what I'm doing wrong?

 

Thanks

Best Answer chosen by Admin (Salesforce Developers) 
ministe_2003ministe_2003

I've now got a workaround, its pretty simple and it works.  I was hoping to do it with just one map but it seems that's not possible.  So my work around is:

 

prodList = *select some PricebookEntry records*

for(PricebookEntry pe : prodList){
  prodMap.put(pe.Id, pe);
  prodQty.put(pe.Id, 0);
}

 As before I query the pricebook entry table and store it in a list.  I then make a map but instead of mapping a pricebookentry to a number, I just map the Id to a number.  I create another map which maps the Id to the pricebookentry, that way I can still link an Id to the object's fields in the VF page.  My table now looks like:

 

<apex:pageBlockTable value="{!prodList}" var="p" columns="6">
  <apex:column headerValue="Quantity" width="50px">
    <apex:inputText styleClass="spinner" value="{!prodQty[p.Id]}" html-readonly="readonly"/>
  </apex:column>
  <apex:column headerValue="Product Name" value="{!prodMap[p.Id].Product2.Name}" />
  <apex:column headerValue="Product Code" value="{!prodMap[p.Id].Product2.ProductCode}" />
  <apex:column headerValue="Product Family" value="{!prodMap[p.Id].Product2.Family}" />
  <apex:column headerValue="Currency" value="{!prodMap[p.Id].CurrencyIsoCode}" />
  <apex:column headerValue="Requires Sub Group" value="{!prodMap[p.Id].Product2.Requires_Sub_Group__c}" />
</apex:pageBlockTable>

 So the difference here is that the Quantity field is linked to the prodQty map, meaning I set the quantity by setting the corresponding value to the priceookentry Id (key).  The rest of the fields are set using the prodMap table where the Id maps to the object itself.  This has fixed the problem so I can only asume the issue is caused by the page trying to reference a map key using an object instead of an Id.

 

I also set the table to pull data from the original List I queried - this is simply so the order is respected because a map is unordered.

 

All Answers

firechimpfirechimp

Hi Ministe,

From your explination it seams you are having an issue when it is trying to update the value in the viewstate.

I probably won't be able to suggest away to fix this without seeing more of your code and debugging.

 

What I would suggest is; the use of a wrapper class in this case would be much better and should not have the same issue. To do this you would store a list of your wrapper class instead of the map that you currently store. In your wrapper you will hold your PricebookEntry record and the quantity value. Then just loop the list of wrappers on your page.

 

ministe_2003ministe_2003

I've now got a workaround, its pretty simple and it works.  I was hoping to do it with just one map but it seems that's not possible.  So my work around is:

 

prodList = *select some PricebookEntry records*

for(PricebookEntry pe : prodList){
  prodMap.put(pe.Id, pe);
  prodQty.put(pe.Id, 0);
}

 As before I query the pricebook entry table and store it in a list.  I then make a map but instead of mapping a pricebookentry to a number, I just map the Id to a number.  I create another map which maps the Id to the pricebookentry, that way I can still link an Id to the object's fields in the VF page.  My table now looks like:

 

<apex:pageBlockTable value="{!prodList}" var="p" columns="6">
  <apex:column headerValue="Quantity" width="50px">
    <apex:inputText styleClass="spinner" value="{!prodQty[p.Id]}" html-readonly="readonly"/>
  </apex:column>
  <apex:column headerValue="Product Name" value="{!prodMap[p.Id].Product2.Name}" />
  <apex:column headerValue="Product Code" value="{!prodMap[p.Id].Product2.ProductCode}" />
  <apex:column headerValue="Product Family" value="{!prodMap[p.Id].Product2.Family}" />
  <apex:column headerValue="Currency" value="{!prodMap[p.Id].CurrencyIsoCode}" />
  <apex:column headerValue="Requires Sub Group" value="{!prodMap[p.Id].Product2.Requires_Sub_Group__c}" />
</apex:pageBlockTable>

 So the difference here is that the Quantity field is linked to the prodQty map, meaning I set the quantity by setting the corresponding value to the priceookentry Id (key).  The rest of the fields are set using the prodMap table where the Id maps to the object itself.  This has fixed the problem so I can only asume the issue is caused by the page trying to reference a map key using an object instead of an Id.

 

I also set the table to pull data from the original List I queried - this is simply so the order is respected because a map is unordered.

 

This was selected as the best answer
Meryem FRQMeryem FRQ
Yes, apparently if you are using a map with a dynamic visualforce component it'll throw this error. I just used a inner class with the objects that I want to map, stored them in a list and it worked like magic.
Good Luck