Conditions not applied properly on clone pages

  • 2
  • Problem
  • Updated 4 years ago
  • Acknowledged
  • (Edited)
In developing a clone page, we are encountering a couple of issues, both of which are rather difficult to describe so instead I provide a sample page (using SkuidCRM) that replicates the issue.  Please note that the design of this sample page doesn't have any real world applicability, it's main purpose is to replicate what we're doing in our real page by applying the same concepts.  The SkuidCRM example just gives me the ability to reduce surface area for the actual repro of the problems.

Steps to repro:

1) Add page below to SkuidCRM org
2) Using preview button on page (make sure to add clone=1 to URL manually) or setup skuid to use this page to clone an account
3) Pick an account to clone - based on model conditions you must be the owner of the account for the account to display.  This condition is required to demonstrate the issues below

Actual Result
1) Owner ID field is empty

Expected Result
2) Owner ID field should contain name of logged in user

Note - If you remove the lookup filter on Owner ID field, then Owner ID will display the proper value.  As mentioned above, this particular lookup filter makes no sense in the real world but it is consistent with the type of filter we need in our application.

Looking underneath the covers, here is what is going on:

1) Because this is a "clone" page, each recordin each model is being cloned even though we really only want AccountData to be cloned
2) Since the "Id" of UserData model is "clone_#", the lookup condition fails
skuid.model.getModel('UserData').getFirstRow().Id == 'clone_1"
3) Even if you change the model condition from using (UserData)(Id) to a hardcoded string value of the ID of the user (e.g. "00540000002LeH4AAK"), Owner ID on the page is still empty.  You can see this in action on the 2nd sample page below (HardCoded Approach), just make sure to update the model condition value for OwnerId field to the ID of your user.
skuid.model.getModel('AccountData').getFirstRow().OwnerId = ""

Questions:
1) Is there a way to force Skuid to not "clone" a model even if the URL paramater contains "clone=1"?  In short, if I could find a way to only clone specific models, I think this would work around the above.
2) Short of #1, I tried some workarounds to replicate something similar to hardcoding a value.  Basically, create a formula field that exposes the ID of a record in a location where skuid won't change it due to cloning.  Unfortunately, as described in #3 above, this approach won't work because even though the UserData model Id field isn't used, the lookup ID field in AccountData (OwnerID) is still blank - This seems very odd btw.  I can explain why it's blank in the first page below (because Id is getting a value of clone_#) but can't quite explain why the 2nd page isn't working as expected.

I have a more realistic repro available if you are interested.  Thank you!!

