14

I have a force:inputField field on my lightning component acting as a lookup. It is working fine:

<force:inputField aura:id="segmentid" value="{!v.campaign.Survey__c}"/>
<ui:button press="{!c.selectSurvey}">Add Survey</ui:button>

The controller looks up the record information, displays it on the page, and then the callback should clear the force:inputField so the user can add another record. This is what I have tried:

var forceChange = cmp.get("v.campaign");
forceChange.Survey__c = ""  ;
cmp.set("v.campaign", forceChange);

I have also tried clearing/setting the v.value and v.text of the object but that doesnt seem to work:

cmp.find("segmentid").set("v.value", "");
cmp.find("segmentid").set("v.text", "");

Out of desperation I tried to force a refresh on both methods to no effect:

$A.get('e.force:refreshView').fire();

I'm out of ideas but I need this to work.

  • what is the type of your campaign attribute? – Itai Shmida Sep 24 '17 at 6:26
  • @ItaiShmida it's a custom sobject: <aura:attribute name="campaign" type="Proof_Campaign__c" default="{ 'sobjectType': 'Proof_Campaign__c' }" access="public"/> – Ross Bassett Sep 25 '17 at 16:00
  • Try cmp.set ("v.campaign", ""); – Itai Shmida Sep 25 '17 at 16:06
  • @ItaiShmida yeah that doesnt work either :( – Ross Bassett Sep 28 '17 at 20:15
  • As a workaround what if you simply set the value of v.campaign.Survey__c to null? Since it is bound to it then it should clear the value from the input as well. – Eric Sep 28 '17 at 20:49
7
+25

Theoretically it should be possible to clear values on force:inputField. But in your specific case it seems not to work as expected. force:inputField is a smart field component operating on different field types differently. For bound plain text fields the reset works while for lookups attribute updates are not rendered correctly.

Known Weakpoints

There are lots of posts here and elsewhere indicating that force:inputField has several flaws. I personally tried it about two years ago an then gave up on it. In the meantime however it looks improved a bit. But I would definitely suggest to use it carefully.

The way you are using cmp.get() and set() looks correct. But my experience with Lightning is: even small typos might end up to a ignored-behaviour with no errors so debugging is a challenge.

Also the Lightning Component Roadmap shows two planned components lightning:inputField and lightning:lookup. Now my interpretations of that is, that Salesforce is aware of the limitations of the current force:inputField and is working on a successor.

Issue Isolation

I would start to isolate the issue and extract it out of your given scenario into a new puristic test compo using only stanard objects, like Contact with the AccountId lookup. Then you'll have short code to post here in full length (as @crmprogdev suggested) and at the same time ruled out a bunch of possible side effects.

I've tried this already, but the results aren't looking very promising (see below). Therefore I would recommend to search for solutions without force:inputField.

Alternatives

Instead of force:inputField you could try to:

I haven't tested the these examples yet.

My attempts using force:inputField

I've played around a bit using that markup

<aura:component controller="elfUHForceInputFields" implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global">       
    <aura:attribute name="recordId" type="Id" default="" />
    <aura:attribute name="Contact" type="Contact" default="{ 'sobjectType': 'Contact' }" />
    <force:inputField value="{!v.Contact.FirstName}" />
    <force:inputField value="{!v.Contact.Salutation}" />
    <force:inputField value="{!v.Contact.AccountId}" />
    <lightning:button variant="brand" label="do it" onclick="{! c.onClick }" />         
</aura:component>

With this Apex invoked in an init-handler and the result assigned to v.Contact

public class elfUHForceInputFields {
    @AuraEnabled public static Contact load(String id) {
        return Database.query( xs.soql('select *, Account.* from Contact where Id= :id') );
    }
}

My observations are

  • force:inputField bound to text fields like FirstName get populated
  • force:inputField bound to Salutation (picklist) gets populated
  • ui:input bound to Account.Name gets populated
  • force:inputField bound to AccountId (lookup) doesn't get populated

But you can use the UI to pick an Account:

  • Rendering looks ok.
  • attribute v.Contact.AccountId gets updated correctly!

Now back to you scenario in an onclick-handler after manually populating the Account lookup:

  • cmp.set('v.Contact.FirstName','test') updates the attribute and the UI
  • cmp.set('v.Contact.AccountId',null) updates the attribute but doesn't update the UI
  • same goes for setting the entire Contact.AccountId to null ==> no UI update

This inconsistent behavior looks like a bug and verifies your observation.

My idea to work around it was to dynamically create the force:inputField using $A.createComponent() in a handler and then destroy and recreate the inputField when you need to clear it.

https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_cb_dynamic_cmp_async.htm

I've tried this

   $A.createComponent(
        "force:inputField",
        {
            "value"  : cmp.getReference("v.Contact.FirstName"),
        },
        function(newCmp, status, errorMessage){
            //Add the new button to the body array
            if (status === "SUCCESS") {
                var body = cmp.get("v.body");
                body.push(newCmp);
                cmp.set("v.body", body);
            }
            else if (status === "INCOMPLETE") {
                console.log("No response from server or client is offline.")
                // Show offline error
            }
            else if (status === "ERROR") {
                console.log("Error: " + errorMessage);
                // Show error message
            }
        }
    );

Unfortunately this only brings up:

Error: An internal server error has occurred Error ID: 1690735821-95785 (-1543061012)

Conclusion

I looks like you have to implement your own lookup compo to get what you need. Possibly it's worth to test the W18 update for improvements.

| improve this answer | |
  • Great post. I ended up placing the force:inputField in a component by itself and dynamically creating/refreshing it from a container. Even though this worked I found other weirdness with it. For example force:inputField will not refresh/render if its nested in a <div>. – Ross Bassett Oct 9 '17 at 18:10
2

After toying with force:inputField a bit, I found the following code to clear it's value.

// Clear binded value
var contractLine = component.get('v.contractLine');
contractLine.Product__c = null;
contractLine.Product__r = {'sobjectType': 'Product2'};
component.set('v.contractLine', contractLine);    

// Clear product lookup
var productLookup = component.find('Product').get('v.body')[0];
productLookup.updateValues();
| improve this answer | |

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.