Render field in pop up with field from row in context

  • 1
  • Question
  • Updated 4 years ago
  • Answered
I have a row action on a contact that creates a pop-up. Within that popup I am creating an account that will house the contact. The new account's name is always "The "last name from the contact row" Family. Is there a way to make this auto-generate each time I click the row action icon?
Photo of Jake Stallman

Jake Stallman

  • 386 Points 250 badge 2x thumb

Posted 4 years ago

  • 1
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
Wait a sec. While on a row of a contact you click on a row action button to display a popup to create an account and contact? How is this to be associated to the original contact? Are these custom Account and Contact objects or the standard? I ask because the standard Salesforce Account and Contact objects require that the Account is created before the Contact.

That's unless you have Person Accounts enabled. Person Accounts are generally only for B2C.
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
Jake,

This is tricky to do, without using JavaScript. Skuid's Action Framework can take care of most of the work, including creating a new Account record whose Name defaults to the LastName of the Contact record in context. But the one place where the Action Framework can't get you yet is in taking the new Account and associating it back to the Contact record in context. What the Action Framework doesn't do well yet (WARNING, gory details ahead!) is allow you to mix and match multiple contexts --- in your scenario, you're creating a new Account row, in context of a Contact. But once you create the new Account, the Account becomes the context row, and the Contact is lost as the context row. For these situations, you need to use a JavaScript snippet to store a reference to the current Contact in context, and then after you've created the new Account, link the Contact back to the new Account. 

I created a basic sample page that will do this for you --- I have a Row Action that is only visible for Contact records with a LastName and without an Account. This Row Action Runs Multiple Actions, one of which is a JavaScript Snippet called "CreateNewAccount", which does the stuff I described above. The other actions are standard, including Show Popup. The Popup has a Save and Cancel button which will save/throw out the new Account as well as Save the changes made to the Contact record (populating the AccountId field).

Here is the page XML:

