2

Autocomplete feature is working great but when there are two Contact blocks and when I try to search for contact then it updates both Contact blocks.How do I make sure it updates only the block that I searched on. AutoComplete

<apex:page Controller="AutoCompleteController" sidebar="false" showHeader="false">

    <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/themes/smoothness/jquery-ui.css" />
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.min.js"></script>
    <apex:remoteObjects >
      <apex:remoteObjectModel name="Contact" fields="Id,Name,Email,Phone"/>
    </apex:remoteObjects>


      <script>
       function autocompleteonfocus(){
        var selectedId = null;

           $('input[id$=conName],input[id$=conEmail],input[id$=conPhone]').autocomplete({ 
            minLength: 2,
            delay: 500,
            source: function( request, response ) {
                var ContactRO = new SObjectModel.Contact();
                ContactRO.retrieve({where: {Name: {like: request.term + "%" }}}, function(err, records, event) {
                    if (err) {
                        alert(err);
                    } else {
                        var result = [];
                        records.forEach(function(record) {
                           result.push( { 
                               label: record.get("Name"),
                               value: record.get("Id"),
                               Name : record.get("Name"),
                               Email: record.get("Email"),
                               Phone: record.get("Phone"),
                           });
                        });
                        response(result);
                    }
                });
            },
            select: function(event, ui) {        
                event.preventDefault();

                 $('input[id$=conEmail]').val(ui.item.Email);
                 $('input[id$=conName]').val(ui.item.Name);
                 $('input[id$=conPhone]').val(ui.item.Phone); 
                selectedId = ui.item.value;
            },


        });

        }


    </script> 

        <apex:form >
              <div style="margin-left: 5%; margin-right: 5%;margin-top: 5%;"> 
                 <apex:outputPanel id="cPanel">
                   <apex:variable value="{!0}" var="cnt" />
                   <apex:repeat value="{!conList}" var="con" id="conRepeatId">
                               Name:
                                <apex:inputText value="{!con.Name}" id="conName"  onfocus="autocompleteonfocus();"/>
                               <br/>
                               Email :
                                <apex:inputText value="{!con.Email}"  id="conEmail"  onfocus="autocompleteonfocus();" />
                               <br/>
                                 Phone Number:
                                 <apex:inputText value="{!con.Phone}" id="conPhone"  onfocus="autocompleteonfocus();"/>
                                <br/>
                        <apex:outputPanel rendered="{!IF(cnt>0,true,false)}">
                                <apex:commandButton value="Remove" action="{!removeContact}" immediate="true" rerender="cPanel">
                                    <apex:param name="index" value="{!cnt}" />
                                </apex:commandButton> <br/>
                        </apex:outputPanel> 
                     <apex:variable var="cnt" value="{!cnt+1}" />
                   </apex:repeat>
                  </apex:outputPanel> 
                   <apex:commandButton value="Add Contact" action="{!addContact}"  rerender="cPanel" /> 
                </div>
            </apex:form>
    </apex:page>

public class AutoCompleteController {
 public list<Contact> conList {get;set;}  

   public  AutoCompleteController(){
        conList = new list<Contact>();
        Contact c = new Contact();
        conList.add(c);
   }

    public void addContact() { 
        Contact c = new Contact();
        conList.add(c);
    }

    public void removeContact(){
        Integer indexVal = Integer.valueof(system.currentpagereference().getparameters().get('index'));
        conList.remove(indexVal - 1);   
    }

}

2 Answers 2

4

This is not really a SFDC question, but I’ll tackle it anyway.

On your JavaScript, your return code searches for the controls to update by using the jQuery selector $ (as in id$=“conName”). This matches all controls that end with the specified string.

Because you have the controls within an ‘apex:repeat’, both of your boxes end with the same string, and are therefore both found and updated by jQuery when searching.

I recommend that you either change the names to make them unique, or use a different selector field (perhaps a class, or attribute, instead of the I’d) to find the proper set of controls to update.

==Update==

Per your request, one of several ways to make an Id unique is by appending something unique to it. I will using an ID, but you could use a number.

<apex:inputText value="{!con.Name}" id="conName_{!con.id}" styleClass="autocomplete" onfocus="autocompleteonfocus();"/>

On your jQuery, you'd change the selectors you use to attach so instead of