Dynamic Approach
<skuidpage showsidebar="false" showheader="true" tabtooverride="Account">   <models>
      <model id="UserData" limit="100" query="true" createrowifnonefound="false" sobject="User">
         <fields>
            <field id="Id"/>
            <field id="Name"/>
         </fields>
         <conditions>
            <condition type="userinfo" value="" field="Id" operator="=" enclosevalueinquotes="true" userinfotype="userid"/>
         </conditions>
      </model>
      <model id="AccountData" limit="1" query="true" createrowifnonefound="false" sobject="Account">
         <fields>
            <field id="Name"/>
            <field id="CreatedDate"/>
            <field id="AccountNumber"/>
            <field id="CreatedById"/>
            <field id="CreatedBy.Name"/>
            <field id="OwnerId"/>
            <field id="Owner.Name"/>
            <field id="ParentId"/>
            <field id="Parent.Name"/>
            <field id="Id"/>
         </fields>
         <conditions>
            <condition type="param" operator="=" field="Id" value="Id" mergefield="Id" enclosevalueinquotes="true"/>
            <condition type="modelmerge" value="" field="OwnerId" operator="=" model="UserData" enclosevalueinquotes="true" mergefield="Id" novaluebehavior="noquery"/>
         </conditions>
      </model>
      <model id="OriginalAccount" limit="1" query="true" createrowifnonefound="false" sobject="Account">
         <fields>
            <field id="Name"/>
         </fields>
         <conditions>
            <condition type="param" value="id" field="Id" operator="=" enclosevalueinquotes="true"/>
         </conditions>
      </model>
   </models>
   <components>
      <pagetitle model="OriginalAccount">
         <maintitle>New {{Model.Label}}</maintitle>
         <subtitle>(Cloned from {{{Name}}})</subtitle>
         <actions>
            <action type="savecancel" label="New Action" afterSave=" /{{Id}}" afterCancel="/{{$Param.id}}" window="self">
               <models>
                  <model>AccountData</model>
                  <model>Contact</model>
                  <model>Opportunities</model>
                  <model>Cases</model>
               </models>
            </action>
         </actions>
      </pagetitle>
      <basicfieldeditor showsavecancel="false" showheader="true" model="AccountData" mode="edit">
         <columns>
            <column width="100%">
               <sections>
                  <section title="General Info">
                     <fields>
                        <field id="Name"/>
                        <field id="ParentId">
                           <label>Parent Account</label>
                        </field>
                        <field id="OwnerId">
                           <filters>
                              <filter type="dependent" operator="=" field="Id" value="" enclosevalueinquotes="true" depfield="OwnerId"/>
                           </filters>
                        </field>
                     </fields>
                  </section>
               </sections>
            </column>
         </columns>
      </basicfieldeditor>
   </components>
   <resources>
      <labels/>
      <css/>
      <javascript/>
   </resources>
</skuidpage>



Hardcoded Approach
<skuidpage showsidebar="false" showheader="true" tabtooverride="Account">   <models>
      <model id="UserData" limit="100" query="true" createrowifnonefound="false" sobject="User">
         <fields>
            <field id="Id"/>
            <field id="Name"/>
         </fields>
         <conditions>
            <condition type="userinfo" value="" field="Id" operator="=" enclosevalueinquotes="true" userinfotype="userid"/>
         </conditions>
      </model>
      <model id="AccountData" limit="1" query="true" createrowifnonefound="false" sobject="Account">
         <fields>
            <field id="Name"/>
            <field id="CreatedDate"/>
            <field id="AccountNumber"/>
            <field id="CreatedById"/>
            <field id="CreatedBy.Name"/>
            <field id="OwnerId"/>
            <field id="Owner.Name"/>
            <field id="ParentId"/>
            <field id="Parent.Name"/>
            <field id="Id"/>
         </fields>
         <conditions>
            <condition type="param" operator="=" field="Id" value="Id" mergefield="Id" enclosevalueinquotes="true"/>
            <condition type="fieldvalue" value="00540000002LeH4AAK" enclosevalueinquotes="true" field="OwnerId"/>
         </conditions>
      </model>
      <model id="OriginalAccount" limit="1" query="true" createrowifnonefound="false" sobject="Account">
         <fields>
            <field id="Name"/>
         </fields>
         <conditions>
            <condition type="param" value="id" field="Id" operator="=" enclosevalueinquotes="true"/>
         </conditions>
      </model>
   </models>
   <components>
      <pagetitle model="OriginalAccount">
         <maintitle>New {{Model.Label}}</maintitle>
         <subtitle>(Cloned from {{{Name}}})</subtitle>
         <actions>
            <action type="savecancel" label="New Action" afterSave=" /{{Id}}" afterCancel="/{{$Param.id}}" window="self">
               <models>
                  <model>AccountData</model>
                  <model>Contact</model>
                  <model>Opportunities</model>
                  <model>Cases</model>
               </models>
            </action>
         </actions>
      </pagetitle>
      <basicfieldeditor showsavecancel="false" showheader="true" model="AccountData" mode="edit">
         <columns>
            <column width="100%">
               <sections>
                  <section title="General Info">
                     <fields>
                        <field id="Name"/>
                        <field id="ParentId">
                           <label>Parent Account</label>
                        </field>
                        <field id="OwnerId">
                           <filters>
                              <filter type="dependent" operator="=" field="Id" value="" depfield="OwnerId" mergefield="Id" novaluebehavior="deactivate" enclosevalueinquotes="true"/>
                           </filters>
                        </field>
                     </fields>
                  </section>
               </sections>
            </column>
         </columns>
      </basicfieldeditor>
   </components>
   <resources>
      <labels/>
      <css/>
      <javascript/>
   </resources>
