-1

I am trying to pass a query written by the user, if the user does not provide a query I want to run a default query by default.

I cannot get this to work, no matter what it runs the default query.

public class exampleRemote {

public string mapQuery {get;set;}
public String remQuery = 'SELECT Id, MailingState FROM Contact WHERE MailingState != null';
public static PageReference getQuery() {

    PageReference pageRef = ApexPages.currentPage();
    return pageRef;

}


@RemoteAction
public static List<Contact> getContacts(String remQuery) {

    List<Contact> contactList = Database.query(remQuery);
    return contactList;

}
}
2
+200
Public string queryToUse {get;set;}

    public void detrmineQuery() {

        QueryToUse = string.isblank(userQuery) ? Defaultquery : userquery;

    }

On your page when the button is clicked have it call determinQuery as the action

Set the button rerender to "scriptBlock" and oncomplete = the js method to do remote action

<apex:outputpanel id="scriptBlock">
<script>
var theQuery = "{!queryToUse}";
</script>
</apex:outputpanel>

The use the js var theQuery to pass into the remote action as a param

Basically using a button to set the value of the property then updating the JS var with current value and pass it to the remote action

If you are interested and want a complete working example leave a comment

Not sure why you are going remote action. You could query in controller and serialize the results and use that as well

  • 1
    No worries. Just glad I could help. Keep in mind all the security concerns mentioned by others and expose with caution – Eric Apr 26 '17 at 21:17
2

Here is a similar question which might help give you context: Access variables in @Remoteaction

What it boils down to is that your RemoteAction fires in an entirely separate transaction than your controller setter. You cannot maintain state across transactions just because you declare the variable static.

The simplest, most secure way to implement the requested feature (based on your comments) is to modify method to accept either a List<String>, or a delimited list. Here is how the remote method itself would look:

@RemoteAction
public static List<Contact> getContacts(List<String> states)
{
    return [SELECT ... FROM Contact WHERE MailingState IN :states];
}

// OR

@RemoteAction
public static List<Contact> getContacts(String delimitedStates)
{
    if (delimitedStates == null)
    {
        return [SELECT ... FROM Contact WHERE MailingState != null];
    }
    return [SELECT ... FROM Contact WHERE MailingState IN :delimitedStates.split(';')];
}

You could use a different delimiter than semicolon (;), that's just how multi-select picklists are delimited, making it a common choice. From a UI perspective, it might be easier to put a rich text field up on the front end and then use a newline (\n) delimiter instead. However you go with the UI, though, your Javascript would have the capacity to split the input into an array of states and call the first signature listed above.


If you must allow specification of a dynamic query, you just need to pass the query string as a parameter:

@RemoteAction
public static List<Contact> getContacts(String soql)
{
    return Database.query(soql);
}

Note, however, that you can just use the AJAX Toolkit at that point and eliminate Apex entirely:

<apex:includeScript value="/soap/ajax/39.0/connection.js"/>
<script>
    (function (connection) {
        "use strict";
        connection.sessionId='{!GETSESSIONID()}';
        var getContacts = function () {
            // add as an event listener somewhere
            var queryInput = document.getElementById("queryInput"),
                soql = queryInput.value;
            return connection.query(soql);
        };
    })(sforce.connection);
</script>
1

You are using a remote action to get the contacts. The remote action knows nothing about your page's view state and so getQuery is basically invisible to your getContacts method. You need to pass the query to your getContacts method to get this to work, like so: getContacts(String query)

1

In case you want to avoid Javascript, here's a simple example using only Visualforce and Apex. Miles away from being safe for production use, but it does exactly (and only) what you're asking for.

Page:

<apex:page controller='TestController' >

    <apex:pageBlock title="Query">      
        <apex:form>
            <apex:inputText value="{!query}" size="200" />
            <apex:commandButton action="{!getContacts}" value="Get Contacts" />
        </apex:form>    
    </apex:pageBlock>

    <apex:pageBlock title="Results">    
        <apex:outputText value="{!query}" />        
        <apex:pageBlockTable value="{!contacts}" var="item">        
            <apex:column headerValue="Id" value="{!item.Id}" />
            <apex:column headerValue="MailingState" value="{!item.MailingState}" />        
        </apex:pageBlockTable>        
    </apex:pageBlock>

</apex:page>

Controller:

public class TestController {    
    public List<Contact> contacts {get; set;}
    public String query {get; set;}

    public TestController(){
        this.contacts = new List<Contact>();
    }

    public void getContacts(){    
        contacts = (String.isBlank(query)) ? [SELECT Id, MailingState FROM Contact WHERE MailingState != null] : Database.query(query);
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.