Opening a drawer seems to re-render other opened drawers and changes are lost

  • 1
  • Problem
  • Updated 3 years ago
  • (Edited)
Here are the steps to reproduce.  Sample page XML at the end.  

Note 1: Just using standard objects and fields; nothing really special.
Note 2: Model query uses Merge/New


Click to open drawer




Get list of opportunities.  Edit the amount and/or stage fields.






Click to open another drawer. Notice the prior edits are lost.





Page XML

<skuidpage unsavedchangeswarning="yes" showsidebar="false" showheader="true" tabtooverride="Account">   <models>
      <model id="Account" limit="100" query="true" createrowifnonefound="false" sobject="Account">
         <fields>
            <field id="Name"/>
            <field id="CreatedDate"/>
            <field id="AccountNumber"/>
            <field id="Type"/>
            <field id="Id"/>
         </fields>
         <conditions>
            <condition type="join" value="" field="Id" operator="in" enclosevalueinquotes="true" joinobject="Opportunity" joinfield="AccountId">
               <conditions/>
            </condition>
         </conditions>
         <actions/>
      </model>
      <model id="Opportunities" limit="20" query="true" createrowifnonefound="false" sobject="Opportunity">
         <fields>
            <field id="Amount"/>
            <field id="IsClosed"/>
            <field id="AccountId"/>
            <field id="Account.Name"/>
            <field id="Name"/>
            <field id="StageName"/>
            <field id="IsWon"/>
         </fields>
         <conditions>
            <condition type="fieldvalue" value="true" enclosevalueinquotes="true" field="AccountId" state="filterableoff" inactive="true" name="AccountId"/>
         </conditions>
         <actions/>
      </model>
   </models>
   <components>
      <pagetitle model="Account">
         <maintitle>
            <template>{{Model.labelPlural}}</template>
         </maintitle>
         <subtitle>
            <template>Home</template>
         </subtitle>
         <actions>
            <action type="savecancel" window="self">
               <models>
                  <model>Opportunities</model>
               </models>
            </action>
         </actions>
      </pagetitle>
      <skootable showconditions="true" showsavecancel="false" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="10" createrecords="false" model="Account" mode="readonly">
         <fields>
            <field id="Name" allowordering="true"/>
            <field id="CreatedDate" allowordering="true"/>
         </fields>
         <rowactions>
            <action type="multi" label="View Opportunities" icon="fa-chevron-right">
               <actions>
                  <action type="setCondition" model="Opportunities" behavior="loadmore" condition="AccountId" value="{{Id}}"/>
                  <action type="requeryModel" model="Opportunities" behavior="loadmore">
                     <models>
                        <model>Opportunities</model>
                     </models>
                  </action>
                  <action type="drawer" openicon="fa-chevron-down">
                     <drawer title="Drawer Area" width="90%" closehandle="true">
                        <components>
                           <template multiple="true" model="Opportunities" allowhtml="true">
                              <contents>&lt;strong&gt;{{Model.LabelPlural}}&lt;/strong&gt;</contents>
                           </template>
                           <skootable showconditions="true" showsavecancel="false" searchmethod="server" searchbox="false" showexportbuttons="false" pagesize="10" createrecords="false" model="Opportunities" buttonposition="" mode="edit" emptysearchbehavior="query">
                              <fields>
                                 <field id="Name" valuehalign="" type="" readonly="true"/>
                                 <field id="Amount" decimalplaces="" valuehalign="" type=""/>
                                 <field id="StageName" valuehalign="" type=""/>
                              </fields>
                              <rowactions/>
                              <massactions usefirstitemasdefault="true"/>
                              <views>
                                 <view type="standard"/>
                              </views>
                              <conditions>
                                 <condition type="contextrow" field="Account.Id" mergefield="Id"/>
                              </conditions>
                              <searchfields/>
                           </skootable>
                        </components>
                     </drawer>
                  </action>
               </actions>
            </action>
         </rowactions>
         <massactions usefirstitemasdefault="true"/>
         <views>
            <view type="standard"/>
         </views>
      </skootable>
   </components>
   <resources>
      <labels/>
      <css/>
      <javascript/>
   </resources>
</skuidpage>
Photo of Irvin Waldman

Irvin Waldman, Champion

  • 9,006 Points 5k badge 2x thumb

Posted 3 years ago

  • 1
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
I believe you've got the query more on the opps in the wrong spot. You've got it on the row action, whereas it ought to be on drawer properties "Before Load Actions".
Photo of Irvin Waldman

Irvin Waldman, Champion

  • 9,006 Points 5k badge 2x thumb
Re-worked the page so that (1) changes Multiple Actions to Drawer, (2) set condition and query model on Before Load Actions.

Still the same result.

{{Model.labelPlural}}

Home

Opportunities

<strong>{{Model.plurallabel}}</strong>
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb
Hey Irvin - I haven't had time to look at your sample closely but here's my thinking based on a similar scenario I've encountered.  When you invoke an action to Requery Model using "Get More", Skuid automatically cancels changes in that model prior to getting the additional data.  In other words, you can't slipstream in new data without losing your edits.  You can mimick this by directly calling updateData on the model.  If you do, you'll get an exception.  To avoid that, the "get more action" cancels changes before calling updateData.  Unfortunately, the only work around I've come up with thus far is a snippet that works along the lines of:

1) Check model for the row needed based on Id
2) If it's there, you're all set
3) If it's not there, then have another model, set its condition, query it and then adopt the row back in to the model that you want "editable"

It's been discussed in the past to offer a "get more if not already there" so that situations like yours (and mine and likely some others) can get data on demand and allow edits to data already retrieved.  +1 for that feature! :)
Photo of Irvin Waldman

Irvin Waldman, Champion

  • 9,006 Points 5k badge 2x thumb
Hi, You'v e confirmed my intuition. In my case it would be adopting row(s). :(

There is another workaround... load the data on page load instead of the Before Load Actions. While this is less than ideal and could be problematic for obvious reasons, it would work for me.

Thanks Barry.

+1
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb
No problem Irvin, sounds like you are in the same camp as me.  I forgot about the load all data on page load situation.  It was the path we went down originally but our page loads were taking way to long.  Our models have 150+ fields on them and there are lots of records involved so loading on demand is critical for us (and it sounds like you as well).

One other solution would be in your action sequence, check if the model is dirty and don't open the drawer until the user saves.  Less than ideal of course but would technically work.

Skuid Team - A couple of thoughts along these lines:

1) Would really like to see a "get more if not already there" action added.  Skuid offers incredible benefit with very rich pages - but with rich pages comes lots of data to marshal over the wire.  Loading on-demand in to a dirty model would solve for this.
2) For the automatic "cancel" in the requery getmore action, might be worthwhile to just let this fail with an exception when calling updateModel instead of automatically cancelling changes (or at least console.log).  The automatic cancel of changes is not obvious where as an exception would be that could be caught during testing.  
3) The work around to use a separate model functions as needed.  That said, it can't be used declaritively and requires a snippet that is specific to that scenario.  It's been talked about in the past but this would be another time when being able to define "custom actions" (similar to custom components) and use the in builder would drive a ton of value for page developers.

Thanks!
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
I just confirmed the same behaviour. I've got the same setup with a table in a drawer and it's changes get wiped when opening another drawer.