</skuidpage>






Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb

Posted 4 years ago

  • 2
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
Hi Barry,

There is currently no way to force Skuid to not clone a particular Model --- if the Model is on the page, it will be cloned.

We are aware that this is an issue, and are considering adding a "Clone data in Model on Page Load" property that will explicitly mark a Model as needing to be cloned or not, and so that you do not have to have the "clone=1" parameter present in order to initiate cloning of Models.

It's possible that this will get in to the Summer 14 release.

Zach
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb
Hey Zach -

Thanks for the info and quick response.  Kind of assumed there wasn't a way to do this today but very glad to hear it's being considered for upcoming release and possibly even Summer '14.

Regarding the workaround that I'm attempting (see hardcoded approach from original post), can you provide some insight as to why this isn't working?  

What appears to be happening is that Skuid is identifying that there is a model on the client with a record of the same SObject type and same ID and using that to set the default value instead of just using the string value in the model condition.  If I can figure this out, I can implement a workaround until the "Clone data in Model on Page Load" feature is available.

Thanks!


Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb
Hi All -

Looking for some guidance on why the workaround I attempted in #2 above doesn't behave the way I would expect it to.  I hope I'm just overlooking something simple :)

In the "Hardcoded Approach", the OwnerID condition on the AccountData model is hardcoded to a known User Id.  However, when cloned, the OwnerId field becomes empty even though it was hardcoded to use a specific value.  Another interesting point of reference is that the Owner property contains the Id & Name that I would expect so it's only that for some reason the OwnerID is not getting the value that was specified in the condition.

I've created an smaller repro of "Hardcoded Approach" from above below.  To reproduce, copy/paste in to SkuidCRM org and hit the URL making sure to add clone=1 to URL.

Can someone shed some light on this please?

<skuidpage showsidebar="false" showheader="true" tabtooverride="Account">   <models>
      <model id="AccountData" limit="1" query="true" createrowifnonefound="false" sobject="Account">
         <fields>
            <field id="Name"/>
            <field id="CreatedDate"/>
            <field id="AccountNumber"/>
            <field id="CreatedById"/>
            <field id="CreatedBy.Name"/>
            <field id="OwnerId"/>
            <field id="Owner.Name"/>
            <field id="ParentId"/>
            <field id="Parent.Name"/>
            <field id="Id"/>
         </fields>
         <conditions>
            <condition type="param" operator="=" field="Id" value="Id" mergefield="Id" enclosevalueinquotes="true"/>
            <condition type="fieldvalue" value="00540000002LeH4AAK" enclosevalueinquotes="true" field="OwnerId"/>
         </conditions>
      </model>
   </models>
   <components>
      <basicfieldeditor showsavecancel="false" showheader="true" model="AccountData" mode="edit">
         <columns>
            <column width="100%">
               <sections>
                  <section title="General Info">
                     <fields>
                        <field id="Name"/>
                        <field id="ParentId">
                           <label>Parent Account</label>
                        </field>
                        <field id="OwnerId">
                           <filters>
                              <filter type="dependent" operator="=" field="Id" value="" depfield="OwnerId" mergefield="Id" novaluebehavior="deactivate" enclosevalueinquotes="true"/>
                           </filters>
                        </field>
                     </fields>
                  </section>
               </sections>
            </column>
         </columns>
      </basicfieldeditor>
   </components>
   <resources>
      <labels/>
      <css/>
      <javascript/>
   </resources>
</skuidpage>
Thanks!
Photo of Emily Davis

