Custom Field Renderer in Mobile Composer?

  • 1
  • Question
  • Updated 4 years ago
Hey team!

Currently having a great time exploring the possibilities with the mobile composer.

We're trying to style the query results of a deck in the mobile composer conditionally (the desired outcome is for a different background colour to be set based on the value in one of the fields in the deck).

Is there any way to achieve this in the current version?

Thank you in advance!

Regards, 

Robin
Photo of Robin

Robin

  • 894 Points 500 badge 2x thumb

Posted 4 years ago

  • 1
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
For sure. You'd create two identical divisions with rendering set on it based on the field you want. Then style each division as needed using a wrapper and add styles to the wrappers.

Hopefully there is an easier way to do this without having to create two sets of identical divisions.

It would be cool if classes could be conditionally set. Then you could just manage the styling with CSS and one layout.
Photo of Robin

Robin

  • 894 Points 500 badge 2x thumb
Hi Pat, 

Thanks for the suggestion! Our use case is about product groups with different items in them, and all the items of the same product group should be displayed with the same background colour. 

Using your method, let's say if we had 10 product groups, we would have to include 10 cloned divisions in the deck with wrappers, and different rendering conditions applied to each of them. Is that correct?

Would be curious if other people have used other workarounds, or if there is an "official" way to hack this.

Much appreciated, 

Robin
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
See. This is how the solution I have is ugly! Works but very very ugly.

I would suggest creating some javascript to insert a class based on the product group. Then it would be very easy to set css to manage the styling. This is certainly possible. Wouldn't take much time to do this.
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
Once the javascript is written, all you would have to manage would be the CSS.

Add a product group, update the CSS. Done.
Photo of Robin

Robin

  • 894 Points 500 badge 2x thumb
Thanks again for clarifying! We have beautiful Javascript for this working in the desktop composer. The mobile composer does not seem to offer me options to apply custom javascript field renderers, just the non-java render conditions. 

Am I missing something obvious here? Being able to use our scripts would solve the problem!
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
There is a location to include javascript. Are you looking to style and/or display input based on product group?
Photo of Robin

Robin

  • 894 Points 500 badge 2x thumb
Ok, got it. Took me a while to catch up. Indeed missed the obvious since I looked for the option on the deck. Thank you Pat for sticking through this :)

Now that I found the option on the FIELD, is there a way to style the background of the DECK the field is in, based on a Javascript renderer I set in the field?

On the desktop page, we were able to set the background colour of the row in a table based on a custom field renderer with field.item.element.addClass('class-name'), field being arguments[0] and the CSS being very specific with

table.nx-skootable-data tbody tr.highlighted-row td {
background-color: lightblue;
}

I would assume that the table and tbody classes won't have an effect on the deck in the mobile page?
Photo of Irvin Waldman

Irvin Waldman, Champion

  • 9,006 Points 5k badge 2x thumb
Hopefully this helps.  Change the custom component JavaScript to use a field in your org.  Note that I am not a jQuery/CSS developer so what I have provided may need to be optimized.

