[SalesForce] Get multiple values from VF Page and pass them to the class

the code below generates a table and each row has a check box, Name and I added an inputField and I would like to pass the value entered in the inputField, without storing the value in the object. This is working following Mark's advice below. But in order to pass the values I have to use SUBSTRING() in order to get the values from inputvalues[]. As the QTY can VARY, is they other way to get them?

I modified this open source tool 'ClonePlus', this tool allows you to clone parent and a child. Everything works as I wanted but I need to find a different approach to get values without using substring(). I will appreciate any help. Thank you!

VF Page code:

  <apex:pageBlockTable value="{!child.objectRows}" var="objectRow" >

     <apex:column headerValue="Clone" width="10px"> <apex:inputCheckbox value="{!objectRow.selected}"/></apex:column>
     <apex:column headerValue="PO-Details" width="20px" ><a target="_blank" href="/{!objectRow.Id}" style="text-decoration:none">{!objectRow.Name}</a></apex:column>
      <apex:column headerValue="Enter Qty" width="20px"> <apex:inputText value="{!objectRow.EnteredValue}"  /></apex:column> 

    </apex:pageBlockTable>

Class:

public String EnteredValue  { get; set; } //this is for the inputField

this is to do the process if the row is selected:

public void cloneSelectedObjects2(){

SOStoupload = new List<Purchase_Order_Details__c>();
List<String> lista= new  List<String>();

for (relatedObjects relatedObject : objectChildren)
{
    for (relatedObjectRow row : relatedObject.objectRows) 
    {
        if (row.selected)
        {

            lista.add(row.toString());

        } 
    }
    //here for loop to get values
    for (String str : lista)
    {
         String[] inputvalues = str.split(',');

      System.debug(inputvalues);

                  //create new pODetails
                    Purchase_Order_Details__c pod= new Purchase_Order_Details__c(
                    Purchase_Order__c = objecttext,
                    NRProducts__c =inputvalues[1].substring(4,22),
                    Qty_NR__c = Decimal.valueof(inputvalues[3].substring(14,17)) //values from inputField

                    );


                    SOStoupload.add(pod);

      }
   }
   insert SOStoupload;  

 }

here is the System.debug result:

  USER_DEBUG [239]|DEBUG|(relatedObjectRow:[obj=NRProducts__c:{Name=105842683,  Id=a0Cf0000002W3t1EAC},  selected=true, EnteredValue=698])

here is the wrapper class:

    public class relatedObjects
 {
   public List<relatedObjectRow> objectRows { get; set; }
   public String pluralLabel      { get; set; }
   public String relatedName{get;set;}
   public String relatedId{get;set;}


public relatedObjects(List<relatedObjectRow> objectRows, 
                      String pluralLabel,
                      String relatedFieldName)

{
  this.objectRows = objectRows;
  this.pluralLabel = pluralLabel;
  this.relatedName = relatedName;
  this.relatedId = relatedId;

    }   
  }     

 //gets the values and display them in vf page with check boxes
   public class relatedObjectRow
  {
   public sObject obj      { get; set; }
   public Boolean selected { get; set; }
    public String objectRow. {get;set;} //for the inputField


   public relatedObjectRow(Sobject obj)
   {
  this.obj      = obj;
  // All object rows are selected by default.
  this.selected     = true;
    }

   public String getName ()
     {
  try{
    return '' + obj.get('Name');
  } catch (Exception e){
    return '';
  } 
  }

    public String getId ()
     {
  try{
    return '' + obj.get('Id');
  } catch (Exception e){
    return '';
  } 
  }

  }

Best Answer

Your relatedObjectRow class, in addition to having a boolean on it for selected, can have a string value on it for the quantity. Your <apex:inputText /> would then bind to this string value.

Note: I think you've anonymized your objects and these are really sObjects we are talking about, but the same mechanism still applies. The concept is known as using a "wrapper class".

public class relatedObjectRow {
    public string Id            { get; set; }
    public string Name          { get; set; }
    public boolean selected     { get; set; }
    public string EnteredValue  { get; set; }
}

And the VF markup

<apex:pageBlockTable value="{!child.objectRows}" var="objectRow" >

    <apex:column headerValue="Clone" width="10px">
        <apex:inputCheckbox value="{!objectRow.selected}"/>
    </apex:column>
    <apex:column headerValue="PO-Details" width="20px" >
        <a target="_blank" href="/{!objectRow.Id}" style="text-decoration:none">{!objectRow.Name}</a>
    </apex:column>
    <apex:column headerValue="Enter Qty" width="20px">
        <apex:inputText value="{!objectRow.EnteredValue}"  />
    </apex:column> 

</apex:pageBlockTable>

Update: here is a modification that does not use strings, instead using the objects directly.

public void cloneSelectedObjects2(){

    SOStoupload = new List<Purchase_Order_Details__c>();

    for (relatedObjects relatedObject : objectChildren) {
        List<relatedObjectRow> selectedRelatedRows = new List<relatedObjectRow>();

        for (relatedObjectRow row : relatedObject.objectRows) {
            if (row.selected) {
                selectedRelatedRows.add(row);
            } 
        }

        //here for loop to get values
        for (relatedObjectRow row : selectedRelatedRows) {

            //create new pODetails
            Purchase_Order_Details__c pod = new Purchase_Order_Details__c();

            // not sure where this objecttext is coming from
            pod.Purchase_Order__c = objecttext;

            // use the sObject.get() to grab the ID field value from the inner object
            pod.NRProducts__c = row.obj.get('Id');

            // get the 'entered value' from the wrapper class and convert to decimal
            pod.Qty_NR__c = Decimal.valueOf(row.EnteredValue);


            SOStoupload.add(pod);

        }
    }

    insert SOStoupload;  

}
Related Topic