[SalesForce] Passing Selected record Id value and Radiobutton value to the controller from pageblocktable

I want to capture both the Record Id and the selected Radio Button value and pass it to the controller and create new Child object record with the selected values only process the selected records.

Visualforce Code:

<apex:page controller="skillproficiencycontroller" >
<apex:form >
<script> function myFunction( val){ var x = val.value; callfunc(x); } </script>
<apex:pageBlock > <
apex:pageblockTable value="{!skilllist}" var="s">
<apex:column value="{!s.Name}"/>
<apex:column headerValue="Proficiency">
<apex:selectRadio value="{!Selected}" onclick="myFunction(this);">
<apex:selectOptions value="{!items}" /> </apex:selectRadio>
</apex:column>
</apex:pageblockTable>
</apex:pageBlock>
</apex:form>
</apex:page>

Controller:

public with sharing class skillproficiencycontroller
{
    public List<skill__c> skilllist{get;set;}
    public String Selected{get;set;}
     
     public skillproficiencycontroller()
         {
             skilllist = new List<Skill__c>();
             skilllist= [select Name FROM skill__c];
         }

     public List<selectoption> getitems() {
         List<SelectOption> options = new List<SelectOption>();  
                 options.add(new SelectOption('Basic Knowledge' , 'Basic Knowledge'));  
                 options.add(new SelectOption('Intermediate' , 'Intermediate'));
                 options.add(new SelectOption('Advanced' , 'Advanced'));  
                 return options;
       }
   
   public void Save()
     {
    List<Skill_Details__c >skilldetailslist = new List<Skill_Details__c >();
         for(Skill s: selectedskilllist){
          Skill_Details__c sd = new Skill_Details__c();
           sd.Skill_c = s.Id;
           sd.Proficiency__c = Selectedvalue;
          skilldetailslist.add(sd);
          }
       Insert skilldetailslist;
}
}}

enter image description here

Best Answer

This is a perfect use case for a wrapper class. The wrapper class will contain the sObject which was originally queried and the value chosen in the related selectRadio, which you can reference during your save method after checking to see if the user made a selection.

Page controller

public with sharing class skillproficiencycontroller {

    public class SkillWrapper {
        // holds the sobject from the query
        public Skill__c theSkillRecord { get; set; }

        // stores the selection from the radio button
        public String proficiencyLevel { get; set; }
    }

    public List<SkillWrapper> skillWrappers { get; set; }

    public skillproficiencycontroller() {

        // new up the list for the wrappers
        skillWrappers = new List<SkillWrapper>();

        // query for the skills and wrap each one in an
        // instance of the wrapper class to be used in the page
        for (Skill__c skill : [SELECT Id, Name FROM Skill__c]) {
            SkillWrapper sWrapper = new SkillWrapper();
            sWrapper.theSkillRecord = skill;
            sWrapper.proficiencyLevel = ''; // a default selection (blank)
        }
    }

    public List <SelectOption> getItems() {
        List<SelectOption> options = new List<SelectOption> ();
        options.add(new SelectOption('Basic Knowledge', 'Basic Knowledge'));
        options.add(new SelectOption('Intermediate', 'Intermediate'));
        options.add(new SelectOption('Advanced', 'Advanced'));
        return options;
    }

    public void Save() {

        List<Skill_Details__c> skilldetailslist = new List<Skill_Details__c>();

        // loop our wrappers and get the data out of the sObject and the selected value
        for (SkillWrapper sWrapper: skillWrappers) {

            // only do the work if a value was selected
            if (sWrapper.proficiencyLevel != '') {
                Skill_Details__c sd = new Skill_Details__c();
                sd.Skill_c = sWrapper.theSkillRecord.Id;
                sd.Proficiency__c = sWrapper.proficiencyLevel;
                skilldetailslist.add(sd);    
            }

        }
        insert skilldetailslist;
    }
}

VF Page

<apex:page controller="skillproficiencycontroller">
    <apex:form>
        <apex:pageBlock>
            <apex:pageblockTable value="{!skillWrappers}" var="sWrapper">
                <!-- reference the sObject in the wrapper and get its name -->
                <apex:column value="{!sWrapper.theSkillRecord.Name}" />
                <apex:column headerValue="Proficiency">
                    <!-- where we are going to store this row's selected proficiency -->
                    <apex:selectRadio value="{!sWrapper.proficiencyLevel}">
                        <apex:selectOptions value="{!items}" /> 
                    </apex:selectRadio>
                </apex:column>
            </apex:pageblockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>