0

I do not understand why my values keep getting switched. I think it assigns the value of the first input value box to the first item added and the value fields are not in order of the objects.

            <apex:inputCheckbox value="{!...}" rendered="{!contains(...)}">
            </apex:inputCheckbox>

            <apex:SelectList rendered="{!contains(...)}" size="1" value="{!...}">
                <apex:SelectOptions value="{!picklist}" />
            </apex:SelectList>


     </apex:outputPanel>
     //

Sample Output when initially added

     Name          Value

     Object2        55   // Added Second datatype: String
     Object1        33   //Added First datatype: String

     Output after save button is clicked once

     Object1        33   
     Object2        55   

Output after clicking the save button again, the values will keep switching.

     Object1        55   
     Object2        33

     //

Object are stored in a Map which is changed to a list using map.value() for displaying:

The list is of the subclass objects from below. public class AccountDetailInstance {

    public List<SelectOption> pickList {get; set;}
    public String textValue {get; set;}


 }

The list is saved into the salesforce object by duplicating the values and the list gets regenerated based off of the salesforce objects that were saved everytime.

//This method loads all the instances for a page
private void loadInstances() {

    instancesMap =  new Map<Id, sObject>([SELECT Id, Name, Value__c, Type__C, content__c FROM sObject);
    //debug account ...

    for (sObject items: instancesMap.values()) {

        subClassObject subItem = new subClassObject(items.Name);

        subItem.Id = Item.Id;


        if (items.Type__c.equals('Picklist') || adi.Type__c.equals('Multipicklist')) {

            subItem.pickList = createLists(content__c); //generates selection list based on values
        }

       if (item.Type__c.equals('String'))    
        {
            subItem.value = Item.value__c'
        }          
    }

}
// This method adds an instance from a selection list which the user chooses in the UI
public void addItem() {

    for (String id : selectedInstances) {

        //creates new sublcass object and adds it to the instanceMap

            instanceMap.put(subItem.Name, subItem);


        }
    }

}
public PageReference save() {
    Account account = (Account) controller.getRecord();
    List<sObject> sObjectList = new List<sObject>();
    subClass subItem; 
    for (subClass subItem : InstanceMap.Values()) {
        //Set all the fields for the sObject
        sObjectList.add(subItem);
    }

    upsert detailInstanceList;

    return ApexPages.currentPage();

}
6
  • Interesting. Is this from a custom controller/extension. If so, do you have your controller code that generates the list of SelectOptions? Commented Apr 4, 2014 at 15:25
  • hey, i just changed the output example to match my problem better, il see if i can post the controller code.
    – ths
    Commented Apr 4, 2014 at 15:27
  • A common cause of varying order is when some intermediate logic makes use of a map and the key isn't just a primitive. So yes, post the code that builds the list that has order problems.
    – Keith C
    Commented Apr 4, 2014 at 15:52
  • Absolutely. If the list is re-created from Map.values, then the order isn't guaranteed to be consistent between client-server roundtrips.
    – Mike Ginou
    Commented Apr 4, 2014 at 15:54
  • I see, I think my problem is surely with the Map.Value() but since I have to use a map how do I preserve the order?
    – ths
    Commented Apr 4, 2014 at 16:08

1 Answer 1

2

I don't fully follow your logic, but hopefully this answer will allow you to address the problem in your own code.

As you mention in your comment, Apex does not have order-retaining maps. (You can create them yourself but the lack of generics in Apex limits the attractiveness of that approach.)

But you can use more than one collection type side-by side e.g. a List and a Map:

private List<SObject> sobList;
private Map<Id, SObject> sobMap;
private void loadInstances() {
    sobList = [select Id, Name, ... from SObject order by Name];
    sobMap = new Map<Id, SObject>();
    for (SObject sob : sobList) {
        sobMap.put(sob.Id, sob);
    }
}

and refer to the list when order matters and use the map where you want to do a quick lookup (or avoid duplicates). Also note the explicit order by in the SOQL.

2
  • thank you so much for your help. I will be trying to implement a similar solution.Hopefully it works out.
    – ths
    Commented Apr 4, 2014 at 18:02
  • It worked! you are the best :)
    – ths
    Commented Apr 4, 2014 at 19:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .