+ Start a Discussion
mgodseymgodsey 

Passing picklist value to controller

I'm trying to build a Visualforce page where as soon as a picklist value is selected/changed, the value is passed to a method in the controller to be used in a dynamic SOQL query. However, I'm having trouble getting the value passed to the controller. I've used this blog post as a starting point, http://blog.jeffdouglas.com/2010/07/13/building-a-dynamic-search-page-in-visualforce/, but I need to use apex:inputField instead because I need to keep the dependent pick lists intact.

When I change the value of TestInventoryType__c I get the alert that the doSearch() function is called, but my second alert comes back null. I would really appreciate if someone could tell me why this is coming back null, and if there is a better way to do this. How could I go about binding the value selected in the Inventory Type picklist to a property in the controller? I need all of this to happen when the picklist value changes without hitting any sort of command button. Thank you!

Here is a snippet of the VF page. The two most relevant lines are bolded:

  <apex:pageBlock title="MANAGE MEDIA PLAN FLIGHTS" mode="edit">


  <table width="100%" border="0">

  <tr>

    <td width="275" valign="top">

      <!-------This is the Search by picklist section-------------------------->

      <apex:pageBlock title="Search" mode="edit" id="criteria">



      <script type="text/javascript">

      function doSearch() {

        alert('doSearch function');

        alert(document.getElementById("creativeFamily")); //THIS COME BACK NULL

            searchServer(

            document.getElementById("creativeFamily").options[document.getElementById("creativeFamily").selectedIndex].value,

            document.getElementById("creativeTypes").options[document.getElementById("creativeTypes").selectedIndex].value,

            document.getElementById("pricingModel").options[document.getElementById("pricingModel").selectedIndex].value,

            document.getElementById("targetingOption").options[document.getElementById("targetingOption").selectedIndex].value

        );

       
      }

      </script>

     <apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors">

          <apex:param name="creativeFamily" value="" />

          <apex:param name="creativeTypes" value="" />

          <apex:param name="pricingModel" value="" />

          <apex:param name="targetingOption" value="" />

      </apex:actionFunction>


     <apex:pageBlockSection columns="1">

         <apex:inputField value="{!Quote.TestInventoryType__c}" id="creativeFamily" onchange="doSearch();"/>
Damien Phillippi033905702927186443Damien Phillippi033905702927186443
You should be binding your data directly to the controller, not trying to pass it with an action function instead.  It simplifies things so much.  Your scenario you are giving doesn't require the apex:param
mgodseymgodsey
Hi - thank you so much for taking a look at this! Unfortunately I'm really new to Visualforce and controllers. How do I bind the data directly to the controller? I assume I would need properties in the controller that can be set with the string values, but I'm a bit lost on how I set that value from the page.

Code snippets from my class:

public with sharing class quoteLineItemEntryExtensionOption5 {
   
    public Quote theQuote {get;set;}
    public Pricebook2 theBook {get;set;}
    public String toSelect{get;set;}
    public List<QuoteLineItem> shoppingCart {get;set;}
    public String CreativeFamily {get;set;}
    public String MediaType {get;set;}
    public String TargetingOptions {get;set;}
    public String PricingModel {get;set;}


//the soql without the order and limit
    private String soql {get;set;}

// runs the search with parameters passed from the page
    public PageReference runSearch() { 

        soql = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.Segment__c, Product2.CreativeType__c, Product2.CreativeFamily__c, Product2.PricingModel__c, Product2.TargetingOptions__c, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and CurrencyISOCode = \'' + theBook.CurrencyISOCode + '\' and Pricebook2Id = \'' + theBook.Id + '\'';

        if (!CreativeFamily.equals(''))
            soql += ' and Product2.CreativeFamily__c LIKE \''+CreativeFamily+'%\'';
        if (!MediaType.equals(''))
            soql += ' and Product2.CreativeType__c LIKE \''+MediaType+'%\'';
        if (!PricingModel.equals(''))
            soql += ' and Product2.pricingModel__c LIKE \''+PricingModel+'%\'';
        if (!TargetingOptions.equals(''))
            soql += ' and Product2.TargetingOptions__c LIKE \''+TargetingOptions+'%\'';

        // run the query again
        System.debug('[MF] running the query from runSearch method' + soql);
        runQuery();

        return null;
    }
mgodseymgodsey
update - I was reading the Visualforce developers guide and it said that " Any setter methods in a controller are automatically executed before any action methods."

So I tried using the above code in my controller, and changing my VF page to following (just a snippet): 

<apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors"/>

<apex:pageBlockSection columns="1">
     <apex:inputField value="{!Quote.TestInventoryType__c}" id="creativeFamily" onchange="searchServer();"/>

However, when I test it I get a null pointer exception:
System.NullPointerException: Attempt to de-reference a null object
Error is in expression '{!runSearch}' in page quotelineitementryoption5

Class.quoteLineItemEntryExtensionOption5.runSearch: line 110, column 1



Line 110 of the controller is if (!CreativeFamily.equals(''), which makes the think the property is not actually getting set. Is this because I'm not saving the record? I don't actually want their selections to save though. They just need to update the SOQL query.
Damien Phillippi033905702927186443Damien Phillippi033905702927186443
Sorry for the long update.  These new boards don't notify me if you respond....  Using apex:inputField or apex:inputText allows you to bind data directly from your page to your controller.  I'm guessing that error is because the values you are using in that query are still null at the point it reaches there.
mgodseymgodsey
No worries, thank you for following up! And yes, that's what I think too, with the issue being that the field values aren't actually saved before running the query.

I ended up using "document.querySelector("[id$='inventoryType']").options[document.querySelector("[id$='inventoryType']").selectedIndex].value," and this was able to get the selected picklist value.