Emily Davis, Employee

  • 3,502 Points 3k badge 2x thumb
Hi, Barry,
For your lookup filter, try changing the "Depends On" field to Owner.Id (go through the Owner related field to get the Id specifically from the User object). Remember to add this to your model as well! This will pass in a particular Id string rather than an object, which your lookup filter should be able to match with the field Id. This should cause your Owner field value to show up and save correctly!
Emily
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb
Hello Emily -

Thank you for the reply!  The approach you outlined worked just as you described :)  Unfortunately, it leads me back to my original issue from the post so we're not through the woods yet :(  

The challenge that I'm having is when I add another model to the page that contains a row that matches the OwnerId.  In this case, the OwnerId on the Account gets set to a value of "clone_#".  For some reason, skuid is using the value of the Id from the row in the other model instead of the hardcoded value of the Id itself.  Since OwnerId on the AccountData row gets set to "clone_#" the page won't save because OwnerId is an invalid reference.

Below is a page that is based on the page from my most recent post but mirrors the behavior I was describing in my original post on by proposed workaround and question #2.  I took the page from my most recent post and modified it as follows:

1) Changed the lookup filter to Owner.Id
2) Added Owner.Id to the AccountData model
3) Added a new model "User" that has a condition on Id to the same hardcoded value that AccountData does for OwnerId.  Note that in my real-world scenario I wouldn't have a hardcoded value and instead would be using Id from UserInfo.  The hardcoding is intended only to make it a little clearer as to what value I expect in the new row's AccountData.OwnerId

If I remove the "User" model, all works, however I need it to work with the 2nd model to align with the scenario I'm developing against.

Is there a viable workaround for this?

<skuidpage showsidebar="false" showheader="true" tabtooverride="Account">   <models>
      <model id="User" limit="100" query="true" createrowifnonefound="false" sobject="User">
         <fields/>
         <conditions>
            <condition type="fieldvalue" value="00540000002LeH4AAK" enclosevalueinquotes="true" field="Id"/>
         </conditions>
      </model>
      <model id="AccountData" limit="1" query="true" createrowifnonefound="false" sobject="Account">
         <fields>
            <field id="Name"/>
            <field id="CreatedDate"/>
            <field id="AccountNumber"/>
            <field id="CreatedById"/>
            <field id="CreatedBy.Name"/>
            <field id="OwnerId"/>
            <field id="Owner.Name"/>
            <field id="ParentId"/>
            <field id="Parent.Name"/>
            <field id="Id"/>
            <field id="Owner.Id"/>
         </fields>
         <conditions>
            <condition type="param" operator="=" field="Id" value="Id" mergefield="Id" enclosevalueinquotes="true"/>
            <condition type="fieldvalue" value="00540000002LeH4AAK" enclosevalueinquotes="true" field="OwnerId"/>
         </conditions>
      </model>
   </models>
   <components>
      <pagetitle model="AccountData">
         <maintitle>
            <template>{{Name}}</template>
         </maintitle>
         <subtitle>
            <template>{{Model.label}}</template>
         </subtitle>
         <actions>
            <action type="savecancel" window="self"/>
         </actions>
      </pagetitle>
      <basicfieldeditor showsavecancel="false" showheader="true" model="AccountData" mode="edit">
         <columns>
            <column width="100%">
               <sections>
                  <section title="General Info">
                     <fields>
                        <field id="Name"/>
                        <field id="ParentId">
                           <label>Parent Account</label>
                        </field>
                        <field id="OwnerId">
                           <filters>
                              <filter type="dependent" operator="=" field="Id" value="" depfield="Owner.Id" mergefield="Id" novaluebehavior="deactivate" enclosevalueinquotes="true"/>
                           </filters>
                        </field>
                     </fields>
                  </section>
               </sections>
            </column>
         </columns>
      </basicfieldeditor>
   </components>
   <resources>
      <labels/>
      <css/>
      <javascript/>
   </resources>
</skuidpage>