Have a read of articles such as this Wikipedia Hash table article to learn about how buckets are used to speed up retrieval from maps.
When the Account
is first added to the map, its hashCode
method returns a value that determines which bucket the key is allocated to. When you change one of the fields of the Account
object, you change the value returned by the hashCode
method and so very likely change the bucket that is looked in for the key value so it is no longer found, hence the null
result.
Using an SObject as the map key is rarely a good choice because SObjects are often changed in code. (It's also potentially costly in CPU time as all the fields of the SObject have to be examined to generate the hash code and to check for equality.) If an SObject has an Id
value defined use that as the key instead.
In the line:
<apex:inputCheckbox label="{!xmlCatalogsMap[i]}" value="{!i}" html-name="CatalogId" />
value attribute should be Boolean. So that checkbox can be marked as check or uncheck.
Currently it's Integer. That's why it is showing error.
To fix this problem, set up a map of Integer to Boolean, then bind the checkbox to that instead.
public Map<Integer, Boolean> xmlCatalogsChecked { get; set; }
public void getXMLCatalogs() {
// Query omitted
xmlCatalogsChecked = new Map<Integer, Boolean>();
for (ZXMLCatalogs__c c : result) {
xmlCatalogsMap.put(Integer.valueOf(c.BOID__c), c.Name);
// Assign default state
xmlCatalogsChecked.put(Integer.valueOf(c.BOID__c), false);
}
}
<apex:inputCheckbox label="{!xmlCatalogsMap[i]}" value="{!xmlCatalogsChecked[i]}"
html-name="CatalogId" />
Update based on Comments
Main issue in your code is this line at getXMLCatalogs() method which is initializes the map and makes that empty.
Map<Integer, String> xmlCatalogsMap = new Map<Integer, String>();
I have create apex class and pages just like you and it is working correctly.
Apex class
public class DealerController
{
public Map<Integer, String> xmlCatalogsMap {get;set;}
public Map<Integer, Boolean> xmlCatalogsChecked { get; set; }
public Set<Integer> xmlCatalogsKeys {get;set;}
public DealerController()
{
getXMLCatalogs();
}
public void getXMLCatalogs() {
xmlCatalogsKeys = new Set<Integer>();
String sql = 'SELECT Dealer_Number__c, Name FROM Dealer__c ORDER BY Name';
List<Dealer__c> result = Database.query(sql);
xmlCatalogsMap = new Map<Integer, String>();
xmlCatalogsChecked = new Map<Integer, Boolean>();
for (Dealer__c c : result) {
xmlCatalogsMap.put(Integer.valueOf(c.Dealer_Number__c), c.Name);
// Assign default state
xmlCatalogsChecked.put(Integer.valueOf(c.Dealer_Number__c), false);
}
xmlCatalogsKeys = new Set<Integer>(xmlCatalogsMap.keySet());
}
}
Visualforce
<apex:page id="dealerPage" controller="DealerController" action="{!getXMLCatalogs}">
<apex:form >
<apex:pageBlock >
<apex:pageBlockSection >
<apex:repeat value="{!xmlCatalogsKeys}" var="i">
<apex:inputCheckbox label="{!xmlCatalogsMap[i]}" value="{!xmlCatalogsChecked[i]}"
html-name="CatalogId" />
</apex:repeat>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
Result
Best Answer
Of course, feel free to use tables (apex:dataTable, apex:pageBlockTable, etc) as appropriate, and any other dressing you need.