<skuidpage unsavedchangeswarning="yes" showsidebar="true" showheader="true" tabtooverride="Contact">   <models>
      <model id="Contact" limit="100" query="true" createrowifnonefound="false" sobject="Contact">
         <fields>
            <field id="FirstName"/>
            <field id="LastName"/>
            <field id="CreatedDate"/>
            <field id="AccountId"/>
            <field id="Account.Name"/>
         </fields>
         <conditions/>
         <actions/>
      </model>
      <model id="NewAccountForContact" limit="1" query="false" createrowifnonefound="false" sobject="Account" doclone="" type="">
         <fields>
            <field id="Name"/>
         </fields>
         <conditions/>
         <actions/>
      </model>
   </models>
   <components>
      <pagetitle model="Contact">
         <maintitle>
            <template>{{Model.labelPlural}}</template>
         </maintitle>
         <subtitle>
            <template>Home</template>
         </subtitle>
         <actions/>
      </pagetitle>
      <skootable showconditions="true" showsavecancel="true" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="10" createrecords="true" model="Contact" mode="read">
         <fields>
            <field id="FirstName" allowordering="true"/>
            <field id="LastName" allowordering="true"/>
            <field id="AccountId" valuehalign="" type=""/>
            <field id="CreatedDate" allowordering="true"/>
         </fields>
         <rowactions>
            <action type="edit"/>
            <action type="delete"/>
            <action type="multi" label="Create Account" icon="sk-icon-account-profile">
               <drawer title="Drawer Area" width="800" closehandle="true">
                  <components/>
               </drawer>
               <renderconditions logictype="and">
                  <rendercondition type="blank" operator="=" fieldmodel="Contact" sourcetype="fieldvalue" field="AccountId" value="null" enclosevalueinquotes="false"/>
                  <rendercondition type="blank" operator="!=" fieldmodel="Contact" sourcetype="fieldvalue" field="LastName" value="null" enclosevalueinquotes="false"/>
               </renderconditions>
               <actions>
                  <action type="cancel">
                     <models>
                        <model>NewAccountForContact</model>
                     </models>
                  </action>
                  <action type="custom" snippet="CreateNewAccount"/>
                  <action type="showPopup">
                     <popup title="Create Account for {{FirstName}} {{LastName}}" width="800">
                        <components>
                           <pagetitle model="NewAccountForContact">
                              <maintitle>New Account for Contact</maintitle>
                              <subtitle>
                                 <template>{{Model.label}}</template>
                              </subtitle>
                              <actions>
                                 <action type="multi" label="Save" icon="sk-icon-save">
                                    <actions>
                                       <action type="blockUI" message="Saving..."/>
                                       <action type="save">
                                          <models>
                                             <model>NewAccountForContact</model>
                                          </models>
                                          <onerroractions>
                                             <action type="unblockUI" message="There was an error saving the new Account." timeout="1500"/>
                                          </onerroractions>
                                       </action>
                                       <action type="save">
                                          <models>
                                             <model>Contact</model>
                                          </models>
                                          <onerroractions>
                                             <action type="unblockUI" message="There was an error" timeout="3000"/>
                                          </onerroractions>
                                       </action>
                                       <action type="unblockUI"/>
                                       <action type="closeTopmostPopup"/>
                                    </actions>
                                 </action>
                                 <action type="multi" label="Cancel" icon="sk-icon-cancel">
                                    <actions>
                                       <action type="cancel">
                                          <models>
                                             <model>Contact</model>
                                             <model>NewAccountForContact</model>
                                          </models>
                                       </action>
                                       <action type="closeTopmostPopup"/>
                                    </actions>
                                 </action>
                              </actions>
                              <conditions>
                                 <condition type="contextrow" field="Id" mergefield="Id"/>
                              </conditions>
                           </pagetitle>
                           <basicfieldeditor showheader="true" showsavecancel="false" model="NewAccountForContact" buttonposition="" mode="edit" layout="">
                              <columns>
                                 <column width="50%">
                                    <sections>
                                       <section title="Account Details" collapsible="no">
                                          <fields>
                                             <field id="Name"/>
                                          </fields>
                                       </section>
                                    </sections>
                                 </column>
                                 <column width="50%">
                                    <sections>
                                       <section title="Section B">
                                          <fields/>
                                       </section>
                                    </sections>
                                 </column>
                              </columns>
                              <conditions>
                                 <condition type="contextrow" field="Id" mergefield="Id"/>
                              </conditions>
                           </basicfieldeditor>
                        </components>
                     </popup>
                  </action>
               </actions>
            </action>
         </rowactions>
         <massactions usefirstitemasdefault="true">
            <action type="massupdate"/>
            <action type="massdelete"/>
         </massactions>
         <views>
            <view type="standard"/>
         </views>
      </skootable>
   </components>
   <resources>
      <labels/>
      <css/>
      <javascript>
         <jsitem location="inlinesnippet" name="CreateNewAccount" cachelocation="false">var params = arguments[0],
    contactRow = params.item ? params.item.row : params.row,
    contactModel = params.model,
$ = skuid.$;
// Create our new Account
var NewAccountModel = skuid.model.getModel('NewAccountForContact');
var NewAccount = NewAccountModel.createRow();
NewAccountModel.updateRow(NewAccount,{
   'Name': contactRow.LastName 
});
// Link our Contact to this Account
contactModel.updateRow(contactRow,{
    'AccountId':NewAccount.Id,
    'Account':NewAccount
});
// Return our new Account row as our context
return {
    row: NewAccount    
};
</jsitem>
      </javascript>
   </resources>
</skuidpage>
Photo of Jake Stallman

Jake Stallman

  • 386 Points 250 badge 2x thumb
This solved it.  I only needed the JavaScript portion. Very cool, and very helpful. Thank you very much Zach!

var params = arguments[0],    contactRow = params.item ? params.item.row : params.row,
    contactModel = params.model,
$ = skuid.$;
// Create our new Account
var NewAccountModel = skuid.model.getModel('Leads');
var NewAccount = NewAccountModel.createRow();
NewAccountModel.updateRow(NewAccount,{
   'Name': 'The ' + contactRow.LastName + ' Family'
});
// Link our Contact to this Account
contactModel.updateRow(contactRow,{
    'AccountId':NewAccount.Id,
    'Account':NewAccount
});
// Return our new Account row as our context
return {
    row: NewAccount    
};
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
That's interesting! I was assuming that the Account was a master-detail vs lookup relationship. It's one of those special fields controlled by SF that makes it a required field on their layouts. Not so with Skuid pages though. Very interesting! hmmmm....

Zach, I was totally confused by how you could've answered without answers to my questions.
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
Pat your confusion is understandable --- from standard Contact layouts, Account is indeed "required", but it is not truly required at the database level, so if you have a Skuid page on Contact and don't included the Account field, that's no problem at all, your contacts will save just fine. Not necessarily a good idea, considering all the functionality baked in around Contact-Account relationships, but technically, it's doable.
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
Hey Zach,

Any idea why my page I built crashes? (XML below) The required functionality is there but the page freezes.

Pat
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
Zach I love a good snippet as much as the next guy, but I think this is actually possible more declaratively-ish with a page include inside of the popup that get's the Contact Id as an additional query string parameter,



you can then create a Model on the page include page on the Contact object with a condition that Id = param Id, and Voila! You now have access to the contact in the page include/popup. Now you just have to add actions to save the account model in the page include, close the popup etc. I did that with JS anyway but I think the page include concept is another cool approach.
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
Having a row in context for the contact can be stored in a model and referenced by merging.

I've made a page that does this without javascript, all done with actions. Custom Buttons on Popup that work as intended except for closing topmost popup and then crashing the page everytime.
(Edited)
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
<skuidpage unsavedchangeswarning="yes" showsidebar="true" showheader="true" tabtooverride="Contact">   <models>      <model id="Contact" limit="100" query="true" createrowifnonefound="false" sobject="Contact">
         <fields>
            <field id="FirstName"/>
            <field id="LastName"/>
            <field id="CreatedDate"/>
            <field id="AccountId"/>
            <field id="Account.Name"/>
         </fields>
         <conditions/>
         <actions/>
      </model>
      <model id="NewAccountForContact" limit="1" query="false" createrowifnonefound="false" sobject="Account" doclone="" type="">
         <fields>
            <field id="Name"/>
         <field id="Id"/>
</fields>
         <conditions/>
         <actions>
<action>
   <actions>
      <action type="save">
         <models>
            <model>NewAccountForContact</model>
         </models>
      </action>
      <action type="requeryModel" model="Contact" behavior="standard"/>
   </actions>
   <events>
      <event>models.saved</event>
   </events>
</action>
</actions>
      </model>
   <model id="CurrentContact" limit="1" query="false" createrowifnonefound="false" sobject="Contact" doclone="" type="">
<fields>
   <field id="Id"/>
</fields>
<conditions>
   <condition type="fieldvalue" value="" enclosevalueinquotes="true" field="Id" state="filterableoff" inactive="true" name="Id"/>
</conditions>
<actions/>
</model>
</models>
   <components>
      <pagetitle model="Contact">
         <maintitle>
            <template>{{Model.labelPlural}}</template>
         </maintitle>
         <subtitle>
            <template>Home</template>
         </subtitle>
         <actions/>
      </pagetitle>
      <skootable showconditions="true" showsavecancel="true" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="10" createrecords="true" model="Contact" mode="read">
         <fields>
            <field id="FirstName" allowordering="true"/>
            <field id="LastName" allowordering="true"/>
            <field id="AccountId" valuehalign="" type=""/>
            <field id="CreatedDate" allowordering="true"/>
         </fields>
         <rowactions>
            <action type="edit"/>
            <action type="delete"/>
            <action type="multi" label="Create Account" icon="sk-icon-account-profile">
               <drawer title="Drawer Area" width="800" closehandle="true">
                  <components/>
               </drawer>
               <renderconditions logictype="and">
                  <rendercondition type="blank" operator="=" fieldmodel="Contact" sourcetype="fieldvalue" field="AccountId" value="null" enclosevalueinquotes="false"/>
                  <rendercondition type="blank" operator="!=" fieldmodel="Contact" sourcetype="fieldvalue" field="LastName" value="null" enclosevalueinquotes="false"/>
               </renderconditions>
               <actions>
                  
                  
                  
               <action type="setCondition" model="CurrentContact" condition="Id" value="{{Id}}">