$('input[id$=conName],input[id$=conEmail],input[id$=conPhone]').autocomplete({

you would get something like

$('.autocomplete').autocomplete({

And then, obviously, you'd change the edit lines to something different. From:

$('input[id$=conEmail]')

to

$('input[id$=conEmail_*<yourIdHere>*]')

8
  • Thank you. How do i make names as unique or IDs as unique in apex:repeat and refer those IDs in Jquery.Can you please post sample example
    – sfdc
    May 25, 2018 at 15:46
  • Thank you when I try to update Id <apex:inputText value="{!con.Name}" id="conName_{!con.id}" onfocus="autocompleteonfocus();" styleClass="autocomplete" /> then I am getting Save error: Literal value is required for attribute id in <apex:inputText>
    – sfdc
    May 25, 2018 at 16:30
  • try {!'conName_' + con.id} May 25, 2018 at 16:31
  • If that doesn't work, then use something other than Id... like a data- attribute May 25, 2018 at 16:31
  • 1
    Can’t do that with id. Just put it in the styleclass and use the class selector
    – Eric
    May 25, 2018 at 23:26
0

Thank you Sebastian Kessel and Eric. Used styleclass and class selector and here is my working vf page.

    <apex:page Controller="AutoCompleteController" sidebar="false" showHeader="false">

<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.min.js"></script>
<apex:remoteObjects >
  <apex:remoteObjectModel name="Contact" fields="Id,Name,Email,Phone"/>
</apex:remoteObjects>


  <script>
   function autocompleteonfocus(row){
    var selectedId = null;
       $('input[id$=conName],input[id$=conEmail],input[id$=conPhone]').autocomplete({ 
        minLength: 2,
        delay: 500,
        source: function( request, response ) {
            var ContactRO = new SObjectModel.Contact();
            ContactRO.retrieve({where: {Name: {like: request.term + "%" }}}, function(err, records, event) {
                if (err) {
                    alert(err);
                } else {
                    var result = [];
                    records.forEach(function(record) {
                       result.push( { 
                           label: record.get("Name"),
                           value: record.get("Id"),
                           Name : record.get("Name"),
                           Email: record.get("Email"),
                           Phone: record.get("Phone"),
                       });
                    });
                    response(result);
                }
            });
        },
        select: function(event, ui) {        
            event.preventDefault();

             $(".conEmail"+row).val(ui.item.Email);
             $(".conName"+row).val(ui.item.Name);
             $(".conPhone"+row).val(ui.item.Phone); 
            selectedId = ui.item.value;
        },


    });

    }


</script> 

    <apex:form >
          <div style="margin-left: 5%; margin-right: 5%;margin-top: 5%;"> 

               <apex:outputPanel id="cPanel">
               <apex:variable value="{!1}" var="rowNum"/>
               <apex:variable value="{!0}" var="cnt" />
               <apex:repeat value="{!conList}" var="con" id="conRepeatId">

                        Name:
                            <apex:inputText value="{!con.Name}"  id="conName"  onfocus="autocompleteonfocus('{!rowNum}');" styleClass="conName{!rowNum}"/>
                           <br/>
                           Email :
                            <apex:inputText value="{!con.Email}"  id="conEmail"  onfocus="autocompleteonfocus('{!rowNum}');" styleClass="conEmail{!rowNum}"/>
                           <br/>
                             Phone Number:
                             <apex:inputText value="{!con.Phone}" id="conPhone"  onfocus="autocompleteonfocus('{!rowNum}');" styleClass="conPhone{!rowNum}"/>
                            <br/>
                    <apex:outputPanel rendered="{!IF(cnt>0,true,false)}">
                            <apex:commandButton value="Remove" action="{!removeContact}" immediate="true" rerender="cPanel">
                                <apex:param name="index" value="{!cnt}" />
                            </apex:commandButton> <br/>
                    </apex:outputPanel>
                     <apex:variable var="rowNum" value="{!rowNum + 1}"/>
                 <apex:variable var="cnt" value="{!cnt+1}" />
               </apex:repeat>
              </apex:outputPanel> 
               <apex:commandButton value="Add Contact" action="{!addContact}"  rerender="cPanel" /> 
            </div>
        </apex:form>
</apex:page>

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .