[SalesForce] How to dynamically add row between two rows in vf page

How to add the new rows dynamically in the middle of existing rows in visualforce page.

enter image description here

My rows will like this shown in image. I can delete the rows where ever i want, but new rows are added in end of the row. I need to add the new rows b/w the rows.

Page:

<apex:pageblock>
    <apex:pageMessages id="pgm"/>
    <apex:variable var="rowNum" value="{!0}"/>
    <apex:pageblockTable value="{!lstWrapper}" var="a" rows="{!rows}" >
        <apex:column headerValue="Fields" >
            <apex:SelectList value="{!a.strField}" size="1" onchange="RefreshFilter1();" >
                <apex:selectOptions value="{!Fields}" />
            </apex:SelectList>
        </apex:column>
        <apex:column headerValue="Operator" >
            <apex:selectList value="{!a.strOperator}" multiselect="false" size="1" >
                <apex:selectOptions value="{!OperatorsOptions}" />                
            </apex:selectList>
        </apex:column>
        <apex:column headerValue="Value" >
            <apex:inputText id="value1" value="{!a.strFilterValue}" />
        </apex:column>
        <apex:column headervalue="Condition" >
            <apex:selectlist value="{!a.strANDORCompare}" size="1">
                <apex:selectOptions value="{!ANDOROptions}" />
            </apex:selectlist>
        </apex:column>
        <apex:column >
           <apex:commandButton id="cmdAdd" value="+" action="{!addRows}" reRender="out1"/>
            <apex:commandButton id="cmdRmv" value="-" action="{!rmvRows}" reRender="out1" rendered="{!rowNum>0}">
                <apex:param name="rowIndex" value="{!rowNum}" />
            </apex:commandButton>
            <apex:variable var="rowNum" value="{!rowNum+1}"/>
        </apex:column>  
    </apex:pageblockTable>
</apex:pageBlock>

Controller:

public with sharing class RowsController{
    public integer rows                                     { get; set; }
    public List<CustomListViewFilterWrapper> lstWrapper     { get; set; }
    public List<ADI_Decision__c> lstDecision                { get; set; }
    public Integer rowNum                                   { get; set; }
    List<SelectOption> lstFieldOptions = new List<SelectOption>();
    List<SelectOption> lstOperatorOptions = new List<SelectOption>();   
    List<SelectOption> lstAndOROptions = new List<SelectOption>();  
    string selField = '';
    string selOperator = '';
    string selFilterValue = '';
    string selAndOrOption = '';

    public RowsController() {
        lstDecision = new List<ADI_Decision__c>();    
        lstWrapper = new List<CustomListViewFilterWrapper>();
        rows = 3;        
        getFields();
        getOperatorsOptions();
        getANDOROptions();
        filterRows();
    }
    public void filterRows(){
        for(integer i=1;i<4;i++){
            selField = 'null';selOperator = 'null'; selFilterValue = ''; 
            objDecision1 = new ADI_Decision__c();
            CustomListViewFilterWrapper objWrapper = new CustomListViewFilterWrapper(rows,selField,selOperator,selFilterValue,'AND',objDecision1);
            lstWrapper.add(objWrapper);
        }
    }
    public void addRows(){
        rows = rows + 1;
        CustomListViewFilterWrapper objWrapper = new CustomListViewFilterWrapper(rows,selField,selOperator,selFilterValue,'AND',objDecision1);
        lstWrapper.add(objWrapper);
    }
    public void rmvRows(){
        rowNum = Integer.valueOf(ApexPages.currentPage().getParameters().get('rowIndex'));
        lstWrapper.remove(rowNum);
    }
    public class CustomListViewFilterWrapper{
        public integer rowCount             { get; set; }
        public string strField              { get; set; }
        public string strOperator           { get; set; }
        public string strANDORCompare       { get; set; }
        public string strFilterValue        { get; set; }
        public ADI_Decision__c objDecision  { get; set; }

        public CustomListViewFilterWrapper(integer i,string str1,string str2,string str3,string str4,ADI_Decision__c act1){
             this.rowCount = i;
             this.strField = str1;
             this.strOperator = str2;
             this.strFilterValue = str3;
             this.strANDORCompare = 'and';
             this.objDecision = act1;
        }
    }
}

Best Answer

I tried to find a method to insert into the middle of the list but got no luck. So I manually implemented it... Here is the code which should work for you:

In Page:

    <apex:commandButton id="cmdAdd" value="+" action="{!addRows}" reRender="out1"/>
        <apex:param name="rowIndex" value="{!rowNum}" />
    </apex:commandButton>

Controller:

    public void addRows(){
        rows = rows + 1;
        rowNum = Integer.valueOf(ApexPages.currentPage().getParameters().get('rowIndex'));
        CustomListViewFilterWrapper objWrapper = new CustomListViewFilterWrapper(rows,selField,selOperator,selFilterValue,'AND',objDecision1);
        //lstWrapper.add(objWrapper);
        List<CustomListViewFilterWrapper> newList = new List<CustomListViewFilterWrapper>();
        for(Integer i = 0; i < rowNum; i++) {
            newList.add(lstWrapper[i]);
        }
        newList.add(objWrapper);
        for(Integer i = rowNum; i < lstWrapper.size(); i++) {
            newList.add(lstWrapper[i]);
        }
        lstWrapper = newList;
    }