[SalesForce] Get data on commandbutton click from pageblocktable

I have this below code where i am parsing json response and displaying it in pageblocktable. I have a button on each row. When clicked it is calling a method. I want when clicked, it should pass the row data to that method.

Basically i am trying to get the data (tittle, author) when add button is clicked in that row.
Apex class –

public class BooksJson {
    public List<Items> items {get;set;} 

    public class Items {
    public VolumeInfo volumeInfo {get;set;}
  }

      public class VolumeInfo { 
            public String title {get;set;} 
            public String subtitle {get;set;} 
            public List<String> authors {get;set;} 
            public String description {get;set;}
            public List<IndustryIdentifiers> industryIdentifiers {get;set;}
            public ImageLinks imageLinks {get;set;}
        }

    public class IndustryIdentifiers {
        public String type_Z {get;set;} // in json: type
        public String identifier {get;set;}
    }

    public class ImageLinks {
        public String smallThumbnail {get;set;} 
        public String thumbnail {get;set;}
    }


}




public class Callout {

    public list<BooksJson.items> returnResultList { get;set; }
    public String searchText { get; set; }
    public String author { get; set; }
    public String isbn { get; set; }
    public String tittle { get; set; }

    public void search() {
        if(searchText != null) {
            bookSearch(searchText);

        }
    }

    public pagereference addBook() {

        return null;
    }

    Public void Search(String searchText){

            HTTPresult = response.getBody();
            BooksJson result = (BooksJson)JSON.deserialize(HTTPresult ,BooksJson.class);
            For(BooksJson.items g :result.items) {
                count++;
                returnResultList.add(g);
            }

        } else if (response.getStatusCode() == 500) {
        } else {
        }
    }
}

Vf Page –

<apex:page controller="Callout" sidebar="false">

    <apex:form id="form">
        <center>
            <div class="SearchDiv">
                <apex:inputText value="{!searchText}" >
                <apex:commandButton action="{!search}" value="search" reRender="form"/>
            </div>
        </center>
        <apex:variable value="{!0}" var="index" />
        <apex:pageBlock id="searchRes" rendered="{!returnResultList != null}">
            <apex:pageBlockTable value="{!returnResultList}" var="res">
                <apex:column headerValue="slNo">
                    <apex:outputText >
                        <apex:variable value="{!index + 1}" var="index" />
                        {!index}
                    </apex:outputText>
                </apex:column>
                <apex:column value="{!res.volumeinfo.title}" headerValue="Title" />
                <apex:column value="{!res.volumeinfo.authors}" headerValue="Author" />
                <apex:column headerValue="Action">
                    <apex:commandButton action="{!addBook}" value="Add">
                        <apex:param assignTo="{!tittle}" name="tittle" id="tittle" value="{!res.volumeinfo.title}"/>
                        <apex:param assignTo="{!author}" name="Author" id="author" value="{!res.volumeinfo.authors}"/>
                    </apex:commandButton>
                </apex:column>
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>

</apex:page>

Best Answer

Use this logic, to pass index as rowNumber to the controller method and from the index, you can easily get the row data.

Also, use proper rerender attribute in button.

Visualforce

<apex:page controller="Callout" sidebar="false">
    <apex:form id="form">
        <center>
            <div class="SearchDiv">
                <apex:inputText value="{!searchText}" >
                <apex:commandButton action="{!search}" value="search" reRender="form"/>
            </div>
        </center>
        <apex:variable var="rowNum" value="{!0}"/>
        <apex:pageBlock id="searchRes" rendered="{!returnResultList != null}">
            <apex:pageBlockTable value="{!returnResultList}" var="res">
                <apex:column headerValue="slNo">
                    <apex:outputText >                        
                        {!rowNum}
                    </apex:outputText>
                </apex:column>
                <apex:column value="{!res.volumeinfo.title}" headerValue="Title" />
                <apex:column value="{!res.volumeinfo.authors}" headerValue="Author" />
                <apex:column headerValue="Action">
                    <apex:commandButton action="{!addBook}" value="Add" reRender="form">
                        <apex:param assignTo="{!tittle}" name="tittle" id="tittle" value="{!res.volumeinfo.title}"/>
                        <apex:param assignTo="{!author}" name="Author" id="author" value="{!res.volumeinfo.authors}"/>
                        <apex:param value="{!rowNum}" name="index"/>
                    </apex:commandButton>
                </apex:column>
                <apex:variable var="rowNum" value="{!rowNum+1}"/>
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>

</apex:page>

Controller

public pagereference addBook() {
    Integer rowNum = Integer.valueOf(apexpages.currentpage().getparameters().get('index'));
    return null;
}