0

I'm replicating the "New Task" page, with "Log Activity" branding instead of "Log a Call" & removing the extra "Follow-up Task" section.

As part of the standard behavior, the polymorphic WhoId field is included. When the type of this field is changed to "Prospect", from "Contact", the WhatId field is disabled.

It looks like this behavior is included on the visualforce page, but whenever I change the type, this error shows up in the log:

Uncaught DOMException: Failed to execute 'querySelector' on 'Document': '[secid=j_id0:j_id2:j_id3:j_id5:WhoId_mlbtn]' is not a valid selector.
    at Function.LookupAutoCompleteInputElement.handleLookupTypeChange (https://c.cs14.visual.force.com/jslibrary/1521492146000/sfdc/main.js:1888:12)
    at HTMLSelectElement.onchange (https://c.cs14.visual.force.com/apex/NewTask?who_id=00Qc000000AM49a&core.apexpages.request.devconsole=1:114:1648)
LookupAutoCompleteInputElement.handleLookupTypeChange @ main.js:formatted:30259
onchange @ NewTask?who_id=00Qc000000AM49a&core.apexpages.request.devconsole=1:114

Specifically, [secid=j_id0:j_id2:j_id3:j_id5:WhoId_mlbtn] seems to be the bit thats failing to execute properly. Problem is, this is standard code, out of my reach. I tried adding my own event listener, but it fails to run, probably since this one fails first.

Running document.getElementById('j_id0:j_id2:j_id3:j_id5:WhoId_mlbtn'); gets me the element I need, but trying to use a query selector fails. According to the document.querySelector documentation, : is a non-standard css id value (which infuritates me that salesforce used a character that doesn't work out of the box with the spec), meaning it needs to be escaped (//:) in order to work properly. This requires me to modify the onchange attribute, which feels super brittle.

Looking at the standard page, the onchange functions look like this:

LookupAutoCompleteInputElement.handleLookupTypeChange('tsk2',false);ActivityFunction.adjwht('tsk2_mlktp');Sfdc.Activity.ManyWhoFunction.flipManyWhoContactField(); 

The Id in this context is 'tsk2', which does not contain invalid characters, and is fetchable using document.querySelector.

I also tried using html-id to override the provided id, but this is explicitly disallowed.

Are there any other solutions? Has anyone else encounter this before?

0

At first I tried replacing the ids with css compatible ids, but this caused problems with other functions that referenced these fields. Then, I tried modifying theonchange attribute to escape the invalid characters, but that caused some problems too.

Turns out, if you provide a actionSupport under the input, it actually replaces the standard onchange function. Taking advantage of this let me write code to replace the functionality & add more.

Heres the section with these inputs on my page:

<apex:pageBlockSection title="Task Information" collapsible="false" columns="2">

    <apex:inputField value="{!Task.OwnerId}" />

    <Apex:pageBlockSectionItem id="WhatId">
        <apex:outputLabel value="Related To" />
        <apex:inputField value="{!Task.WhatId}" />
    </Apex:pageBlockSectionItem>

    <apex:inputField value="{!Task.Subject}" required="true" />

    <!-- On Change of WhoId, fetch - Email, Phone, and rerender section below to update values -->
    <Apex:pageBlockSectionItem >
        <Apex:outputLabel value="Name" />
        <apex:actionRegion >
            <apex:inputField id="WhoId" value="{!Task.WhoId}">
                <apex:actionSupport event="onchange" reRender="ExtraInfo,WhatId" action="{!UpdateWho}" immediate="true" oncomplete="CheckType('{!$Component.WhoId}');" >
                </apex:actionSupport>
                <script>
                    function CheckType(i) {
                        var typeInput = document.getElementById(i + '_mlktp');
                        var whatIdInputs = document.querySelectorAll('[id^="{!$Component.WhatId}"]');  
                        var whatIdLookupWindow = document.querySelector('[id^="{!$Component.WhatId}"] a'); 

                        if (typeInput.value == '00Q') {
                            whatIdInputs.forEach(function(v, i, l){
                                v.disabled = true;    
                            });

                            whatIdLookupWindow.style.display = 'none'; 
                        } else {
                            whatIdInputs.forEach(function(v, i, l){
                                v.disabled = false;    
                            });

                            whatIdLookupWindow.style.display = 'inline'; 
                        }
                    }
                </script>
            </apex:inputField>
        </apex:actionRegion>
    </Apex:pageBlockSectionItem>


    <apex:inputField value="{!Task.ActivityDate}" />
    <apex:pageBlockSectionItem />

    <apex:inputField required="true" html-colspan="2" value="{!Task.Description}" style="width: 80%;" />

</apex:pageBlockSection>  

The actionSupport here calls over to the controller, and sets the Who variable, which the ExtraInfo section uses to display the Phone & Email of the selected lead or contact. It uses the oncomplete attribute to call a javascript function to check the type of the _mlktp sub-input, which houses the select list with the object types. Based on this value, we select the WhatId inputs, and the nearby lookup window element, and either enable or disable these elements.

We end up with the same functionality as the standard page, but now our extra info section rerenders & updates as the user chooses options.

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.