<models>
   <model>CurrentContact</model>
</models>
</action>
<action type="requeryModel" model="CurrentContact" behavior="standard"/>
<action type="createRow" model="NewAccountForContact" appendorprepend="prepend" defaultmodefornewitems="read">
   <defaults>
      <default type="fieldvalue" field="Name" enclosevalueinquotes="true" value="{{LastName}}"/>
   </defaults>
</action>
<action type="showPopup">
                     <popup title="Create Account for {{FirstName}} {{LastName}}" width="800">
                        <components>
<pagetitle model="NewAccountForContact">
   <maintitle>{{Name}}</maintitle>
   <subtitle>
      <template>{{Model.label}}</template>
   </subtitle>
   <actions>
      <action type="multi" label="Save &amp; Close" window="self">
         <actions>
            <action type="updateRow" model="CurrentContact" appendorprepend="prepend" defaultmodefornewitems="edit" fieldmodel="CurrentContact" field="AccountId" enclosevalueinquotes="true" value="{{$Model.NewAccountForContact.data.0.Id}}"/>
            <action type="save" rollbackonanyerror="true">
               <models>
                  <model>NewAccountForContact</model>
                  <model>CurrentContact</model>
               </models>
               <onerroractions>
                  <action type="blockUI" message="There was an error" timeout="3000"/>
               </onerroractions>
            </action>
            <action type="closeAllPopups"/>
         </actions>
      </action>
      <action type="multi" label="Cancel" window="self">
         <actions>
            <action type="markRowsForDeletion" model="NewAccountForContact"/>
            <action type="save">
               <models>
                  <model>NewAccountForContact</model>
               </models>
               <onerroractions>
                  <action type="blockUI" message="There was an error" timeout="3000"/>
               </onerroractions>
            </action>
            <action type="closeTopmostPopup"/>
         </actions>
      </action>
   </actions>
</pagetitle>
<skootable showconditions="true" showsavecancel="false" searchmethod="server" searchbox="false" showexportbuttons="false" pagesize="10" createrecords="false" model="NewAccountForContact" buttonposition="" mode="edit">
   <fields>
      <field id="Name"/>
   </fields>
   <rowactions>
      <action type="edit"/>
      <action type="delete"/>
   </rowactions>
   <massactions usefirstitemasdefault="true"/>
   <views/>
   <searchfields/>
   </skootable>
                           
                           
                        </components>
                     </popup>
                  </action>
</actions>
            </action>
         </rowactions>
         <massactions usefirstitemasdefault="true">
            <action type="massupdate"/>
            <action type="massdelete"/>
         </massactions>
         <views>
            <view type="standard"/>
         </views>
      <searchfields/>
</skootable>
   </components>
   <resources>
      <labels/>
      <css/>
      <javascript>
         
      </javascript>
   </resources>
</skuidpage>
Photo of Jake Stallman

Jake Stallman

  • 386 Points 250 badge 2x thumb
I fell behind on this thread quickly. Thanks Zach, I'm going to play around with what you provided. I've made a work around for associating the contacts to the account created using a wizard. When the account is created on the first step, there is a custom field on accounts "isunassigned" which defaults as checked. The account model is saved when progressing on to step 2 (where the user puts some new information in for the newly created account). On step 2 there is also a field editor which is collapsed for the contacts model, with a filter only allowing accounts where "isunassigned" is true. When the model as a whole is saved at the end of the wizard isunassigned is changed to unchecked.