[SalesForce] Upsert using wrapper class? Products not getting selected after checking the checkbox

I have written the following code to upsert the selected records using Wrapper classes. But I am getting Null Pointer exception . I am not understanding what I have missed. Please suggest. How can I save the records.

    public class DynamicRows
    {
        public List<Product__c> ProductNameList{get;set;}
        public Order__c micOrder{get; set;}
        public String item{get; set;}
        public List<wrapProduct> wrapProductList{get;set;}
        public Boolean selected{get; set;}
        public List<OrderProduct__c> selectedProduct{get;set;}

         public DynamicRows(ApexPages.StandardController controller)
         {
            micOrder = (Order__c)controller.getRecord();
            System.debug('Order Id ' + micOrder.id);
            ProductNameList = new List<Product__c>();
            ProductNameList = [Select Name, Quantity__c, Price__c, Packaging__c from Product__c];
         }

          public void productsSelected() {
            selectedProduct= new List<MiC_OrderProduct__c>();
      wrapProductList = new  List<wrapProduct>();
            for(wrapProduct wrapProductObj : wrapProductList) {
                if(wrapProductObj.selected == true) {
                    System.debug( 'show ' + wrapProductObj.OrderProd.Product__c);
                    selectedProduct.add(wrapProductObj.OrderProd);
                }
            }

            if(!selectedProduct.isEmpty()){
                upsert selectedProduct;
            }

           ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.Info,'Record Saved Successfully.');
           ApexPages.addMessage(myMsg);

        }
         public void checkAll()
        {

          //  for(wrapProduct wrapProductObj : wrapProductList) {
          //      wrapProductObj.selected = true;
               // isrendered = false;
          //  system.debug('exited checkAll');
        }

        public class wrapProduct{
            public OrderProduct__c OrderProd {get; set;}
            public Boolean selected {get; set;}

            public wrapProduct(Product__c prodObj) {
                OrderProd.Product__c = prodObj.Id;
                selected = false;
            }
        }
    }

Page:

<apex:page standardController="Order__c" extensions="DynamicRows"> 
   <apex:form >
      <apex:pageBlock >  
                <apex:pageBlockButtons >
                    <apex:commandButton value="Save Products Selected" action="{!productsSelected}" rerender="table"/>
                </apex:pageBlockButtons>
                <apex:pageBlockTable value="{!ProductNameList}" var="prod">
                 <apex:pageMessages ></apex:pageMessages>
                    <apex:column headerValue="Product">
                        <apex:outputField value="{!prod.Name}"/>
                    </apex:column>
                    <apex:column headerValue="Quantity">
                        <apex:inputField value="{!prod.Quantity__c}"/>
                    </apex:column>    
                    <apex:column headerValue="Price">
                        <apex:inputField value="{!prod.Price__c}"/>
                    </apex:column> 
                    <apex:column headerValue="Packaging">
                        <apex:inputField value="{!prod.Packaging__c}"/>
                    </apex:column>  
              <!--      <apex:column headerValue="Select Product">
                        <apex:inputCheckbox value="{!selected}" id="checkdone"/>
                    </apex:column>  -->
                     <apex:column >
                         <apex:facet name="header">
                              <apex:inputCheckbox onclick="checkAllBoxes(this)"> </apex:inputCheckbox>
                         </apex:facet>
                      <apex:inputCheckbox value="{!selected}" id="checkdone"/> 
                    </apex:column>                      
               </apex:pageBlockTable>
                <apex:actionFunction name="callCheckAllBoxes" action="{!checkAll}" reRender="selected"/>

       </apex:pageBlock>
    </apex:form>
</apex:page>

Best Answer

The code you have posted is a little confusing. Here is the basic structure of how to present a list of objects and to update the selected ones:

public class DynamicRows {

    public List<wrapProduct> wrapProductList{get;set;}

    public DynamicRows(ApexPages.StandardController controller) {
        wrapProductList = new List<wrapProduct>();
        for (Product__c p : [Select Name, Quantity__c, Price__c, Packaging__c from Product__c]) {
            wrapProductList.add(new wrapProduct(p));
        }
    }

    public void productsSelected() {
        List<Product__c> selectedProduct = new List<Product__c>();
        for (wrapProduct wrapProductObj : wrapProductList) {
            if (wrapProductObj.selected) {
                selectedProduct.add(wrapProductObj.OrderProd);
            }
        }
        update selectedProduct;
    }

    public class wrapProduct{
        public OrderProduct__c OrderProd {get; set;}
        public Boolean selected {get; set;}
        public wrapProduct(Product__c prodObj) {
            OrderProd.Product__c = prodObj.Id;
            selected = false;
        }
    }
}

Use this as a starting point. You can modify productsSelected if you want to update some other object (e.g. MiC_OrderProduct__c).