<skuidpage unsavedchangeswarning="yes">
   <models>
      <model id="Account" limit="100" query="true" createrowifnonefound="false" sobject="Account">
         <fields>
            <field id="Name"/>
            <field id="CreatedDate"/>
            <field id="Description"/>
            <field id="AccountNumber"/>
            <field id="helios__Active__c"/>
         </fields>
         <conditions/>
      </model>
   </models>
   <components>
      <skuidmobile>
         <mobilepanels>
            <mobilepanel uniqueid="main" minwidth="400">
               <components>
                  <mobiledeck showsavecancel="false" searchmethod="server" searchbox="true" tokenizesearch="true" createrecords="false" precision="6" minwidth="300" model="Account" mode="read" emptysearchbehavior="query" cssclass="{{#IsPartner}}customCSS{{/IsPartner}}">
                     <components>
                        <mobilefield id="Name"/>
                        <mobilefield id="Description" valuehalign="" type="">
                           <renderconditions logictype="and" onhidedatabehavior="keep"/>
                        </mobilefield>
                        <mobilefield id="AccountNumber" valuehalign="" type="">
                           <renderconditions logictype="and" onhidedatabehavior="keep"/>
                        </mobilefield>
                        <mobilefield id="helios__Active__c" valuehalign="" type="">
                           <renderconditions logictype="and" onhidedatabehavior="keep"/>
                        </mobilefield>
                        <mobilefield id="CreatedDate" valuehalign="" type="">
                           <renderconditions logictype="and" onhidedatabehavior="keep"/>
                        </mobilefield>
                        <custom name="colorCodeDeck">
                           <renderconditions logictype="and"/>
                        </custom>
                     </components>
                     <title>{{Model.labelPlural}}</title>
                     <cardtitle>{{Name}}</cardtitle>
                     <searchfields/>
                     <aftersaveactions/>
                     <renderconditions logictype="and"/>
                  </mobiledeck>
               </components>
            </mobilepanel>
         </mobilepanels>
         <mobilenavs>
            <mobilenav uniqueid="header">
               <components>
                  <mobilegrid precision="6" minwidth="50">
                     <divisions>
                        <division size="1">
                           <components>
                              <mobilebutton label="" style="nav" icon="fa-bars">
                                 <actions>
                                    <action type="setMainPanel" panel="main"/>
                                 </actions>
                              </mobilebutton>
                           </components>
                        </division>
                        <division size="4">
                           <components>
                              <mobiletitle>
                                 <contents>{{$Model.Account.labelPlural}}</contents>
                              </mobiletitle>
                           </components>
                        </division>
                        <division size="1">
                           <components>
                              <mobilebutton label="" style="nav" icon="fa-th">
                                 <actions>
                                    <action type="toggleSetupMenu"/>
                                 </actions>
                              </mobilebutton>
                           </components>
                        </division>
                     </divisions>
                  </mobilegrid>
               </components>
               <interactions>
                  <interaction type="doubletap">
                     <actions>
                        <action type="toggleSetupMenu"/>
                     </actions>
                  </interaction>
                  <interaction type="swipedown">
                     <actions>
                        <action type="toggleSetupMenu"/>
                     </actions>
                  </interaction>
               </interactions>
            </mobilenav>
         </mobilenavs>
      </skuidmobile>
   </components>
   <resources>
      <labels/>
      <css/>
      <javascript>
         <jsitem location="inlinecomponent" name="colorCodeDeck" cachelocation="false" url="">
var element = arguments[0],
    component = arguments[2],
    $ = skuid.$;

var row = component.context.item.row;
var isActive = row.helios__Active__c == 'Yes' ? true : false;
console.log(isActive);
if (isActive) {
    component.context.item.element.find('div.sm-card-body').css( "background", "lightblue" );
} else {
    component.context.item.element.find('div.sm-card-body').css( "background", "pink" );
}</jsitem>
      </javascript>
   </resources>
</skuidpage>
(Edited)
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
Class is in session! Professor Waldman making it look easy.

Going to use this myself.
Photo of Robin

Robin

  • 894 Points 500 badge 2x thumb
Hi Pat and Irvin, 

Thank you so much for the contribution! I was actually able to make it work, however not using component and component.context as in Irvin's example (those would just come up as undefined).

The guidance regarding the .find and then setting the .css directly was what got me on the right tack. It renders beautifully and for our use case is more appropriate than cloning divisions, however will use Pat's solution in scenarios with fewer variables. 

Here is my working code, saved as Resource Javascript Snippet (Inline), and then assigned as custom field renderer to the field I want to evaluate in the deck I want to colour in:

var field = arguments[0],   
value = arguments[1],
    $ = skuid.$;
var csspath = field.item.element;
var Pro1 = "Awesome Product Name";
var Pro2 = "Best Product Ever";

if (value != null) {
   
if (~value.indexOf(Pro1)) {
    field.element.text(value);
csspath.find('div.sm-card-inner').css( "background", "#B6CCFF" );

else if (~value.indexOf(Pro2)) {
    field.element.text(value);
csspath.find('div.sm-card-inner').css( "background", "orange" );
} else {
    field.element.text(value);
csspath.find('div.sm-card-inner').css( "background", "#1390CD" );   
}
}

Will consider using French doors and bulldogs for inspiration in the next project since that definitely got the job done! #insidejoke

Very grateful for this community, 

Robin
(Edited)