<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tech Vision &#8211; Salesforce Best Practices</title>
	<atom:link href="https://www.tech-vision.us/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.tech-vision.us/</link>
	<description>Salesforce consultancy.</description>
	<lastBuildDate>Sat, 28 Oct 2023 20:29:06 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>
	<item>
		<title>Salesforce &#124; Inbound Webhook Integration Guide</title>
		<link>https://www.tech-vision.us/salesforce-inbound-webhook-integration-guide/</link>
					<comments>https://www.tech-vision.us/salesforce-inbound-webhook-integration-guide/#comments</comments>
		
		<dc:creator><![CDATA[Oleksandr Makarenko]]></dc:creator>
		<pubDate>Sat, 28 Oct 2023 17:21:29 +0000</pubDate>
				<category><![CDATA[Salesforce]]></category>
		<guid isPermaLink="false">https://www.tech-vision.us/?p=13971</guid>

					<description><![CDATA[<p>Hi everyone! In this post I'd like to walk you through the configurations needed to integrate a third party service with Salesforce by using webhooks. There are plenty similar articles out there. However, when I tried to do it myself I had to collect information from different sites in order to get it to work.  [...]</p>
<p>The post <a href="https://www.tech-vision.us/salesforce-inbound-webhook-integration-guide/">Salesforce | Inbound Webhook Integration Guide</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Hi everyone! In this post I&#8217;d like to walk you through the configurations needed to integrate a third party service with Salesforce by using webhooks. There are plenty similar articles out there. However, when I tried to do it myself I had to collect information from different sites in order to get it to work.</p>



<p class="wp-block-paragraph">Hopefully in this guide I&#8217;ll be able to provide everything you need to process inbound webhook in Salesforce.</p>



<p class="wp-block-paragraph">So webhooks (also called a web to callback or HTTP push API) are typically used to provide real-time information to other applications such as Salesforce. A webhook delivers data as it happens so you get immediate access to it. </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Please note that webhook integration is a fire &amp; forget type of integration. It does not require any kind of authentication. Make sure it fits your security standards &amp; consider potential risks. You definitely don&#8217;t want to have a public URL that returns a list of contacts upon request. But a function that makes updates internally may be just fine. I understand that not every service offers more secure integration type such as oAuth 2.0, but please take your time to think through data security.</p>



<p class="wp-block-paragraph"></p>
</blockquote>



<p class="wp-block-paragraph">For example:</p>



<ul class="wp-block-list">
<li>You use marketing tools outside of CRM and someone clicked the link from your email campaign. You&#8217;d like to record this event as activity on lead/contact in Salesforce.</li>



<li>You have a web-form on your website pages. When someone submits the form you&#8217;d like to create a lead in Salesforce.</li>



<li>You get the point&#8230;</li>
</ul>



<p class="wp-block-paragraph">Essentially it is a JSON that contains event information that is sent to another application. In our case it&#8217;s Salesforce.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"> There are two main components to this process:</p>



<ol class="wp-block-list">
<li>Configure Salesforce to process third party notifications.</li>



<li>Configure third-party service to send event notifications.</li>
</ol>
</blockquote>



<p class="wp-block-paragraph">Alright, I think we are ready to get started. You&#8217;ll need &#8216;System Administrator&#8217; access in Salesforce as well as admin account in third-party service you&#8217;re integrating.</p>



<h2 class="wp-block-heading">Step 1: Configure Public Site URL</h2>



<p class="wp-block-paragraph">In order to get this to work, we need to do register public URL. This URL will be used to push updates to Salesforce.</p>



<p class="wp-block-paragraph">Go to Setup -&gt; Sites</p>



<p class="wp-block-paragraph">If it&#8217;s your first time configuring sites then it is likely that you&#8217;ll see the following notice:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="1404" height="542" src="https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-register-sites-domain.png" alt="" class="wp-image-13974" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-register-sites-domain-200x77.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-register-sites-domain-300x116.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-register-sites-domain-400x154.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-register-sites-domain-600x232.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-register-sites-domain-768x296.png 768w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-register-sites-domain-800x309.png 800w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-register-sites-domain-1024x395.png 1024w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-register-sites-domain-1200x463.png 1200w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-register-sites-domain.png 1404w" sizes="(max-width: 1404px) 100vw, 1404px" /></figure>
</div>


<p class="wp-block-paragraph">Go ahead and accept Salesforce terms of use and click &#8216;<code>Register My Salesforce Site Domain</code>&#8216;.</p>



<p class="wp-block-paragraph">Press &#8216;New&#8217; to add new site:</p>



<p class="wp-block-paragraph"></p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1040" height="321" src="https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-button.png" alt="" class="wp-image-13975" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-button-200x62.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-button-300x93.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-button-400x123.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-button-600x185.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-button-768x237.png 768w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-button-800x247.png 800w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-button-1024x316.png 1024w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-button.png 1040w" sizes="(max-width: 1040px) 100vw, 1040px" /></figure>
</div>


<p class="wp-block-paragraph">Set site configurations as follows:</p>



<figure class="wp-block-table"><table><tbody><tr><td>Site Label</td><td>Webhooks</td></tr><tr><td>Site Contact</td><td><em>doesn&#8217;t matter</em></td></tr><tr><td>Default Record Owner</td><td><em>doesn&#8217;t matter</em></td></tr><tr><td>Default Web Address</td><td>webhooks</td></tr><tr><td>Active</td><td><strong>True</strong></td></tr><tr><td>Active Site Home Page</td><td>SiteLogin (No one is actually will be able to login)</td></tr><tr><td>Clickjack protection level</td><td><em>pick most secure</em></td></tr></tbody></table><figcaption class="wp-element-caption">All the rest checkboxes can be de-selected.</figcaption></figure>



<p class="wp-block-paragraph">Overall, take a look at the screenshot below for site settings.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="722" height="801" src="https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-configurations.png" alt="" class="wp-image-13979" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-configurations-200x222.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-configurations-270x300.png 270w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-configurations-400x444.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-configurations-600x666.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-new-site-configurations.png 722w" sizes="(max-width: 722px) 100vw, 722px" /></figure>
</div>


<p class="wp-block-paragraph">I&#8217;m not sure if you can tell from the screenshot. But my SF developer org base site URL is: <br>https://dev-ed.my.salesforce-sites.com. </p>



<p class="wp-block-paragraph">We just created site page with <code>/webhooks</code> add-on. </p>



<p class="wp-block-paragraph">This means our full site URL for webhooks is <br>https://dev-ed.my.salesforce-sites.com/webhooks.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Please note, that this &#8216;/webhooks&#8217; site can be used for many webhook integrations from different services. It is not limited to just one integration. Therefore you don&#8217;t need to create a separate site for each webhook. Later in this guide I&#8217;ll walk you through on how integrations are separated by having different URLs.</p>
</blockquote>



<p class="wp-block-paragraph">So for now, we are good with site configurations. We&#8217;ll come back to it once we configure other things.</p>



<h2 class="wp-block-heading">Step 2: Configure REST Resource In Apex</h2>



<p class="wp-block-paragraph">Let&#8217;s create an apex class to process incoming callouts. This is will be our main place to process JSON data that is sent from external service.</p>



<p class="wp-block-paragraph">Go ahead and create first apex class that is: WebhookListner</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="" style="font-size:.875rem;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Apex</span><span role="button" tabindex="0" data-code="@RestResource(urlMapping ='/application-name')
global without sharing class WebhookListner{
    /**
     * @description this is POST method.
     */
    @HttpPost
    global static void doGet(){
		// Your awesome code goes here
    }
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">@RestResource</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">urlMapping</span><span style="color: #D4D4D4"> =</span><span style="color: #CE9178">&#39;/application-name&#39;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #569CD6">global</span><span style="color: #D4D4D4"> without sharing </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">WebhookListner</span><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #6A9955">    /**</span></span>
<span class="line"><span style="color: #6A9955">     * @description this is POST method.</span></span>
<span class="line"><span style="color: #6A9955">     */</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">@HttpPost</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">global</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">doGet</span><span style="color: #D4D4D4">(){</span></span>
<span class="line"><span style="color: #D4D4D4">		</span><span style="color: #6A9955">// Your awesome code goes here</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">This is all you need to start processing requests. Just simply add your logic in doGet() method. You can read more about <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">@RestResource</mark></code> annotation in <a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_rest_resource.htm">SF documentation</a>.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Notice how I have urlMapping attribute set to <code>'/application-name'</code>. This is how you can separate different webhook integrations. You can have a different apex class with different urlMapping that still uses &#8216;webhooks&#8217; site URL.</p>



<p class="wp-block-paragraph">Earlier in this guide we&#8217;ve set our webhooks site to have the following URL:<br>https://dev-ed.my.salesforce-sites.com/webhooks<br><br>So the final URL that points to our apex class with URL mapping will look like this:<br>https://dev-ed.my.salesforce-sites.com/webhooks/<strong>services/apexrest/application-name</strong></p>
</blockquote>



<p class="wp-block-paragraph">Now we just need to uncover how you&#8217;d actually process callouts as they come in from external service.</p>



<h2 class="wp-block-heading">Step 3: Configure Webhook Callout Within Third-Party App</h2>



<p class="wp-block-paragraph">To make it more relatable, let&#8217;s pretend that I&#8217;m integrating with marketing service to track email clicks. My marketing platform allows me to send webhook notifications when someone clicks any link in my email.</p>



<p class="wp-block-paragraph">Obviously, I don&#8217;t know what your service user interface looks like. But typically in order to setup webhook integration all you need to do is to determine triggering event and supply the URL which will be used for callouts.</p>



<p class="wp-block-paragraph">Here is a visual example for your reference:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="689" height="536" src="https://www.tech-vision.us/wp-content/uploads/2023/10/webhook-configuration-external-service-example.png" alt="Webhook Configuration on External Service Example" class="wp-image-13995" title="Webhook Configuration on External Service Example" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/webhook-configuration-external-service-example-200x156.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/webhook-configuration-external-service-example-300x233.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/webhook-configuration-external-service-example-400x311.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/webhook-configuration-external-service-example-600x467.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/webhook-configuration-external-service-example.png 689w" sizes="(max-width: 689px) 100vw, 689px" /></figure>
</div>


<p class="wp-block-paragraph">As you can tell the key parameters are:</p>



<ul class="wp-block-list">
<li><strong>Name</strong>: call it as you like</li>



<li><strong>Triggering Event</strong>: in my example it&#8217;s when someone clicks the link within the email</li>



<li><strong>URL</strong>: this will be our REST URL on Salesforce webhooks site: <br>https://dev-ed.my.salesforce-sites.com/webhooks/services/apexrest/application-name</li>
</ul>



<h2 class="wp-block-heading">Step 4: Determine What&#8217;s In Your JSON Payload</h2>



<p class="wp-block-paragraph">Let&#8217;s say the webhook event has been triggered at your third-party service. In our case someone clicked the link within the email. At that time webhook automation will send a JSON that contains all relevant information about the event to your exposed REST URL in Salesforce.</p>



<p class="wp-block-paragraph">There are two main methods that I can suggest for you to determine incoming JSON structure.</p>



<h3 class="wp-block-heading">Research API documentation</h3>



<p class="wp-block-paragraph">Most services provide API documentation with sample JSONs. You just need to find a section about webhooks and then find sample JSON for your use case.</p>



<h3 class="wp-block-heading">Use Salesforce Debug Logs (Preferred Method)</h3>



<p class="wp-block-paragraph">So lets say you&#8217;ve been looking for documentation online but can&#8217;t seem to find where they talk about your specific use case. In this scenario, we can just setup debug logs in Salesforce and see what comes in.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Important!</strong> In order to see debug logs you must trace them under &#8216;<strong>Webhooks Site Guest User&#8217;</strong>. </p>



<p class="wp-block-paragraph">This is because every time you create a site, Salesforce will create a guest user for it with it&#8217;s own guest profile. All updates in the system to happen as this guest user. The reason user is called &#8216;Webhooks Site Guest User&#8217; is because our site name is &#8216;Webhooks&#8217;</p>
</blockquote>



<p class="wp-block-paragraph">Go to Setup -&gt; Debug Logs -&gt; New</p>



<ul class="wp-block-list">
<li>Traced Entity Type: User</li>



<li>Traced Entity Name: Webhooks Site Guest User</li>



<li>Start Date/Expiration Date</li>



<li>Debug Level: Pick default (SFDC_DevConsole)</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="667" height="539" src="https://www.tech-vision.us/wp-content/uploads/2023/10/debug-log-example.png" alt="Debug Log Example" class="wp-image-14002" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/debug-log-example-177x142.png 177w, https://www.tech-vision.us/wp-content/uploads/2023/10/debug-log-example-200x162.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/debug-log-example-300x242.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/debug-log-example-400x323.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/debug-log-example-600x485.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/debug-log-example.png 667w" sizes="(max-width: 667px) 100vw, 667px" /></figure>
</div>


<p class="wp-block-paragraph">Make sure that the start/expiration times are set to when you actually going to run debug logs.</p>



<p class="wp-block-paragraph">Now, let&#8217;s add debug logs to our apex class:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="" style="font-size:.875rem;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Apex</span><span role="button" tabindex="0" data-code="@RestResource(urlMapping ='/application-name')
global without sharing class WebhookListner{
    /**
     * @description this is POST method.
     */
    @HttpPost
    global static void doGet(){
			// Debug log:
			RestRequest request = RestContext.request;
			System.debug('MyService.newMessage body:\n ' + request.requestBody.toString());
    }
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">@RestResource</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">urlMapping</span><span style="color: #D4D4D4"> =</span><span style="color: #CE9178">&#39;/application-name&#39;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #569CD6">global</span><span style="color: #D4D4D4"> without sharing </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">WebhookListner</span><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #6A9955">    /**</span></span>
<span class="line"><span style="color: #6A9955">     * @description this is POST method.</span></span>
<span class="line"><span style="color: #6A9955">     */</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">@HttpPost</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">global</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">doGet</span><span style="color: #D4D4D4">(){</span></span>
<span class="line"><span style="color: #D4D4D4">			</span><span style="color: #6A9955">// Debug log:</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">			</span><span style="color: #569CD6">RestRequest</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">request</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">RestContext</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">request</span><span style="color: #D4D4D4">;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">			</span><span style="color: #4EC9B0">System</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">debug</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;MyService.newMessage body:</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178"> &#39;</span><span style="color: #D4D4D4"> + </span><span style="color: #9CDCFE">request</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">requestBody</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">toString</span><span style="color: #D4D4D4">());</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">Next step is to trigger event in your external application so that we can inspect debug logs. In my imaginary use case scenario I have to send myself an email and click the link within the email.</p>



<p class="wp-block-paragraph">Here is what I can see in debug logs as I trigger the event in my external application:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="506" height="160" src="https://www.tech-vision.us/wp-content/uploads/2023/10/debug-log-json-example.png" alt="Debug Log JSON example" class="wp-image-14006" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/debug-log-json-example-200x63.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/debug-log-json-example-300x95.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/debug-log-json-example-400x126.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/debug-log-json-example.png 506w" sizes="(max-width: 506px) 100vw, 506px" /></figure>
</div>


<p class="wp-block-paragraph">So the JSON I&#8217;m getting in return is the following:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="" style="font-size:.875rem;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:3;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">JSON</span><span role="button" tabindex="0" data-code="{
  &quot;event&quot;: &quot;email.link.click&quot;,
  &quot;entity&quot;: {
    &quot;campaignName&quot;: &quot;Email Newsletter&quot;,
    &quot;contact&quot;: {
      &quot;firstname&quot;: &quot;John&quot;,
      &quot;lastname&quot;: &quot;Doe&quot;,
      &quot;email&quot;: &quot;test@test.com&quot;
    }
  }
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">&quot;event&quot;</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;email.link.click&quot;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">&quot;entity&quot;</span><span style="color: #D4D4D4">: {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">&quot;campaignName&quot;</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;Email Newsletter&quot;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">&quot;contact&quot;</span><span style="color: #D4D4D4">: {</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">&quot;firstname&quot;</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;John&quot;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">&quot;lastname&quot;</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;Doe&quot;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">&quot;email&quot;</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;test@test.com&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<div style="height:2em" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">Alright, let&#8217;s move on to a next step where we have to implement JSON processing.</p>



<h2 class="wp-block-heading">Step 5: Process JSON</h2>



<p class="wp-block-paragraph">Since now we know what we are getting from external service, we have to turn incoming JSON into sObjects for further processing. To do that, let&#8217;s use <a href="https://www.adminbooster.com/tool/json2apex" target="_blank" rel="noreferrer noopener">json2Apex </a>service to come up with a class structure. All you need to do is copy/paste your JSON and click &#8216;<code>Generate Apex Code</code>&#8216;. Very easy!</p>



<p class="wp-block-paragraph">Here is an example output:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1021" height="813" src="https://www.tech-vision.us/wp-content/uploads/2023/10/json-to-apex-example.png" alt="JSON to Apex sample output" class="wp-image-14011" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/json-to-apex-example-177x142.png 177w, https://www.tech-vision.us/wp-content/uploads/2023/10/json-to-apex-example-200x159.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/json-to-apex-example-300x239.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/json-to-apex-example-400x319.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/json-to-apex-example-600x478.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/json-to-apex-example-768x612.png 768w, https://www.tech-vision.us/wp-content/uploads/2023/10/json-to-apex-example-800x637.png 800w, https://www.tech-vision.us/wp-content/uploads/2023/10/json-to-apex-example.png 1021w" sizes="(max-width: 1021px) 100vw, 1021px" /></figure>
</div>


<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">I will make small alterations to object names in apex output to align with standard name conventions for apex classes. </p>
</blockquote>



<p class="wp-block-paragraph">Here is what I have for a class that is supposed to handle webhook responses:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="" style="font-size:.875rem;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:3;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Apex</span><span role="button" tabindex="0" data-code="public with sharing class WebhookResponse {
	public String event;	//email.link.click
	public entityObj entity;

	public class entityObj {
		public String campaignName;	//Email Newsletter
		public contactObj contact;
	}

	public class contactObj {
		public String firstname; // John
		public String lastname; // Doe
		public String email; // john.doe@email.com
	}

	public static WebhookResponse parse(String json){
		return (WebhookResponse) System.JSON.deserialize(json, WebhookResponse.class);
	}
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> with sharing </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">WebhookResponse</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">	</span><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">String</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">event</span><span style="color: #D4D4D4">;	</span><span style="color: #6A9955">//email.link.click</span></span>
<span class="line"><span style="color: #D4D4D4">	</span><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">entityObj</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">entity</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">	</span><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">entityObj</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">		</span><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">String</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">campaignName</span><span style="color: #D4D4D4">;	</span><span style="color: #6A9955">//Email Newsletter</span></span>
<span class="line"><span style="color: #D4D4D4">		</span><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">contactObj</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">contact</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">	}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">	</span><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">contactObj</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">		</span><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">String</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">firstname</span><span style="color: #D4D4D4">; </span><span style="color: #6A9955">// John</span></span>
<span class="line"><span style="color: #D4D4D4">		</span><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">String</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">lastname</span><span style="color: #D4D4D4">; </span><span style="color: #6A9955">// Doe</span></span>
<span class="line"><span style="color: #D4D4D4">		</span><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">String</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">email</span><span style="color: #D4D4D4">; </span><span style="color: #6A9955">// john.doe@email.com</span></span>
<span class="line"><span style="color: #D4D4D4">	}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">	</span><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">WebhookResponse</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">parse</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">String</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">json</span><span style="color: #D4D4D4">){</span></span>
<span class="line"><span style="color: #D4D4D4">		</span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> (</span><span style="color: #569CD6">WebhookResponse</span><span style="color: #D4D4D4">) </span><span style="color: #4EC9B0">System</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">JSON</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">deserialize</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">json</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">WebhookResponse</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">class</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">	}</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<div style="height:2em" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Step 6: Give Access to Apex Classes</h2>



<p class="wp-block-paragraph">So we have two classes at this time. One is set to intake incoming POST calls. Another one is to process JSON payloads. Both of those classes should be accessible by &#8216;Webhooks Profile&#8217;. You will not be able to find this profile within the list of other profiles.</p>



<p class="wp-block-paragraph">You have to go to Setup -&gt; Sites -&gt; Webhooks</p>



<p class="wp-block-paragraph">From Site details page you have to click &#8216;<code>Public Access Settings</code>&#8216; button. This will get you to a site profile page.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" width="930" height="463" src="https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-public-access-settings.png" alt="Salesforce Sites Public Access Settings" class="wp-image-14015" style="aspect-ratio:2.0086393088552916;width:930px;height:auto" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-public-access-settings-200x100.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-public-access-settings-300x149.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-public-access-settings-400x199.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-public-access-settings-600x299.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-public-access-settings-768x382.png 768w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-public-access-settings-800x398.png 800w, https://www.tech-vision.us/wp-content/uploads/2023/10/salesforce-sites-public-access-settings.png 930w" sizes="(max-width: 930px) 100vw, 930px" /></figure>
</div>


<p class="wp-block-paragraph">From there click &#8216;<code>Apex Class Access</code>&#8216;. Select both: WebhookListner, WebhookResponse classes. Save.</p>



<h2 class="wp-block-heading">Step 7: Process Webhook Callout</h2>



<p class="wp-block-paragraph">Let&#8217;s recap what we did so far. </p>



<ol class="wp-block-list">
<li>We&#8217;ve configured a webhook in external application</li>



<li>Exposed REST resource link in Salesforce</li>



<li>Figured out JSON payload</li>



<li>Configured APEX to process callouts</li>
</ol>



<p class="wp-block-paragraph">Now we just need Salesforce to process webhooks &amp; perform record updates. Let&#8217;s pretend that when someone clicks the email link I&#8217;d like to create an activity record under lead/contact in Salesforce. If there are no leads/contacts in the system then I should create a new lead and add activity record.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Depending on your use case you may need give appropriate access rights to objects and fields to your Webhooks Profile.</p>
</blockquote>



<p class="wp-block-paragraph">Here is a full code to process webhook callout:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="" style="font-size:.875rem;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:3;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Apex</span><span role="button" tabindex="0" data-code="@RestResource(urlMapping ='/application-name')
global without sharing class WebhookListner {
    /**
     * @description Application has a webhook that calls Salesforce whenever someone clicks a link from the email.
     */
    @HttpPost
    global static void doGet(){
        RestRequest request = RestContext.request;
        WebhookResponse responseWrapper = WebhookResponse.parse(request.requestBody.toString());

        String contactEmail = responseWrapper.entity.contact.email;
        String campaignName = responseWrapper.entity.campaignName;
        // From the list of objects we need to extract email address

        if(contactEmail != null){
            List &lt;Lead&gt; leadsToInsert = new List &lt;Lead&gt;();
            List &lt;Event&gt; eventsToInsert = new List &lt;Event&gt;();
            
            // Query Leads and Contacts that match email address
            List &lt;Lead&gt; leadList = [SELECT Id, OwnerId FROM Lead WHERE Email =: contactEmail AND isConverted = FALSE];
            List &lt;Contact&gt; contactList = [SELECT Id, Account.OwnerId FROM Contact WHERE Email =: contactEmail];
            
            for(Lead l : leadList){
                eventsToInsert.add(getEventRecord(l.id, l.OwnerId, campaignName));
            }

            for(Contact c : contactList){
                eventsToInsert.add(getEventRecord(c.id, c.Account.OwnerId, campaignName));
            }

            // When no leads/contacts found - create new lead record.
            if(leadList.isEmpty() &amp;&amp; contactList.isEmpty()){
                Lead newLeadRecord = getLeadRecord(responseWrapper);
                insert newLeadRecord;
                eventsToInsert.add(getEventRecord(newLeadRecord.id, null, campaignName));
            }

            if(!eventsToInsert.isEmpty()){
                insert eventsToInsert;
            }
        }
    }

    /**
     * @description generates Event record
     * @param  parentRecordId        Id of the lead/contact
     * @param  recordOwnerId         Id of the event owner
     * @param  campaignName          Campaign Name
     * @return                       return Event record
     */
    private static Event getEventRecord(Id parentRecordId, Id recordOwnerId, String campaignName){
        // sObjName will always be Lead or Contact
        String sObjName = parentRecordId.getSObjectType().getDescribe().getName();
        
        Event eventRecord = new Event();
        eventRecord.Subject = 'Email Click - Campaign: '+ campaignName;
        eventRecord.Type = 'Other';
        eventRecord.WhoId = parentRecordId;
        eventRecord.Description = 'This ' + sObjName + ' clicked the link from Email Campaign: '+ campaignName;
        eventRecord.DurationInMinutes = 1;
        eventRecord.ActivityDateTime = System.now();
        if(recordOwnerId != null){
            eventRecord.OwnerId = recordOwnerId;
        }
        return eventRecord;
    }

    /**
     * @description creates new Lead record. Company field value is set to email domain name 
     *              since it's not included in payload.
     * @param  response webhook response
     * @return          return lead record
     */
    private static Lead getLeadRecord(WebhookResponse response){
        
        Lead leadRecord = new Lead();
        leadRecord.FirstName = response.entity.contact.firstname;
        leadRecord.LastName = response.entity.contact.lastname;
        leadRecord.Email = response.entity.contact.email;
        leadRecord.Company = leadRecord.Email.split('@').get(1);
        leadRecord.LeadSource = 'Marketing';

        return leadRecord;
    }
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">@RestResource</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">urlMapping</span><span style="color: #D4D4D4"> =</span><span style="color: #CE9178">&#39;/application-name&#39;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #569CD6">global</span><span style="color: #D4D4D4"> without sharing </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">WebhookListner</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #6A9955">    /**</span></span>
<span class="line"><span style="color: #6A9955">     * @description Application has a webhook that calls Salesforce whenever someone clicks a link from the email.</span></span>
<span class="line"><span style="color: #6A9955">     */</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">@HttpPost</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">global</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">doGet</span><span style="color: #D4D4D4">(){</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">RestRequest</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">request</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">RestContext</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">request</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">WebhookResponse</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">responseWrapper</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">WebhookResponse</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">parse</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">request</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">requestBody</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">toString</span><span style="color: #D4D4D4">());</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">String</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">contactEmail</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">responseWrapper</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">entity</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">contact</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">email</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">String</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">campaignName</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">responseWrapper</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">entity</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">campaignName</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955">// From the list of objects we need to extract email address</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">contactEmail</span><span style="color: #D4D4D4"> != </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">){</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">List</span><span style="color: #D4D4D4"> &lt;</span><span style="color: #569CD6">Lead</span><span style="color: #D4D4D4">&gt; </span><span style="color: #9CDCFE">leadsToInsert</span><span style="color: #D4D4D4"> = </span><span style="color: #C586C0">new</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">List</span><span style="color: #D4D4D4"> &lt;</span><span style="color: #569CD6">Lead</span><span style="color: #D4D4D4">&gt;();</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">List</span><span style="color: #D4D4D4"> &lt;</span><span style="color: #569CD6">Event</span><span style="color: #D4D4D4">&gt; </span><span style="color: #9CDCFE">eventsToInsert</span><span style="color: #D4D4D4"> = </span><span style="color: #C586C0">new</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">List</span><span style="color: #D4D4D4"> &lt;</span><span style="color: #569CD6">Event</span><span style="color: #D4D4D4">&gt;();</span></span>
<span class="line"><span style="color: #D4D4D4">            </span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955">// Query Leads and Contacts that match email address</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">List</span><span style="color: #D4D4D4"> &lt;</span><span style="color: #569CD6">Lead</span><span style="color: #D4D4D4">&gt; </span><span style="color: #9CDCFE">leadList</span><span style="color: #D4D4D4"> = [SELECT </span><span style="color: #569CD6">Id</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">OwnerId</span><span style="color: #D4D4D4"> FROM </span><span style="color: #569CD6">Lead</span><span style="color: #D4D4D4"> WHERE </span><span style="color: #569CD6">Email</span><span style="color: #D4D4D4"> =: </span><span style="color: #9CDCFE">contactEmail</span><span style="color: #D4D4D4"> AND </span><span style="color: #569CD6">isConverted</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">FALSE</span><span style="color: #D4D4D4">];</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">List</span><span style="color: #D4D4D4"> &lt;</span><span style="color: #569CD6">Contact</span><span style="color: #D4D4D4">&gt; </span><span style="color: #9CDCFE">contactList</span><span style="color: #D4D4D4"> = [SELECT </span><span style="color: #569CD6">Id</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">Account.OwnerId</span><span style="color: #D4D4D4"> FROM </span><span style="color: #569CD6">Contact</span><span style="color: #D4D4D4"> WHERE </span><span style="color: #569CD6">Email</span><span style="color: #D4D4D4"> =: </span><span style="color: #9CDCFE">contactEmail</span><span style="color: #D4D4D4">];</span></span>
<span class="line"><span style="color: #D4D4D4">            </span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">Lead</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">l</span><span style="color: #D4D4D4"> : </span><span style="color: #9CDCFE">leadList</span><span style="color: #D4D4D4">){</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">eventsToInsert</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">add</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">getEventRecord</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">l</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">id</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">l</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">OwnerId</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">campaignName</span><span style="color: #D4D4D4">));</span></span>
<span class="line"><span style="color: #D4D4D4">            }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">Contact</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">c</span><span style="color: #D4D4D4"> : </span><span style="color: #9CDCFE">contactList</span><span style="color: #D4D4D4">){</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">eventsToInsert</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">add</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">getEventRecord</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">c</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">id</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">c</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">Account</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">OwnerId</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">campaignName</span><span style="color: #D4D4D4">));</span></span>
<span class="line"><span style="color: #D4D4D4">            }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #6A9955">// When no leads/contacts found - create new lead record.</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">leadList</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">isEmpty</span><span style="color: #D4D4D4">() &amp;&amp; </span><span style="color: #9CDCFE">contactList</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">isEmpty</span><span style="color: #D4D4D4">()){</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #569CD6">Lead</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">newLeadRecord</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">getLeadRecord</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">responseWrapper</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #DCDCAA">insert</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">newLeadRecord</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #9CDCFE">eventsToInsert</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">add</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">getEventRecord</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">newLeadRecord</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">id</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">campaignName</span><span style="color: #D4D4D4">));</span></span>
<span class="line"><span style="color: #D4D4D4">            }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4">(!</span><span style="color: #9CDCFE">eventsToInsert</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">isEmpty</span><span style="color: #D4D4D4">()){</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #DCDCAA">insert</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">eventsToInsert</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">            }</span></span>
<span class="line"><span style="color: #D4D4D4">        }</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">    /**</span></span>
<span class="line"><span style="color: #6A9955">     * @description generates Event record</span></span>
<span class="line"><span style="color: #6A9955">     * </span><span style="color: #569CD6">@param</span><span style="color: #6A9955">  </span><span style="color: #9CDCFE">parentRecordId</span><span style="color: #6A9955">        Id of the lead/contact</span></span>
<span class="line"><span style="color: #6A9955">     * </span><span style="color: #569CD6">@param</span><span style="color: #6A9955">  </span><span style="color: #9CDCFE">recordOwnerId</span><span style="color: #6A9955">         Id of the event owner</span></span>
<span class="line"><span style="color: #6A9955">     * </span><span style="color: #569CD6">@param</span><span style="color: #6A9955">  </span><span style="color: #9CDCFE">campaignName</span><span style="color: #6A9955">          Campaign Name</span></span>
<span class="line"><span style="color: #6A9955">     * </span><span style="color: #569CD6">@return</span><span style="color: #6A9955">                       return Event record</span></span>
<span class="line"><span style="color: #6A9955">     */</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">Event</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">getEventRecord</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">Id</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">parentRecordId</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">Id</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">recordOwnerId</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">String</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">campaignName</span><span style="color: #D4D4D4">){</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955">// sObjName will always be Lead or Contact</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">String</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">sObjName</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">parentRecordId</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">getSObjectType</span><span style="color: #D4D4D4">().</span><span style="color: #DCDCAA">getDescribe</span><span style="color: #D4D4D4">().</span><span style="color: #DCDCAA">getName</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">        </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">Event</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">eventRecord</span><span style="color: #D4D4D4"> = </span><span style="color: #C586C0">new</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">Event</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">eventRecord</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">Subject</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;Email Click - Campaign: &#39;</span><span style="color: #D4D4D4">+ </span><span style="color: #9CDCFE">campaignName</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">eventRecord</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">Type</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;Other&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">eventRecord</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">WhoId</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">parentRecordId</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">eventRecord</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">Description</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;This &#39;</span><span style="color: #D4D4D4"> + </span><span style="color: #9CDCFE">sObjName</span><span style="color: #D4D4D4"> + </span><span style="color: #CE9178">&#39; clicked the link from Email Campaign: &#39;</span><span style="color: #D4D4D4">+ </span><span style="color: #9CDCFE">campaignName</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">eventRecord</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">DurationInMinutes</span><span style="color: #D4D4D4"> = </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">eventRecord</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">ActivityDateTime</span><span style="color: #D4D4D4"> = </span><span style="color: #4EC9B0">System</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">now</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">recordOwnerId</span><span style="color: #D4D4D4"> != </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">){</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">eventRecord</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">OwnerId</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">recordOwnerId</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        }</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">eventRecord</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">    /**</span></span>
<span class="line"><span style="color: #6A9955">     * @description creates new Lead record. Company field value is set to email domain name </span></span>
<span class="line"><span style="color: #6A9955">     *              since it&#39;s not included in payload.</span></span>
<span class="line"><span style="color: #6A9955">     * </span><span style="color: #569CD6">@param</span><span style="color: #6A9955">  </span><span style="color: #9CDCFE">response</span><span style="color: #6A9955"> webhook response</span></span>
<span class="line"><span style="color: #6A9955">     * </span><span style="color: #569CD6">@return</span><span style="color: #6A9955">          return lead record</span></span>
<span class="line"><span style="color: #6A9955">     */</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">Lead</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">getLeadRecord</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">WebhookResponse</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">response</span><span style="color: #D4D4D4">){</span></span>
<span class="line"><span style="color: #D4D4D4">        </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">Lead</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">leadRecord</span><span style="color: #D4D4D4"> = </span><span style="color: #C586C0">new</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">Lead</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">leadRecord</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">FirstName</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">response</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">entity</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">contact</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">firstname</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">leadRecord</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">LastName</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">response</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">entity</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">contact</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">lastname</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">leadRecord</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">Email</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">response</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">entity</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">contact</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">email</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">leadRecord</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">Company</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">leadRecord</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">Email</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">split</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;@&#39;</span><span style="color: #D4D4D4">).</span><span style="color: #DCDCAA">get</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #9CDCFE">leadRecord</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">LeadSource</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;Marketing&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">leadRecord</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<div style="height:2em" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">Basically it looks for leads/contacts with exact same email addresses as in JSON payload. If records are found, it will generate an activity record which has details about marketing campaign. If there are no leads and contacts found then it will generate new lead record. It will extract company name from email address and pre-set a few other fields. It will then insert an activity for it as well.</p>



<p class="wp-block-paragraph">Later on Salesforce administrator can set a report to track campaign efficiency and use generated leads in other sales processes.</p>



<h2 class="wp-block-heading">Webhook Security Considerations</h2>



<p class="wp-block-paragraph">As mentioned in the beginning of the article, there is no authentication needed for webhooks. Therefore you may need to consider risks associated with having public REST resource.</p>



<p class="wp-block-paragraph">One viable option is to validate callouts by incoming IP address. Some services are set with static IPs that rarely change.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="" style="font-size:.875rem;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:3;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Apex</span><span role="button" tabindex="0" data-code="@RestResource(urlMapping ='/application-name')
global without sharing class WebhookListner{
    /**
     * @description this is POST method.
     */
    @HttpPost
    global static void doGet(){
			RestRequest request = RestContext.request;
			String acceptedIpAddress = label.Application_IP_Address; // Example: 192.168.1.1 (Coming from Custom Label)
			String requestIpAddress = request.remoteAddress; // Example: 192.168.1.1 (Coming from RestRequest)
			
			if(requestIpAddress == acceptedIpAddress  ){
				// do something here
			} else {
				// log unauthorized IP address
			}
    }
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">@RestResource</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">urlMapping</span><span style="color: #D4D4D4"> =</span><span style="color: #CE9178">&#39;/application-name&#39;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #569CD6">global</span><span style="color: #D4D4D4"> without sharing </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">WebhookListner</span><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #6A9955">    /**</span></span>
<span class="line"><span style="color: #6A9955">     * @description this is POST method.</span></span>
<span class="line"><span style="color: #6A9955">     */</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">@HttpPost</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">global</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">doGet</span><span style="color: #D4D4D4">(){</span></span>
<span class="line"><span style="color: #D4D4D4">			</span><span style="color: #569CD6">RestRequest</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">request</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">RestContext</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">request</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">			</span><span style="color: #569CD6">String</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">acceptedIpAddress</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">label</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">Application_IP_Address</span><span style="color: #D4D4D4">; </span><span style="color: #6A9955">// Example: 192.168.1.1 (Coming from Custom Label)</span></span>
<span class="line"><span style="color: #D4D4D4">			</span><span style="color: #569CD6">String</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">requestIpAddress</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">request</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">remoteAddress</span><span style="color: #D4D4D4">; </span><span style="color: #6A9955">// Example: 192.168.1.1 (Coming from RestRequest)</span></span>
<span class="line"><span style="color: #D4D4D4">			</span></span>
<span class="line"><span style="color: #D4D4D4">			</span><span style="color: #C586C0">if</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">requestIpAddress</span><span style="color: #D4D4D4"> == </span><span style="color: #9CDCFE">acceptedIpAddress</span><span style="color: #D4D4D4">  ){</span></span>
<span class="line"><span style="color: #D4D4D4">				</span><span style="color: #6A9955">// do something here</span></span>
<span class="line"><span style="color: #D4D4D4">			} </span><span style="color: #C586C0">else</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">				</span><span style="color: #6A9955">// log unauthorized IP address</span></span>
<span class="line"><span style="color: #D4D4D4">			}</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<div style="height:2em" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">If your application uses multiple random IPs then this method won&#8217;t work. It only works if you know exactly which IP(s) are being used to make callouts.</p>



<p class="wp-block-paragraph">Alright, that&#8217;s it for today. You&#8217;ve learned how to integrate inbound webhooks with Salesforce. Now you just have to put this knowledge to the test. Please let me know if I missed something &amp; happy coding!</p>
<p>The post <a href="https://www.tech-vision.us/salesforce-inbound-webhook-integration-guide/">Salesforce | Inbound Webhook Integration Guide</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.tech-vision.us/salesforce-inbound-webhook-integration-guide/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Salesforce &#124; Control User Access to a Flow with Custom Settings</title>
		<link>https://www.tech-vision.us/salesforce-control-user-access-to-a-flow-with-custom-settings/</link>
					<comments>https://www.tech-vision.us/salesforce-control-user-access-to-a-flow-with-custom-settings/#respond</comments>
		
		<dc:creator><![CDATA[Oleksandr Makarenko]]></dc:creator>
		<pubDate>Tue, 24 Oct 2023 01:53:02 +0000</pubDate>
				<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Flow]]></category>
		<category><![CDATA[Salesforce]]></category>
		<guid isPermaLink="false">https://www.tech-vision.us/?p=13926</guid>

					<description><![CDATA[<p>There are times when you want to give certain profiles access to a flow. As an example, only Sales Team can escalate cases. Or maybe you are looking into limiting certain flow functionality to some profiles. I came up with a simple way to handle this use case. But before jumping into solution let me  [...]</p>
<p>The post <a href="https://www.tech-vision.us/salesforce-control-user-access-to-a-flow-with-custom-settings/">Salesforce | Control User Access to a Flow with Custom Settings</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">There are times when you want to give certain profiles access to a flow. As an example, only Sales Team can escalate cases. Or maybe you are looking into limiting certain flow functionality to some profiles.</p>



<p class="wp-block-paragraph">I came up with a simple way to handle this use case. But before jumping into solution let me take a second to walk you through what I typically see in existing implementations.</p>



<h3 class="wp-block-heading">Common Flow Profile Access Implementation</h3>



<p class="wp-block-paragraph">Let&#8217;s say you have a screen flow. To validate access to a profile you&#8217;d have the following list of elements:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" width="543" height="531" src="https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation.png" alt="" class="wp-image-13933" style="aspect-ratio:1.0225988700564972;width:543px;height:auto" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-66x66.png 66w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-200x196.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-300x293.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-400x391.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation.png 543w" sizes="(max-width: 543px) 100vw, 543px" /></figure>
</div>


<p class="wp-block-paragraph">If we look at &#8216;Access Validation&#8217; decision element, it contains just a basic profile evaluation:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img decoding="async" width="1024" height="516" src="https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-decision-element-basic-1024x516.png" alt="" class="wp-image-13935" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-decision-element-basic-200x101.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-decision-element-basic-300x151.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-decision-element-basic-400x202.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-decision-element-basic-540x272.png 540w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-decision-element-basic-600x302.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-decision-element-basic-768x387.png 768w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-decision-element-basic-800x403.png 800w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-decision-element-basic-1024x516.png 1024w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-decision-element-basic-1200x605.png 1200w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-example-profile-validation-decision-element-basic.png 1220w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p class="wp-block-paragraph">If logged in user profile EQUALS to &#8216;Sales Team&#8217; OR &#8216;Operations Team&#8217; then go ahead with a next step.</p>



<p class="wp-block-paragraph">The problem with this approach is in hardcoding profile names.</p>



<p class="wp-block-paragraph"><strong>First potential risk</strong>: let&#8217;s say one day you&#8217;ll need to adjust the list of allowed profiles. This means you have to go in and adjust this decision element and re-deploy.</p>



<p class="wp-block-paragraph"><strong>The second potential risk</strong> can be if you decide to change the profile name. Same as first one. You have to go in, make adjustments and re-deploy. I&#8217;d even add more to it. Realistically it is unlikely that someone will go in, and proactively update profile names. If you have a config person, who is not having access/experience with VS code/metadata &#8211; it&#8217;d be hard to find all places where profile names are hard coded.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">To be fair, you can put profile names in labels. This will simplify the mitigation process for a second use case. If you didn&#8217;t want to use names, then you&#8217;d have to use Profile Ids. But you don&#8217;t want to hardcode IDs in labels. For profile Ids you&#8217;re likely have to use &#8216;Get Records&#8217; which then turn into extra elements.</p>
</blockquote>



<h3 class="wp-block-heading">Flow Access Through Custom Settings</h3>



<p class="wp-block-paragraph">The concept of custom setting is very appealing because it allows you to set certain field values as org defaults. But you are also able to set those fields on by profile basis.</p>



<p class="wp-block-paragraph">Let&#8217;s create a &#8216;Custom Setting&#8217; and call it &#8216;FLOW Access Settings&#8217;</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="989" height="490" src="https://www.tech-vision.us/wp-content/uploads/2023/10/new-custom-settings.png" alt="New Custom Settings" class="wp-image-13945" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/new-custom-settings-200x99.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/new-custom-settings-300x149.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/new-custom-settings-400x198.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/new-custom-settings-600x297.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/new-custom-settings-768x381.png 768w, https://www.tech-vision.us/wp-content/uploads/2023/10/new-custom-settings-800x396.png 800w, https://www.tech-vision.us/wp-content/uploads/2023/10/new-custom-settings.png 989w" sizes="(max-width: 989px) 100vw, 989px" /></figure>
</div>


<p class="wp-block-paragraph">To determine if a certain flow should validate profile access we can use <span style="text-decoration: underline;">checkbox</span> field. For example, let&#8217;s pretend we have a flow that is called: &#8216;View List of Expired Contracts&#8217;. We want only &#8216;Sales Team&#8217; and &#8216;Operations Team&#8217; to view the list of expired contracts.</p>



<p class="wp-block-paragraph">In our custom setting let&#8217;s create a custom checkbox field &amp; for the label we can use the flow name &#8216;View List of Expired Contracts&#8217;.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="993" height="570" src="https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-checkbox-field.png" alt="Custom checkbox field" class="wp-image-13947" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-checkbox-field-200x115.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-checkbox-field-300x172.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-checkbox-field-400x230.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-checkbox-field-600x344.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-checkbox-field-768x441.png 768w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-checkbox-field-800x459.png 800w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-checkbox-field.png 993w" sizes="(max-width: 993px) 100vw, 993px" /></figure>
</div>


<p class="wp-block-paragraph">When you go to &#8216;Manage&#8217; you&#8217;ll notice that org defaults are blank. Therefore at this time, this checkbox value is deselected for everyone.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">The concept of the custom setting approach is so that no one has access to a flow functionality (org default) unless you explicitly grant it to a profile.</p>
</blockquote>



<p class="wp-block-paragraph">Go ahead and click &#8216;New&#8217; button below:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="911" height="357" src="https://www.tech-vision.us/wp-content/uploads/2023/10/new-profile-setting.png" alt="" class="wp-image-13950" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/new-profile-setting-200x78.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/new-profile-setting-300x118.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/new-profile-setting-400x157.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/new-profile-setting-600x235.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/new-profile-setting-768x301.png 768w, https://www.tech-vision.us/wp-content/uploads/2023/10/new-profile-setting-800x314.png 800w, https://www.tech-vision.us/wp-content/uploads/2023/10/new-profile-setting.png 911w" sizes="(max-width: 911px) 100vw, 911px" /></figure>
</div>


<p class="wp-block-paragraph">And then all that is left is to pick desired profile and set &#8216;View List of Expired Contracts&#8217; checkbox to &#8216;true&#8217;.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="625" height="240" src="https://www.tech-vision.us/wp-content/uploads/2023/10/sales-team-checkbox-value.png" alt="" class="wp-image-13951" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/sales-team-checkbox-value-200x77.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/sales-team-checkbox-value-300x115.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/sales-team-checkbox-value-400x154.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/sales-team-checkbox-value-600x230.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/sales-team-checkbox-value.png 625w" sizes="(max-width: 625px) 100vw, 625px" /></figure>
</div>


<p class="wp-block-paragraph">I&#8217;ve added &#8216;Operations Team&#8217; profile as well. Also adjusted list view to display the value of the checkbox for each profile. Here is how it look on my end:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1659" height="477" src="https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-list-view.png" alt="" class="wp-image-13953" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-list-view-200x58.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-list-view-300x86.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-list-view-400x115.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-list-view-600x173.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-list-view-768x221.png 768w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-list-view-800x230.png 800w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-list-view-1024x294.png 1024w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-list-view-1200x345.png 1200w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-list-view-1536x442.png 1536w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-settings-list-view.png 1659w" sizes="(max-width: 1659px) 100vw, 1659px" /></figure>
</div>


<p class="wp-block-paragraph">Now let&#8217;s go back to our flow and update decision element. It&#8217;s important to know that custom settings are always cached and available in flows without any kind of get elements. Also, the value that you are getting from custom setting is based on profile entry in those settings. If there is no entry for a given profile, it will fall back to org defaults.</p>



<p class="wp-block-paragraph">You can access custom setting field values by using <strong>$Setup</strong> menu item.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1270" height="660" src="https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-setup-menu.png" alt="" class="wp-image-13955" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-setup-menu-200x104.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-setup-menu-300x156.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-setup-menu-400x208.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-setup-menu-600x312.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-setup-menu-768x399.png 768w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-setup-menu-800x416.png 800w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-setup-menu-1024x532.png 1024w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-setup-menu-1200x624.png 1200w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-setup-menu.png 1270w" sizes="(max-width: 1270px) 100vw, 1270px" /></figure>
</div>


<p class="wp-block-paragraph">So now, we just simply add a condition where we evaluate if this checkbox will be set to true for a logged in user:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1223" height="551" src="https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-profile-validation-decision.png" alt="" class="wp-image-13957" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-profile-validation-decision-200x90.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-profile-validation-decision-300x135.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-profile-validation-decision-400x180.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-profile-validation-decision-600x270.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-profile-validation-decision-768x346.png 768w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-profile-validation-decision-800x360.png 800w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-profile-validation-decision-1024x461.png 1024w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-profile-validation-decision-1200x541.png 1200w, https://www.tech-vision.us/wp-content/uploads/2023/10/flow-custom-settings-profile-validation-decision.png 1223w" sizes="(max-width: 1223px) 100vw, 1223px" /></figure>
</div>


<p class="wp-block-paragraph">And that&#8217;s it. You no longer need to re-deploy this flow if you wanted to adjust the list of allowed profiles. No need to store profile names in labels. You can control flow access by profile all in one place.</p>



<p class="wp-block-paragraph">This is what your custom setting may look like as you add your other flows that may require access validation.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1659" height="563" src="https://www.tech-vision.us/wp-content/uploads/2023/10/custom-setting-access-to-flows-by-profile-overview.png" alt="" class="wp-image-13959" srcset="https://www.tech-vision.us/wp-content/uploads/2023/10/custom-setting-access-to-flows-by-profile-overview-200x68.png 200w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-setting-access-to-flows-by-profile-overview-300x102.png 300w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-setting-access-to-flows-by-profile-overview-400x136.png 400w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-setting-access-to-flows-by-profile-overview-600x204.png 600w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-setting-access-to-flows-by-profile-overview-768x261.png 768w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-setting-access-to-flows-by-profile-overview-800x271.png 800w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-setting-access-to-flows-by-profile-overview-1024x348.png 1024w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-setting-access-to-flows-by-profile-overview-1200x407.png 1200w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-setting-access-to-flows-by-profile-overview-1536x521.png 1536w, https://www.tech-vision.us/wp-content/uploads/2023/10/custom-setting-access-to-flows-by-profile-overview.png 1659w" sizes="(max-width: 1659px) 100vw, 1659px" /></figure>
</div>


<p class="wp-block-paragraph">As you can see, it looks nice &amp; organized. It is very easy to maintain and pretty robust.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">As a side note, custom settings can be applied to both: profiles and individual users. This means, if you wanted to grant certain users some exclusive rights, you could use this framework as well. If there are one or two users then it&#8217;s fine. But if there&#8217;s more, then I&#8217;d suggest to look into something else rather than custom setting approach.</p>
</blockquote>
<p>The post <a href="https://www.tech-vision.us/salesforce-control-user-access-to-a-flow-with-custom-settings/">Salesforce | Control User Access to a Flow with Custom Settings</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.tech-vision.us/salesforce-control-user-access-to-a-flow-with-custom-settings/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Salesforce &#124; Week Number Formula Field. Step-by-step guide.</title>
		<link>https://www.tech-vision.us/salesforce-week-number-formula-field/</link>
					<comments>https://www.tech-vision.us/salesforce-week-number-formula-field/#comments</comments>
		
		<dc:creator><![CDATA[Oleksandr Makarenko]]></dc:creator>
		<pubDate>Fri, 30 Oct 2020 03:50:34 +0000</pubDate>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Salesforce]]></category>
		<guid isPermaLink="false">https://www.tech-vision.us/?p=13870</guid>

					<description><![CDATA[<p>Hey everyone! Today I'll show the formula for the week number based on a date field. This became an issue for me since I had to do reports that were broken down by calendar weeks. So when I was grouping dates by calendar week the grouping would look like this: 10/18/2020-10/24/2020 10/25/2020-10/31/2020 ... It  [...]</p>
<p>The post <a href="https://www.tech-vision.us/salesforce-week-number-formula-field/">Salesforce | Week Number Formula Field. Step-by-step guide.</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="fusion-fullwidth fullwidth-box fusion-builder-row-1 fusion-flex-container nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-flex-wrap:wrap;" ><div class="fusion-builder-row fusion-row fusion-flex-align-items-flex-start fusion-flex-content-wrap" style="max-width:1216.8px;margin-left: calc(-4% / 2 );margin-right: calc(-4% / 2 );"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-0 fusion_builder_column_1_1 1_1 fusion-flex-column" style="--awb-bg-size:cover;--awb-width-large:100%;--awb-margin-top-large:0px;--awb-spacing-right-large:1.92%;--awb-margin-bottom-large:20px;--awb-spacing-left-large:1.92%;--awb-width-medium:100%;--awb-order-medium:0;--awb-spacing-right-medium:1.92%;--awb-spacing-left-medium:1.92%;--awb-width-small:100%;--awb-order-small:0;--awb-spacing-right-small:1.92%;--awb-spacing-left-small:1.92%;"><div class="fusion-column-wrapper fusion-column-has-shadow fusion-flex-justify-content-flex-start fusion-content-layout-column"><div class="fusion-text fusion-text-1"><p>Hey everyone! Today I&#8217;ll show the formula for the week number based on a date field. This became an issue for me since I had to do reports that were broken down by calendar weeks. So when I was grouping dates by calendar week the grouping would look like this:</p>
<p>10/18/2020-10/24/2020<br />
10/25/2020-10/31/2020<br />
&#8230;</p>
<p>It is not visually appealing when you are viewing the entire year.</p>
<p>One year has approximately 52 weeks. So if the date field says 10/29/2020 &#8211; our formula field should say it&#8217;s week 44. That is because week 44 is from Monday, October 26, 2020 until (and including) Sunday, November 1, 2020.</p>
<p>So to get started let&#8217;s create a number formula field with no decimals. As an example, we&#8217;ll use the Created Date field. Since Created Date is a Date/Time field we&#8217;ll have to convert it into a date field. In Salesforce, it&#8217;s very easy to do by using DATEVALUE function. So in our case, it&#8217;ll look like this:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-1 > .CodeMirror, .fusion-syntax-highlighter-1 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-1 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-1 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-1 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_1" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_1" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_1" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh">DATEVALUE(CreatedDate)</textarea></div><div class="fusion-text fusion-text-2"><p>Alright, so here is the full formula for week number:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-2 > .CodeMirror, .fusion-syntax-highlighter-2 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-2 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-2 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-2 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_2" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_2" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_2" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh">CEILING((( DATEVALUE(CreatedDate) - DATE(YEAR(DATEVALUE(CreatedDate)), 1, 1) + 1) +
MOD(DATE(YEAR(DATEVALUE(CreatedDate)), 1, 1) - DATE(1900, 1, 7), 7)) / 7)</textarea></div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-1 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce_week_number_formula_date_time_field.jpg" class="fusion-lightbox" data-rel="iLightbox[5d5cfde6e004710bc3d]" data-title="Salesforce week number formula date/time field" title="Salesforce week number formula date/time field"><img decoding="async" width="300" height="194" alt="Salesforce week number formula date/time field" src="https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce_week_number_formula_date_time_field-300x194.jpg" class="img-responsive wp-image-13881" srcset="https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce_week_number_formula_date_time_field-200x130.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce_week_number_formula_date_time_field-400x259.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce_week_number_formula_date_time_field-600x389.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce_week_number_formula_date_time_field-800x519.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce_week_number_formula_date_time_field.jpg 1177w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 300px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-3"><p>If you would like to get the current week number from a date field, we&#8217;ll have to take out date/time to date conversion:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-3 > .CodeMirror, .fusion-syntax-highlighter-3 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-3 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-3 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-3 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_3" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_3" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_3" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh">CEILING(((Custom_Date_Field__c - DATE(YEAR(Custom_Date_Field__c), 1, 1) + 1) +
MOD(DATE(YEAR(Custom_Date_Field__c ), 1, 1) - DATE(1900, 1, 7), 7)) / 7)</textarea></div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-2 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce_week_number_formula_date_field.jpg" class="fusion-lightbox" data-rel="iLightbox[2852b701e1c57d78a9a]" data-title="Salesforce week number formula date field" title="Salesforce week number formula date field"><img decoding="async" width="300" height="195" alt="Salesforce week number formula date field" src="https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce_week_number_formula_date_field-300x195.jpg" class="img-responsive wp-image-13879" srcset="https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce_week_number_formula_date_field-200x130.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce_week_number_formula_date_field-400x259.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce_week_number_formula_date_field-600x389.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce_week_number_formula_date_field-800x519.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce_week_number_formula_date_field.jpg 1175w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 300px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-4"><p>Now you can use this field in your reports &amp; dashboards. When you group by Week Number field, you&#8217;ll be able to sort your data in a sequence that you like. Your reports and dashboards will look much better.</p>
<p>Please let me know if you have any questions in the comment section below. See you next time!</p>
</div><div class="fusion-text fusion-text-5"><blockquote>
<p><strong>2022 Update:</strong></p>
<p>Salesforce has now added a function for this. You can simply use the ISOWEEK-function which returns the ISO 8601-week number (from 1 through 53) for the given date, ensuring that the first week starts on a Monday.</p>
<p>ISOWEEK( CreatedDate )</p>
</blockquote>
</div></div></div></div></div></p>
<p>The post <a href="https://www.tech-vision.us/salesforce-week-number-formula-field/">Salesforce | Week Number Formula Field. Step-by-step guide.</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.tech-vision.us/salesforce-week-number-formula-field/feed/</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
			</item>
		<item>
		<title>Salesforce &#124; Mass Transfer Records with Developers Console</title>
		<link>https://www.tech-vision.us/salesforce-mass-transfer-records-with-developers-console/</link>
					<comments>https://www.tech-vision.us/salesforce-mass-transfer-records-with-developers-console/#respond</comments>
		
		<dc:creator><![CDATA[Oleksandr Makarenko]]></dc:creator>
		<pubDate>Fri, 09 Oct 2020 04:15:21 +0000</pubDate>
				<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Salesforce]]></category>
		<guid isPermaLink="false">https://www.tech-vision.us/?p=13840</guid>

					<description><![CDATA[<p>Hi and welcome to another great tutorial! I'm going to show you the exact step-by-step process on how to mass transfer records from one user to another in Salesforce. To accomplish this task I'll be using the "Developers Console". For those who are unfamiliar with Developers Console - here is an awesome trailhead that  [...]</p>
<p>The post <a href="https://www.tech-vision.us/salesforce-mass-transfer-records-with-developers-console/">Salesforce | Mass Transfer Records with Developers Console</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="fusion-fullwidth fullwidth-box fusion-builder-row-2 fusion-flex-container nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-flex-wrap:wrap;" ><div class="fusion-builder-row fusion-row fusion-flex-align-items-flex-start fusion-flex-content-wrap" style="max-width:1216.8px;margin-left: calc(-4% / 2 );margin-right: calc(-4% / 2 );"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-1 fusion_builder_column_1_1 1_1 fusion-flex-column" style="--awb-bg-size:cover;--awb-width-large:100%;--awb-margin-top-large:0px;--awb-spacing-right-large:1.92%;--awb-margin-bottom-large:20px;--awb-spacing-left-large:1.92%;--awb-width-medium:100%;--awb-order-medium:0;--awb-spacing-right-medium:1.92%;--awb-spacing-left-medium:1.92%;--awb-width-small:100%;--awb-order-small:0;--awb-spacing-right-small:1.92%;--awb-spacing-left-small:1.92%;"><div class="fusion-column-wrapper fusion-column-has-shadow fusion-flex-justify-content-flex-start fusion-content-layout-column"><div class="fusion-text fusion-text-6"><p>Hi and welcome to another great tutorial! I&#8217;m going to show you the exact step-by-step process on how to mass transfer records from one user to another in Salesforce. To accomplish this task I&#8217;ll be using the &#8220;Developers Console&#8221;.</p>
<p>For those who are unfamiliar with Developers Console &#8211; <a href="https://trailhead.salesforce.com/en/content/learn/modules/developer_console" target="_blank" rel="noopener noreferrer">here is an awesome trailhead</a> that you can take to get familiar.</p>
<p>Alright, so before we get started I&#8217;d like to point out that there is a standard tool to mass transfer records from one user to another. <a href="https://help.salesforce.com/articleView?id=admin_transfer.htm&amp;type=5" target="_blank" rel="noopener noreferrer">Here</a> is a help article on that. However, I&#8217;ve found some limitations that were a dealbreaker for me. For example, I can&#8217;t use fields from related objects to filter the data. Also, I can&#8217;t transfer more than 200 records at a time.</p>
</div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-3 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/09/mass-transfer-records-standard-salesforce.jpg" class="fusion-lightbox" data-rel="iLightbox[3515f9f9f60df0ba706]" data-title="Mass Transfer Records Standard Salesforce" title="Mass Transfer Records Standard Salesforce"><img decoding="async" width="632" height="542" src="https://www.tech-vision.us/wp-content/uploads/2020/09/mass-transfer-records-standard-salesforce.jpg" alt class="img-responsive wp-image-13844" srcset="https://www.tech-vision.us/wp-content/uploads/2020/09/mass-transfer-records-standard-salesforce-200x172.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/09/mass-transfer-records-standard-salesforce-400x343.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/09/mass-transfer-records-standard-salesforce-600x515.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/09/mass-transfer-records-standard-salesforce.jpg 632w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 632px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-7"><p>Anyways, if for some reason the standard tool does not work for you, this approach should do the trick. Aside from transferring records, you could use this method for all kinds of data manipulations: create, update, delete records in Salesforce.</p>
<h3>STEP 1: Launch Developers Console</h3>
<p>Go ahead and click Setup -&gt; Developers Console. Make sure that you allow pop-ups on a page. A new browser window should show up.</p>
</div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-4 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/09/launch-developers-console-salesforce.jpg" class="fusion-lightbox" data-rel="iLightbox[545a420a1ec4c192078]" data-title="Launch Developers Console Salesforce" title="Launch Developers Console Salesforce"><img decoding="async" width="610" height="420" alt="Launch Developers Console Salesforce" src="https://www.tech-vision.us/wp-content/uploads/2020/09/launch-developers-console-salesforce.jpg" class="img-responsive wp-image-13843" srcset="https://www.tech-vision.us/wp-content/uploads/2020/09/launch-developers-console-salesforce-200x138.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/09/launch-developers-console-salesforce-400x275.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/09/launch-developers-console-salesforce-600x413.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/09/launch-developers-console-salesforce.jpg 610w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 610px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-8"><p>Here is how the <strong>Developers</strong> <strong>Console</strong> looks like. Now we just need to get to a window that can execute our simple apex script.</p>
</div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-5 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-salesforce.jpg" class="fusion-lightbox" data-rel="iLightbox[b5f85627b9b0d6b11b2]" data-caption="Developers Console Salesforce" data-title="Developers Console Salesforce" title="Developers Console Salesforce"><img decoding="async" width="1053" height="632" src="https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-salesforce.jpg" alt class="img-responsive wp-image-13846" srcset="https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-salesforce-200x120.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-salesforce-400x240.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-salesforce-600x360.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-salesforce-800x480.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-salesforce.jpg 1053w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 1053px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-9"><p>From the top menu go ahead and click &#8216;<strong>Debug</strong>&#8216; -&gt; &#8216;<strong>Open Execute Annonymous Window</strong>&#8216;. It will open a smaller window where we&#8217;ll be pasting our apex code to transfer records.</p>
</div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-6 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-execute-anonymous-salesforce.jpg" class="fusion-lightbox" data-rel="iLightbox[0e74c16ab12a8192200]" data-title="Developers Console Execute anonymous Salesforce" title="Developers Console Execute anonymous Salesforce"><img decoding="async" width="1053" height="613" src="https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-execute-anonymous-salesforce.jpg" alt class="img-responsive wp-image-13850" srcset="https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-execute-anonymous-salesforce-200x116.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-execute-anonymous-salesforce-400x233.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-execute-anonymous-salesforce-600x349.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-execute-anonymous-salesforce-800x466.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-execute-anonymous-salesforce.jpg 1053w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 1053px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-10"><p>That smaller window will be used to execute our apex code. Please see below.</p>
</div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-7 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-execute-anonymous-window-salesforce.jpg" class="fusion-lightbox" data-rel="iLightbox[d333502f02d656e8d8f]" data-title="Developers Console Execute anonymous window Salesforce" title="Developers Console Execute anonymous window Salesforce"><img decoding="async" width="1074" height="684" alt="Developers Console Execute anonymous window Salesforce" src="https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-execute-anonymous-window-salesforce.jpg" class="img-responsive wp-image-13858" srcset="https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-execute-anonymous-window-salesforce-200x127.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-execute-anonymous-window-salesforce-400x255.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-execute-anonymous-window-salesforce-600x382.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-execute-anonymous-window-salesforce-800x509.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/10/developers-console-execute-anonymous-window-salesforce.jpg 1074w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 1074px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-11"><h3>Step 2: Write an Apex Script</h3>
<p>Alright, let&#8217;s say we need to transfer all opportunity records from inactive users. To do so, we just need a very simple SOQL query and update statement. Please see below:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-4 > .CodeMirror, .fusion-syntax-highlighter-4 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-4 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-4 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-4 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_4" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_4" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_4" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/jsx">// Quering Opportunities that we'd like to update 
List <Opportunity> Opportunities = [SELECT ID FROM Opportunity WHERE Owner.isActive = FALSE];
for(Opportunity o : Opportunities){
	// For each opportunity we assign a new owner
	o.OwnerId = 'XXXXXXXXXXXXXXXXXX';
}
//performing update
update Opportunities;</textarea></div><div class="fusion-text fusion-text-12"><p>I&#8217;ve added some comments to the code. But essentially we look for all records that match our search criteria. Then we do a FOR loop to replace owner IDs for each record. Lastly, we perform an update in the database.</p>
<p>XXXXXXXXXXXXXXXXXX &#8211; is the user ID in Salesforce. Let&#8217;s say you&#8217;ve identified a user you&#8217;d like to transfer records to. Go to any record that is owned by that user and click on its name. It will take you to a user page. From there you just need to find the Salesforce ID in the URL as shown below:</p>
</div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-8 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce-user-id.jpg" class="fusion-lightbox" data-rel="iLightbox[dd384a1f23f8dbd4d0a]" data-title="Salesforce User ID" title="Salesforce User ID"><img decoding="async" width="1053" height="537" alt="Salesforce User ID" src="https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce-user-id.jpg" class="img-responsive wp-image-13860" srcset="https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce-user-id-200x102.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce-user-id-400x204.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce-user-id-600x306.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce-user-id-800x408.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce-user-id.jpg 1053w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 1053px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-13"><p>Once everything is set and ready to go just hit &#8216;Execute&#8217; and it will update all the records. That&#8217;s it. This very simple example shows how you can alter the data in your SF org very efficiently.</p>
<p>Depending on how many records you are trying to update, you may run into &#8216;Apex CPU time limit exceeded&#8217; error. That means you are exceeding governor limits for processing time. To resolve this you just need to use LIMIT for your SOQL Query. For example:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-5 > .CodeMirror, .fusion-syntax-highlighter-5 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-5 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-5 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-5 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_5" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_5" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_5" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/jsx">List <Opportunity> Opportunities = [SELECT ID FROM Opportunity WHERE Owner.isActive = FALSE LIMIT 50];</textarea></div><div class="fusion-text fusion-text-14"><p>This will limit the amount of returned opportunities to 50. This means if you have 146 records to update, you&#8217;ll need to run your script 3 times.</p>
<p>You may also encounter errors due to validation rules. You&#8217;ll have to either disable validation rules, fix invalid records or filter them out of your script in the first place.</p>
<h3>IMPORTANT PRECAUTIONS</h3>
<p>Like I&#8217;ve said earlier, this a very simple way to update records in SF. However, make sure you are 100% sure of what you doing.</p>
<ul>
<li>Double-check all scripts that you are going to execute.</li>
<li>Comment all insert/update/delete statements and verify that your queries return the correct amount of records.</li>
<li>Make a SOQL query and then run a quick report to cross-check the number of records.</li>
<li>Use <a href="https://help.salesforce.com/articleView?id=code_debug_log.htm&amp;type=5" target="_blank" rel="noopener noreferrer">debug logs</a> when necessary.</li>
</ul>
<p>All in all, don&#8217;t **** up! Good luck and may the Salesforce be with you!</p>
</div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-9 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><img decoding="async" width="500" height="374" alt="Salesforce Developer Meme" title="Salesforce Developer Meme" src="https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce-developer-meme.jpeg" class="img-responsive wp-image-13861" srcset="https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce-developer-meme-200x150.jpeg 200w, https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce-developer-meme-400x299.jpeg 400w, https://www.tech-vision.us/wp-content/uploads/2020/10/salesforce-developer-meme.jpeg 500w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 500px" /></span></div></div></div></div></div></p>
<p>The post <a href="https://www.tech-vision.us/salesforce-mass-transfer-records-with-developers-console/">Salesforce | Mass Transfer Records with Developers Console</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.tech-vision.us/salesforce-mass-transfer-records-with-developers-console/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Salesforce &#124; Conditionally add Custom Icons to a Related List</title>
		<link>https://www.tech-vision.us/salesforce-conditionally-add-custom-icons-to-a-related-list/</link>
					<comments>https://www.tech-vision.us/salesforce-conditionally-add-custom-icons-to-a-related-list/#respond</comments>
		
		<dc:creator><![CDATA[Oleksandr Makarenko]]></dc:creator>
		<pubDate>Wed, 02 Sep 2020 02:04:18 +0000</pubDate>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Salesforce]]></category>
		<guid isPermaLink="false">https://www.tech-vision.us/?p=13792</guid>

					<description><![CDATA[<p>Hi there! In this very quick tutorial, I'll show you how to add custom icons to any record within the related list in Salesforce. This can be useful if you'd like to highlight certain records. Since Salesforce's related lists are all look alike, such icons may help a user to navigate page layouts more  [...]</p>
<p>The post <a href="https://www.tech-vision.us/salesforce-conditionally-add-custom-icons-to-a-related-list/">Salesforce | Conditionally add Custom Icons to a Related List</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="fusion-fullwidth fullwidth-box fusion-builder-row-3 fusion-flex-container nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-flex-wrap:wrap;" ><div class="fusion-builder-row fusion-row fusion-flex-align-items-flex-start fusion-flex-content-wrap" style="max-width:1216.8px;margin-left: calc(-4% / 2 );margin-right: calc(-4% / 2 );"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-2 fusion_builder_column_1_1 1_1 fusion-flex-column" style="--awb-bg-size:cover;--awb-width-large:100%;--awb-margin-top-large:0px;--awb-spacing-right-large:1.92%;--awb-margin-bottom-large:20px;--awb-spacing-left-large:1.92%;--awb-width-medium:100%;--awb-order-medium:0;--awb-spacing-right-medium:1.92%;--awb-spacing-left-medium:1.92%;--awb-width-small:100%;--awb-order-small:0;--awb-spacing-right-small:1.92%;--awb-spacing-left-small:1.92%;"><div class="fusion-column-wrapper fusion-column-has-shadow fusion-flex-justify-content-flex-start fusion-content-layout-column"><div class="fusion-text fusion-text-15"><p>Hi there! In this very quick tutorial, I&#8217;ll show you how to add custom icons to any record within the related list in Salesforce. This can be useful if you&#8217;d like to highlight certain records. Since Salesforce&#8217;s related lists are all look alike, such icons may help a user to navigate page layouts more efficiently.</p>
<p>Let&#8217;s say we have a task to highlight only <b>new cases</b> within the cases related list. So let&#8217;s get started.</p>
<p>This is how our related list looks now:</p>
</div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-10 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/09/initial-case-list.jpg" class="fusion-lightbox" data-rel="iLightbox[ba8d087c7de0520b44f]" data-title="Initial Case List" title="Initial Case List"><img decoding="async" width="1246" height="410" alt="Initial Case List" src="https://www.tech-vision.us/wp-content/uploads/2020/09/initial-case-list.jpg" class="img-responsive wp-image-13805" srcset="https://www.tech-vision.us/wp-content/uploads/2020/09/initial-case-list-200x66.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/09/initial-case-list-400x132.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/09/initial-case-list-600x197.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/09/initial-case-list-800x263.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/09/initial-case-list-1200x395.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2020/09/initial-case-list.jpg 1246w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 1200px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-16"><p>So far, if we look at the case list, it&#8217;s hard to tell which one is new. A user has to read through the statuses to figure it out. So let&#8217;s get this simplified.</p>
<h3>STEP 1: Get an Icon</h3>
<p>This step should be very simple. You just need to download an icon from google or make your own one. I&#8217;m suggesting to use icons that are up to <strong>20px</strong> in height.</p>
<p>For our example I&#8217;ll use this one: <img decoding="async" class="alignnone size-full wp-image-13794" src="https://www.tech-vision.us/wp-content/uploads/2020/08/pin.png" alt="Salesforce Icon" width="20" height="20" /></p>
<h3>STEP 2: Upload an Icon as a Static Resource</h3>
<p>Go to Setup -&gt; Type in search &#8216;Static&#8217; -&gt; Click &#8216;<strong>Static Resources</strong>&#8216;.</p>
</div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-11 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/09/static-resource-setup.jpg" class="fusion-lightbox" data-rel="iLightbox[79b041d41f3328eab27]" data-title="Static Resource Setup" title="Static Resource Setup"><img decoding="async" width="511" height="324" alt="Static Resource Setup" src="https://www.tech-vision.us/wp-content/uploads/2020/09/static-resource-setup.jpg" class="img-responsive wp-image-13797" srcset="https://www.tech-vision.us/wp-content/uploads/2020/09/static-resource-setup-200x127.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/09/static-resource-setup-400x254.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/09/static-resource-setup.jpg 511w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 511px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-17"><p>Once there, click on &#8216;<strong>New</strong>&#8216; to create a new static resource.</p>
<p>The Name can be anything you like. For our example, let&#8217;s use &#8216;<strong>Green_Flag</strong>&#8216;. Then select your icon file to upload. Make sure to set &#8216;<strong>Cache Control</strong>&#8216; to <strong>public</strong>. That way your icon will be accessible by other users.</p>
</div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-12 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/09/static-resource-upload.jpg" class="fusion-lightbox" data-rel="iLightbox[cd9ee92a19376016a80]" data-title="Static Resource Upload" title="Static Resource Upload"><img decoding="async" width="979" height="449" alt="Static Resource Upload" src="https://www.tech-vision.us/wp-content/uploads/2020/09/static-resource-upload.jpg" class="img-responsive wp-image-13800" srcset="https://www.tech-vision.us/wp-content/uploads/2020/09/static-resource-upload-200x92.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/09/static-resource-upload-400x183.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/09/static-resource-upload-600x275.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/09/static-resource-upload-800x367.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/09/static-resource-upload.jpg 979w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 979px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-18"><h3>Step 3: Create a Custom Text Formula Field</h3>
<p>To do that, go to a <strong>Case</strong> object. Under<strong> Fields &amp; Relationships</strong> create a new custom text formula field. Let&#8217;s call it &#8216;<strong>Contact Name</strong>&#8216;. It will replace exact same standard field.</p>
</div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-13 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field.jpg" class="fusion-lightbox" data-rel="iLightbox[d83309a978f20553a15]" data-title="Contact Name Custom Field" title="Contact Name Custom Field"><img decoding="async" width="1343" height="578" alt="Contact Name Custom Field" src="https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field.jpg" class="img-responsive wp-image-13807" srcset="https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field-200x86.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field-400x172.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field-600x258.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field-800x344.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field-1200x516.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field.jpg 1343w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 1200px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-19"><p>Here comes the fun part. For our custom formula field, we need to have two main things.</p>
<ol>
<li>It should display the contact name and if clicked on it &#8211; it should take you to a record itself. (<strong>HYPERLINK</strong>)</li>
<li>Conditionally display our icon next to the name when our case is having &#8216;<strong>New</strong>&#8216; status. (<strong>IF</strong>)+(<strong>IMAGE</strong>)</li>
</ol>
<p>The <strong>HYPERLINK</strong> function looks this way:</p>
<blockquote>
<p>HYPERLINK(url, friendly_name [, target])</p>
</blockquote>
<p>In our case:</p>
<blockquote>
<p>HYPERLINK(&#8220;/&#8221;+ ContactId , Contact.FirstName+&#8217; &#8216;+Contact.LastName, &#8220;_self&#8221;)</p>
</blockquote>
<p>The <strong>IMAGE</strong> function looks this way:</p>
<blockquote>
<p>IMAGE(image_url, alternate_text [, height, width])</p>
</blockquote>
<p>In our case:</p>
<blockquote>
<p>IMAGE(&#8220;/resource/Green_Flag&#8221;, &#8220;Green_Flag&#8221;,20,20)</p>
</blockquote>
<p>Lastly, if we want to conditionally display an icon next to a contact record name, we need to use <strong>IF</strong> function:</p>
<blockquote>
<p>IF(logical_test, value_if_true, value_if_false)</p>
</blockquote>
<p>Here is a great article that I&#8217;ve written about <a href="https://www.tech-vision.us/salesforce-the-easiest-way-to-write-if-formulas/">Salesforce IF formulas</a>. Please take a look if you have a minute.</p>
<p>So our <strong>IF</strong> formula will look like this:</p>
<blockquote>
<p>if( ISPICKVAL(Status, “New” ), ‘ ‘ + IMAGE(“/resource/Green_Flag”, “Green_Flag”,20,20), ”)</p>
</blockquote>
<p>Let&#8217;s put everything together as one formula:</p>
<blockquote>
<p>HYPERLINK(&#8220;/&#8221;+ ContactId , Contact.FirstName+&#8217; &#8216;+Contact.LastName, &#8220;_self&#8221;) + if( ISPICKVAL(Status, &#8220;New&#8221; ), &#8216; &#8216; + IMAGE(&#8220;/resource/Green_Flag&#8221;, &#8220;Green_Flag&#8221;,20,20), &#8221;)</p>
</blockquote>
<p>Once done, go ahead and save. Attaching a screenshot for your reference.</p>
</div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-14 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field-formula.jpg" class="fusion-lightbox" data-rel="iLightbox[c8d65a108d914523b6b]" data-title="Contact Name Field Formula" title="Contact Name Field Formula"><img decoding="async" width="1174" height="656" alt="Contact Name Field Formula" src="https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field-formula.jpg" class="img-responsive wp-image-13813" srcset="https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field-formula-200x112.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field-formula-400x224.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field-formula-600x335.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field-formula-800x447.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/09/contact-name-field-formula.jpg 1174w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 1174px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-20"><h3>Step 4: Add the Field to a Page Layout</h3>
<p>Go ahead into object settings, <strong>Page Layouts</strong>, and add our new field to a Case related list. Make sure to remove the existing field as well.</p>
</div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-15 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/09/add-field-to-a-page-layout-salesforce.jpg" class="fusion-lightbox" data-rel="iLightbox[6fdfc11b0158326d365]" data-title="Add Field to a page layout salesforce" title="Add Field to a page layout salesforce"><img decoding="async" width="1417" height="742" alt="Add Field to a page layout salesforce" src="https://www.tech-vision.us/wp-content/uploads/2020/09/add-field-to-a-page-layout-salesforce.jpg" class="img-responsive wp-image-13815" srcset="https://www.tech-vision.us/wp-content/uploads/2020/09/add-field-to-a-page-layout-salesforce-200x105.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/09/add-field-to-a-page-layout-salesforce-400x209.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/09/add-field-to-a-page-layout-salesforce-600x314.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/09/add-field-to-a-page-layout-salesforce-800x419.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/09/add-field-to-a-page-layout-salesforce-1200x628.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2020/09/add-field-to-a-page-layout-salesforce.jpg 1417w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 1200px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-21"><p>If you did everything right, here what you are supposed to see:</p>
</div><div class="fusion-image-element " style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><span class=" fusion-imageframe imageframe-dropshadow imageframe-16 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/09/final-case-list.jpg" class="fusion-lightbox" data-rel="iLightbox[d207bb735bfd5f4fdea]" data-title="Final Case List" title="Final Case List"><img decoding="async" width="1233" height="397" alt="Final Case List" src="https://www.tech-vision.us/wp-content/uploads/2020/09/final-case-list.jpg" class="img-responsive wp-image-13816" srcset="https://www.tech-vision.us/wp-content/uploads/2020/09/final-case-list-200x64.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/09/final-case-list-400x129.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/09/final-case-list-600x193.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/09/final-case-list-800x258.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/09/final-case-list-1200x386.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2020/09/final-case-list.jpg 1233w" sizes="(max-width: 1024px) 100vw, (max-width: 640px) 100vw, 1200px" /></a></span></div><div class="fusion-separator fusion-full-width-sep" style="align-self: center;margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div>
<div class="fusion-text fusion-text-22"><p>To me, it&#8217;s much more visually appealing when highlighted by icons. Obviously you can have your own conditions set for icons to show.  You can also set different icon colors if necessary. This was just to get you the idea that it is possible to customize related lists with custom icons. Oh yeah, it can potentially save you column space as related lists are limited to 10 columns max.</p>
<p>Please let me know if you have any questions. Comments are also welcome! See ya&#8217;ll next time!</p>
</div></div></div></div></div></p>
<p>The post <a href="https://www.tech-vision.us/salesforce-conditionally-add-custom-icons-to-a-related-list/">Salesforce | Conditionally add Custom Icons to a Related List</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.tech-vision.us/salesforce-conditionally-add-custom-icons-to-a-related-list/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Salesforce &#124; Executing Trigger From a Process Builder</title>
		<link>https://www.tech-vision.us/salesforce-executing-trigger-from-a-process-builder/</link>
					<comments>https://www.tech-vision.us/salesforce-executing-trigger-from-a-process-builder/#respond</comments>
		
		<dc:creator><![CDATA[Oleksandr Makarenko]]></dc:creator>
		<pubDate>Sun, 21 Jun 2020 21:02:55 +0000</pubDate>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Salesforce]]></category>
		<guid isPermaLink="false">https://www.tech-vision.us/?p=13770</guid>

					<description><![CDATA[<p>Hi and welcome to another very exciting tutorial! Today I'll provide step-by-step instructions on how to invoke a trigger from a process builder in Salesforce. That way you'll have more control over the code that is set in your org. The main advantage of starting a trigger from a process builder is that you  [...]</p>
<p>The post <a href="https://www.tech-vision.us/salesforce-executing-trigger-from-a-process-builder/">Salesforce | Executing Trigger From a Process Builder</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="fusion-fullwidth fullwidth-box fusion-builder-row-4 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-flex-wrap:wrap;" ><div class="fusion-builder-row fusion-row"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-3 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="--awb-bg-size:cover;"><div class="fusion-column-wrapper fusion-column-has-shadow fusion-flex-column-wrapper-legacy"><div class="fusion-text fusion-text-23"><p>Hi and welcome to another very exciting tutorial! Today I&#8217;ll provide step-by-step instructions on how to invoke a trigger from a process builder in Salesforce. That way you&#8217;ll have more control over the code that is set in your org.</p>
<p>The main advantage of starting a trigger from a process builder is that you have the ability to turn off the automation whenever it&#8217;s necessary. If you were to hardcode the trigger criteria it&#8217;d take quite a while to deploy changeset to turn it off. Another cool thing is that you&#8217;ll have less code in your trigger. All triggering criteria will be specified in the process builder.</p>
</div><div class="fusion-text fusion-text-24"><h3>Step 1: Create APEX</h3>
<p>Let&#8217;s create a very simple apex class. In order to access apex class functions from process builder, you need to use <strong>@InvocableMethod</strong> annotation. Please take a moment to read about this annotation in the <a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableMethod.htm" target="_blank" rel="noopener noreferrer">Developer Guide</a> to get familiar.</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-6 > .CodeMirror, .fusion-syntax-highlighter-6 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-6 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-6 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-6 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_6" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_6" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_6" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/jsx">public class contacts_trigger {
    @InvocableMethod(label = 'Custom Logic on Contact' description = 'It will execute \'custom \' trigger  if criteria is met')
    public static void phone_update(List<Contact> contacts) {
        for(Contact c : contacts){
            // Do something here
        }
    }
}</textarea></div><div class="fusion-text fusion-text-25"><p>As you see, the apex class above does not do anything in particular. It&#8217;s more like a template for your future triggers. Essentially this class gets a list of records from process builder so that you can use them in apex.</p>
<p><strong>Label</strong> parameter helps to identify apex class function from Process builder</p>
<p><strong>Description</strong> provides some details about the trigger.</p>
</div><div class="fusion-text fusion-text-26"><h3>Step 2: Create a Process Builder With Triggering Criteria</h3>
<p>For this example, I&#8217;ll create some simple process builder on a &#8216;Contact&#8217; object. Go to Setup -&gt; Type in the search bar &#8216;Process Builder&#8217;. You should be able to see filtered results shortly. If you are not familiar with Process Builder &#8211; please take <a href="https://www.tech-vision.us/salesforce-how-to-lock-related-records-if-pending-approval/" target="_blank" rel="noopener noreferrer">this awesome trailhead</a> to get familiar.</p>
<p>Click &#8216;<strong>New</strong>&#8216; to create a new process.</p>
<p><strong>Process Name:</strong> Contact Trigger.</p>
<p><strong>API Name:</strong> Will be auto-populated.</p>
<p><strong>Description:</strong> Execute Custom Logic For Contact.</p>
<p><strong>The process starts when:</strong> A record changes.</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-dropshadow imageframe-17 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_salesforce.jpg" class="fusion-lightbox" data-rel="iLightbox[93ccb9c9e23e605ee5b]" data-title="New Process Builder Salesforce" title="New Process Builder Salesforce"><img decoding="async" width="918" height="572" alt="New Process Builder Salesforce" src="https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_salesforce.jpg" class="img-responsive wp-image-13771" srcset="https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_salesforce-200x125.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_salesforce-400x249.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_salesforce-600x374.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_salesforce-800x498.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_salesforce.jpg 918w" sizes="(max-width: 1100px) 100vw, 918px" /></a></span></div></div><div class="fusion-text fusion-text-27"><p>Next, go ahead and add a &#8216;Contact&#8217; object. You can do it by clicking &#8216;<strong>Add Object</strong>&#8216; and finding Contact in the list.</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-dropshadow imageframe-18 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_select_contact_salesforce.jpg" class="fusion-lightbox" data-rel="iLightbox[14fb6911230788a7c9a]" data-title="New Process Builder Select Contact Salesforce" title="New Process Builder Select Contact Salesforce"><img decoding="async" width="1498" height="578" alt="New Process Builder Select Contact Salesforce" src="https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_select_contact_salesforce.jpg" class="img-responsive wp-image-13772" srcset="https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_select_contact_salesforce-200x77.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_select_contact_salesforce-400x154.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_select_contact_salesforce-600x232.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_select_contact_salesforce-800x309.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_select_contact_salesforce-1200x463.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_select_contact_salesforce.jpg 1498w" sizes="(max-width: 1100px) 100vw, 1200px" /></a></span></div></div><div class="fusion-text fusion-text-28"><p>Set &#8216;<strong>Start the process</strong>&#8216; when a record is created or edited.</p>
<blockquote>
<p>Obviously, you could use the other option. It all depends on your use case. I prefer to use &#8216;when a record is created or edited&#8217; just because it eliminates the need of creating another process builder for worklows that are supposed to fire on updates. If you need process builder to fire on insert, you could use ISNEW() formula to check if record is inserted.</p>
</blockquote>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-dropshadow imageframe-19 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_created_edited_salesforce.jpg" class="fusion-lightbox" data-rel="iLightbox[c4268093bb756a72bf6]" data-title="New Process Builder Created Edited Salesforce" title="New Process Builder Created Edited Salesforce"><img decoding="async" width="480" height="299" alt="New Process Builder Created Edited Salesforce" src="https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_created_edited_salesforce.jpg" class="img-responsive wp-image-13773" srcset="https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_created_edited_salesforce-200x125.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_created_edited_salesforce-400x249.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/06/new_process_builder_created_edited_salesforce.jpg 480w" sizes="(max-width: 1100px) 100vw, 480px" /></a></span></div></div><div class="fusion-text fusion-text-29"><p>Let&#8217;s add our first action. For this example, I&#8217;ll use very simple trigger criteria. I want our process builder to fire only when a phone number is populated on a contact record.</p>
<p><strong>Criteria Name:</strong> Phone is not Empty.</p>
<p><strong>Criteria for Executing Actions:</strong> Conditions are met.</p>
<p><strong>Set conditions:</strong>  [Contact].Phone &#8211; Does Not Equal &#8211; Global Constant &#8211; $GlobalConstant.EmptyString</p>
<p><strong>Conditions:</strong> All conditions are met (AND)</p>
<p><strong>Important!</strong> <span style="text-decoration: underline;">Make sure to click the &#8216;Advanced&#8217; link to set checkbox to &#8216;Yes&#8217;</span>. That way your action will fire only when specified changes are made to the record. In other words, it will only trigger when a phone field changes from blank to some value.</p>
<p>Otherwise, action will fire every time when a contact record is updated while the phone number is not blank.</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-dropshadow imageframe-20 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_criteria_salesforce.jpg" class="fusion-lightbox" data-rel="iLightbox[5d89be54075a6326d8c]" data-title="Process Builder Criteria Salesforce" title="Process Builder Criteria Salesforce"><img decoding="async" width="694" height="709" alt="Process Builder Criteria Salesforce" src="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_criteria_salesforce.jpg" class="img-responsive wp-image-13774" srcset="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_criteria_salesforce-200x204.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_criteria_salesforce-400x409.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_criteria_salesforce-600x613.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_criteria_salesforce.jpg 694w" sizes="(max-width: 1100px) 100vw, 694px" /></a></span></div></div><div class="fusion-text fusion-text-30"><p>Once done, don&#8217;t forget to click &#8216;Save&#8217;. Next, let&#8217;s add action by clicking &#8216;Add Action&#8217; link.</p>
<p>For Action Type select &#8216;Apex&#8217;</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-dropshadow imageframe-21 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_apex_salesforce.jpg" class="fusion-lightbox" data-rel="iLightbox[bf81f623c1cc352c3dd]" data-title="Process Builder Apex Salesforce" title="Process Builder Apex Salesforce"><img decoding="async" width="1494" height="716" alt="Process Builder Apex Salesforce" src="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_apex_salesforce.jpg" class="img-responsive wp-image-13775" srcset="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_apex_salesforce-200x96.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_apex_salesforce-400x192.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_apex_salesforce-600x288.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_apex_salesforce-800x383.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_apex_salesforce-1200x575.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_apex_salesforce.jpg 1494w" sizes="(max-width: 1100px) 100vw, 1200px" /></a></span></div></div><div class="fusion-text fusion-text-31"><p>Once you select &#8216;Apex&#8217; from the list it&#8217;ll display some options.</p>
<p><strong>Action Name:</strong> Execute Trigger</p>
<p><strong>Apex Class:</strong> Start typing Custom&#8230; It&#8217;ll then display full class name &#8216;Custom Logic on Contact&#8217; This title comes from a label attribute in our apex class example.</p>
<p>Lets set variables. Since our apex class function accepts a list of contacts that have a name &#8216;contacts&#8217;, the field variable will be &#8216;contacts&#8217;.</p>
<p><strong>Type:</strong> Field Reference</p>
<p><strong>Value:</strong> Contact Record that Started Your Process</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-dropshadow imageframe-22 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_select_record_that_started_your_process_salesforce.jpg" class="fusion-lightbox" data-rel="iLightbox[9d0408e9dbab5a363ad]" data-title="Process Builder Select Record That Started Your Process Salesforce" title="Process Builder Select Record That Started Your Process Salesforce"><img decoding="async" width="667" height="561" alt="Process Builder Select Record That Started Your Process Salesforce" src="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_select_record_that_started_your_process_salesforce.jpg" class="img-responsive wp-image-13776" srcset="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_select_record_that_started_your_process_salesforce-200x168.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_select_record_that_started_your_process_salesforce-400x336.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_select_record_that_started_your_process_salesforce-600x505.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_select_record_that_started_your_process_salesforce.jpg 667w" sizes="(max-width: 1100px) 100vw, 667px" /></a></span></div></div><div class="fusion-text fusion-text-32"><p>Your apex action should look like this: Again, please make sure to hit &#8216;Save&#8217; at the end. It&#8217;s so annoying to re-do the same thing over again.</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-dropshadow imageframe-23 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_set_trigger_variables_salesforce.jpg" class="fusion-lightbox" data-rel="iLightbox[1eb596f5d8c41116867]" data-title="Process Builder Set Trigger Variables Salesforce" title="Process Builder Set Trigger Variables Salesforce"><img decoding="async" width="695" height="711" alt="Process Builder Set Trigger Variables Salesforce" src="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_set_trigger_variables_salesforce.jpg" class="img-responsive wp-image-13777" srcset="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_set_trigger_variables_salesforce-200x205.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_set_trigger_variables_salesforce-400x409.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_set_trigger_variables_salesforce-600x614.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_set_trigger_variables_salesforce.jpg 695w" sizes="(max-width: 1100px) 100vw, 695px" /></a></span></div></div><div class="fusion-text fusion-text-33"><p>Alright, once the action is saved the very last step would be to click &#8216;Activate&#8217; to make your trigger live.</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-dropshadow imageframe-24 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_complete_salesforce.jpg" class="fusion-lightbox" data-rel="iLightbox[ca4b9853fe22d6e0224]" data-title="Process Builder Complete Salesforce" title="Process Builder Complete Salesforce"><img decoding="async" width="1900" height="718" alt="Process Builder Complete Salesforce" src="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_complete_salesforce.jpg" class="img-responsive wp-image-13778" srcset="https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_complete_salesforce-200x76.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_complete_salesforce-400x151.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_complete_salesforce-600x227.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_complete_salesforce-800x302.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_complete_salesforce-1200x453.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2020/06/process_builder_complete_salesforce.jpg 1900w" sizes="(max-width: 1100px) 100vw, 1200px" /></a></span></div></div><div class="fusion-text fusion-text-34"><p>Now you should be able to easily move your hardcoded triggers into process builders. While there are obvious advantages of using such approach, there are still some things to take into consideration:</p>
<ul>
<li>Triggers will only fire on after insert/update. You can&#8217;t use a process builder for all before &amp; delete/undelete operations.</li>
<li>If you have multiple triggers under the same object, you can&#8217;t turn some of them off temporarily. You either have to make a copy of the entire process or isolate each trigger into a separate process builder. I don&#8217;t recommend having a process builder per trigger.</li>
</ul>
<p>These are all precautions. Other than that I hope you&#8217;ve learned something new today &amp; can apply this knowledge in your projects. Please let me know if I&#8217;m missing something, or if you have questions. See ya&#8217;ll next time!</p>
</div><div class="fusion-clearfix"></div></div></div></div></div></p>
<p>The post <a href="https://www.tech-vision.us/salesforce-executing-trigger-from-a-process-builder/">Salesforce | Executing Trigger From a Process Builder</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.tech-vision.us/salesforce-executing-trigger-from-a-process-builder/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Salesforce &#124; Adding Lightning Modal to a VisualForce Page</title>
		<link>https://www.tech-vision.us/salesforce-adding-lightning-modal-to-a-visualforce-page/</link>
					<comments>https://www.tech-vision.us/salesforce-adding-lightning-modal-to-a-visualforce-page/#comments</comments>
		
		<dc:creator><![CDATA[Oleksandr Makarenko]]></dc:creator>
		<pubDate>Sat, 02 May 2020 04:06:33 +0000</pubDate>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Salesforce]]></category>
		<guid isPermaLink="false">https://www.tech-vision.us/?p=13754</guid>

					<description><![CDATA[<p>Hi everyone! At some point, I was looking for a way to have a modal popup on one of my visualforce pages. The main requirement is that I wanted it to look professional and be in the lightning design system. So here are my findings: In this example, the whole thing consists of a  [...]</p>
<p>The post <a href="https://www.tech-vision.us/salesforce-adding-lightning-modal-to-a-visualforce-page/">Salesforce | Adding Lightning Modal to a VisualForce Page</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="fusion-fullwidth fullwidth-box fusion-builder-row-5 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-flex-wrap:wrap;" ><div class="fusion-builder-row fusion-row"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-4 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="--awb-bg-size:cover;"><div class="fusion-column-wrapper fusion-column-has-shadow fusion-flex-column-wrapper-legacy"><div class="fusion-text fusion-text-35"><p>Hi everyone! At some point, I was looking for a way to have a modal popup on one of my visualforce pages. The main requirement is that I wanted it to look professional and be in the lightning design system.</p>
<p>So here are my findings:</p>
<ul>
<li>In <a href="http://www.salesforcegeneral.com/salesforce-modal-dialog-box/" target="_blank" rel="noopener noreferrer">this</a> example, the whole thing consists of a few controller properties, CSS styles, and some VF markup. I&#8217;ve tested it, it works! But doesn&#8217;t meet my needs.</li>
<li><a href="https://salesforce.stackexchange.com/questions/92622/how-to-display-modal-window-in-visualforce-page" target="_blank" rel="noopener noreferrer">salesforce.stackexchange.com</a> &amp; <a href="https://developer.salesforce.com/forums/?id=906F0000000g3AmIAI" target="_blank" rel="noopener noreferrer">developer.salesforce.com </a> mostly consist of variations from the first example, or in my opinion, more complex solutions.</li>
<li><a href="https://www.thephani.com/bootstrap-modal-popup-with-visualforce-commandbutton-explained/" target="_blank" rel="noopener noreferrer">Here</a> is a very interesting solution. However, the styling is off. It has bootstrap CSS. Overall it looks good &amp; very close to what I need.</li>
<li><a href="https://www.sfdcpoint.com/salesforce/modal-popup-lightning-component-salesforce/" target="_blank" rel="noopener noreferrer">This</a> is what we are looking for! But it&#8217;s a lightning component. I wish we could convert it to use in the visualforce page! Let&#8217;s actually do it!</li>
</ul>
<h2>Let&#8217;s Find the Lightning Modal that Fits Our Needs</h2>
<p>I&#8217;ll use <a href="https://www.lightningdesignsystem.com/" target="_blank" rel="noopener noreferrer">Lightning Design System</a> guidance. <a href="https://www.lightningdesignsystem.com/" target="_blank" rel="noopener noreferrer">Here</a> is a page where you can pick the modal design that you like. For this post, I decided to pick a medium modal because it has a nice title header, content box, and two buttons: Save &amp; Cancel.</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-7 > .CodeMirror, .fusion-syntax-highlighter-7 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-7 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-7 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-7 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_7" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_7" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_7" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/html"><section role="dialog" tabindex="-1" class="slds-modal slds-fade-in-open slds-modal_medium" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1">
    <div class="slds-modal__container">
        <header class="slds-modal__header">
            <button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" title="Close">
                <svg class="slds-button__icon slds-button__icon_large" aria-hidden="true">
                    <use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#close"></use>
                </svg>
                <span class="slds-assistive-text">Close</span>
            </button>
            <h2 id="modal-heading-01" class="slds-modal__title slds-hyphenate">Modal Header</h2>
        </header>
        <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
            <p>Sit nulla est ex deserunt exercitation anim occaecat. Nostrud ullamco deserunt aute id consequat veniam incididunt duis in sint irure nisi.
			Mollit officia cillum Lorem ullamco minim nostrud elit officia tempor esse quis. Cillum sunt ad dolore quis aute consequat ipsum magna exercitation reprehenderit magna. 
			Tempor cupidatat consequat elit dolor adipisicing.</p>
            <p>Dolor eiusmod sunt ex incididunt cillum quis nostrud velit duis sit officia. Lorem aliqua enim laboris do dolor eiusmod officia.
			Mollit incididunt nisi consectetur esse laborum eiusmod pariatur proident. Eiusmod et adipisicing culpa deserunt nostrud ad veniam nulla aute est. 
			Labore esse esse cupidatat amet velit id elit consequat minim ullamco mollit enim excepteur ea.</p>
        </div>
        <footer class="slds-modal__footer">
            <button class="slds-button slds-button_neutral">Cancel</button>
            <button class="slds-button slds-button_brand">Save</button>
        </footer>
    </div>
</section>
<div class="slds-backdrop slds-backdrop_open"></div></textarea></div><div class="fusion-text fusion-text-36"><h2>Adding a Simple Visualforce Page</h2>
<p>Let&#8217;s say, we have a task to create a Visualforce page that displays all Contacts that are related to an Account. Aside from that it also should have the capability of adding more contacts to the same account.</p>
<blockquote>
<p>I know that it&#8217;d be much easier to just add new rows to a contact table to add more records. But since we are trying to understand how to use modals, let&#8217;s use them instead. That way you&#8217;ll be able to use modals where it&#8217;s much more convenient than adding rows.</p>
</blockquote>
<p>Page:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-8 > .CodeMirror, .fusion-syntax-highlighter-8 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-8 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-8 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-8 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_8" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_8" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_8" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/html"><apex:page standardController="Account" extensions="Contacts_Controller" lightningStylesheets="true">
    <apex:form>
        <h1>Here is a list of all contacts that are related to {!Account.Name}</h1>
        <apex:pageBlock>
            <apex:pageBlockButtons>
                <apex:commandButton action="{!Cancel}" value="Cancel" />
            </apex:pageBlockButtons>
            <apex:pageBlockSection columns="1">
                <apex:pageBlockTable value="{!existing_contacts}" var="c">
                    <apex:column value="{!c.FirstName}" />
                    <apex:column value="{!c.LastName}" />
                    <apex:column value="{!c.Email}" />
                </apex:pageBlockTable>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page></textarea></div><div class="fusion-text fusion-text-37"><p>Controller:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-9 > .CodeMirror, .fusion-syntax-highlighter-9 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-9 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-9 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-9 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_9" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_9" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_9" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/jsx">public class Contacts_Controller {
    public List <Contact> existing_contacts {get; set;}
    
    public Contacts_Controller(ApexPages.StandardController controller){
        Id Acc_Id = controller.getRecord().id;
        existing_contacts = [SELECT Id, FirstName, LastName, Email FROM Contact where AccountId =: Acc_Id];
    }
}</textarea></div><div class="fusion-text fusion-text-38"><p>Button:</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-bottom-shadow-color:rgba(0,0,0,0.4);--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><div class="awb-image-frame awb-image-frame-25 awb-bottomshadow fusion-animated" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><span class=" fusion-imageframe imageframe-bottomshadow imageframe-25 hover-type-none"><a href="https://www.tech-vision.us/wp-content/uploads/2020/04/sample_button.jpg" class="fusion-lightbox" data-rel="iLightbox[6ce5767a2b4bb250cd9]" data-title="Salesforce Modal Button" title="Salesforce Modal Button"><img decoding="async" width="999" height="422" alt="Salesforce Modal Button" src="https://www.tech-vision.us/wp-content/uploads/2020/04/sample_button.jpg" class="img-responsive wp-image-13755" srcset="https://www.tech-vision.us/wp-content/uploads/2020/04/sample_button-200x84.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_button-400x169.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_button-600x253.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_button-800x338.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_button.jpg 999w" sizes="(max-width: 1100px) 100vw, 999px" /></a></span><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" viewBox="0 0 600 28" preserveAspectRatio="none"><g clip-path="url(#a)"><mask id="b" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="600" height="28"><path d="M0 0h600v28H0V0Z" fill="#fff"/></mask><g filter="url(#c)" mask="url(#b)"><path d="M16.439-18.667h567.123v30.8S438.961-8.4 300-8.4C161.04-8.4 16.438 12.133 16.438 12.133v-30.8Z" fill="#000"/></g></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h600v28H0z"/></clipPath><filter id="c" x="5.438" y="-29.667" width="589.123" height="52.8" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur stdDeviation="5.5" result="effect1_foregroundBlur_3983_183"/></filter></defs></svg></div></div></div><div class="fusion-text fusion-text-39"><p>Add Button to Page Layout:</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-bottom-shadow-color:rgba(0,0,0,0.4);--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><div class="awb-image-frame awb-image-frame-26 awb-bottomshadow fusion-animated" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><span class=" fusion-imageframe imageframe-bottomshadow imageframe-26 hover-type-none"><a href="https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_layout.jpg" class="fusion-lightbox" data-rel="iLightbox[b11f72eb89ba47174d3]" data-title="Modal Sample Page Layout" title="Modal Sample Page Layout"><img decoding="async" width="1891" height="500" alt="Modal Sample Page Layout" src="https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_layout.jpg" class="img-responsive wp-image-13756" srcset="https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_layout-200x53.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_layout-400x106.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_layout-600x159.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_layout-800x212.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_layout-1200x317.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_layout.jpg 1891w" sizes="(max-width: 1100px) 100vw, 1200px" /></a></span><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" viewBox="0 0 600 28" preserveAspectRatio="none"><g clip-path="url(#a)"><mask id="b" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="600" height="28"><path d="M0 0h600v28H0V0Z" fill="#fff"/></mask><g filter="url(#c)" mask="url(#b)"><path d="M16.439-18.667h567.123v30.8S438.961-8.4 300-8.4C161.04-8.4 16.438 12.133 16.438 12.133v-30.8Z" fill="#000"/></g></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h600v28H0z"/></clipPath><filter id="c" x="5.438" y="-29.667" width="589.123" height="52.8" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur stdDeviation="5.5" result="effect1_foregroundBlur_3983_183"/></filter></defs></svg></div></div></div><div class="fusion-text fusion-text-40"><p>Result:</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-bottom-shadow-color:rgba(0,0,0,0.4);--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><div class="awb-image-frame awb-image-frame-27 awb-bottomshadow fusion-animated" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><span class=" fusion-imageframe imageframe-bottomshadow imageframe-27 hover-type-none"><a href="https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page.jpg" class="fusion-lightbox" data-rel="iLightbox[50fbe961285b0648dcf]" data-title="Salesforce Modal Sample Page" title="Salesforce Modal Sample Page"><img decoding="async" width="1909" height="357" alt="Salesforce Modal Sample Page" src="https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page.jpg" class="img-responsive wp-image-13757" srcset="https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page-200x37.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page-400x75.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page-600x112.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page-800x150.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page-1200x224.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page.jpg 1909w" sizes="(max-width: 1100px) 100vw, 1200px" /></a></span><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" viewBox="0 0 600 28" preserveAspectRatio="none"><g clip-path="url(#a)"><mask id="b" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="600" height="28"><path d="M0 0h600v28H0V0Z" fill="#fff"/></mask><g filter="url(#c)" mask="url(#b)"><path d="M16.439-18.667h567.123v30.8S438.961-8.4 300-8.4C161.04-8.4 16.438 12.133 16.438 12.133v-30.8Z" fill="#000"/></g></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h600v28H0z"/></clipPath><filter id="c" x="5.438" y="-29.667" width="589.123" height="52.8" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur stdDeviation="5.5" result="effect1_foregroundBlur_3983_183"/></filter></defs></svg></div></div></div><div class="fusion-text fusion-text-41"><p>Now its time to embed our modal into our VisualForce page. First, we need to include two scripts. One is a jQuery library, another one is bootstrap js component. The jQuery is required in order for bootstrap to work.</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-10 > .CodeMirror, .fusion-syntax-highlighter-10 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-10 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-10 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-10 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_10" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_10" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_10" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/html"><apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script></textarea></div><div class="fusion-text fusion-text-42"><p>Next, we need to allow our Visualforce page to reference Lightning Design System styling. We can do that by adding a simple tag:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-11 > .CodeMirror, .fusion-syntax-highlighter-11 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-11 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-11 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-11 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_11" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_11" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_11" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh"><apex:slds /></textarea></div><div class="fusion-text fusion-text-43"><p>Per <a href="https://www.lightningdesignsystem.com/platforms/visualforce/" target="_blank" rel="noopener noreferrer">LEX guidance page</a>, we also have to wrap our modal block with &#8220;slds-scope&#8221; class.</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-12 > .CodeMirror, .fusion-syntax-highlighter-12 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-12 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-12 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-12 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_12" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_12" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_12" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh"><div id="myModal" class="modal slds-scope">
</div></textarea></div><div class="fusion-text fusion-text-44"><p>Let&#8217;s make our modal to be hidden by default by adding a simple CSS styling:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-13 > .CodeMirror, .fusion-syntax-highlighter-13 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-13 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-13 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-13 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_13" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_13" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_13" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/css"><style>
  .modal {
    display: none;
  }
</style></textarea></div><div class="fusion-text fusion-text-45"><p>HTML buttons within the modal are replaced by VisualForce command buttons. Please note that each button has <strong>return false; </strong>In simple words, it&#8217;ll prevent refreshing the whole page which will reset everything. Please take the time to read more about it <a href="https://developer.salesforce.com/forums/?id=906F0000000AfV1IAK" target="_blank" rel="noopener noreferrer">here</a>.</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-14 > .CodeMirror, .fusion-syntax-highlighter-14 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-14 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-14 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-14 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_14" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_14" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_14" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh"> <commandbutton class="slds-button slds-button_neutral" onclick="closeModal(); return false;">Cancel</commandbutton>
 <commandbutton class="slds-button slds-button_brand" onclick="return false;">Save</commandbutton></textarea></div><div class="fusion-text fusion-text-46"><p>I think our modal markup can be much simplified by removing <strong>X</strong> icon at the very top to close the modal. This function will be done by the &#8216;Cancel&#8217; button within the modal. So let&#8217;s remove this part:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-15 > .CodeMirror, .fusion-syntax-highlighter-15 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-15 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-15 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-15 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_15" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_15" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_15" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/html"><button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" title="Close">
    <svg class="slds-button__icon slds-button__icon_large" aria-hidden="true">
  		<use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#close"></use>
    </svg>
	<span class="slds-assistive-text">Close</span>
</button></textarea></div><div class="fusion-text fusion-text-47"><p>Let&#8217;s add a small script to close modal when clicking on &#8216;Cancel&#8217; button within the modal:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-16 > .CodeMirror, .fusion-syntax-highlighter-16 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-16 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-16 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-16 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_16" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_16" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_16" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/javascript"><script>
	function closeModal() {
      $('#myModal').modal('hide');
	}
</script></textarea></div><div class="fusion-text fusion-text-48"><p>As far as controller modifications, let&#8217;s just add a blank function to do nothing for now. That way we&#8217;ll be able to ensure that our modal works.</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-17 > .CodeMirror, .fusion-syntax-highlighter-17 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-17 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-17 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-17 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_17" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_17" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_17" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-php">public void modal_add_row() {
}</textarea></div><div class="fusion-text fusion-text-49"><p>Finally, we should add a button that will open our modal:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-18 > .CodeMirror, .fusion-syntax-highlighter-18 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-18 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-18 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-18 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_18" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_18" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_18" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/html"><apex:commandButton value="Add Contacts" action="{!open_modal}" status="status" reRender="main, modal" oncomplete="$('#myModal').modal({backdrop:'static'}).show(); return false;" /></textarea></div><div class="fusion-text fusion-text-50"><h2>Putting things together. VF Page + Modal + Controller</h2>
<p>Alright, if we were to put all things together, the VisualForce page would look like this:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-19 > .CodeMirror, .fusion-syntax-highlighter-19 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-19 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-19 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-19 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_19" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_19" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_19" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/html"><apex:page standardController="Account" extensions="Contacts_Controller" lightningStylesheets="true" applyHtmlTag="false" showHeader="false">
    <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" />
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <apex:slds />
    <style>
        .modal {
            display: none;
        }
    </style>
    <apex:form>

        <h1>Here is a list of all contacts that are related to {!Account.Name}</h1>
        <apex:pageBlock id="main">
            <apex:pageBlockButtons location="top">
                <apex:commandButton action="{!Cancel}" value="Cancel" />
                <apex:commandButton value="Add Contacts" action="{!modal_function}" status="status" reRender="modal" oncomplete="$('#myModal').modal({backdrop:'static'}).show(); return false;" />
            </apex:pageBlockButtons>
            <apex:pageBlockSection columns="1">
                <apex:pageBlockTable value="{!existing_contacts}" var="c">
                    <apex:column value="{!c.FirstName}" />
                    <apex:column value="{!c.LastName}" />
                    <apex:column value="{!c.Email}" />
                </apex:pageBlockTable>
            </apex:pageBlockSection>
        </apex:pageBlock>

        <!--MODAL START -->
        <div id="myModal" class="modal slds-scope">
            <section role="dialog" tabindex="-1" class="slds-modal slds-fade-in-open slds-modal_medium" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1">
                <div class="slds-modal__container">
                    <header class="slds-modal__header">
                        <h2 id="modal-heading-01" class="slds-modal__title slds-hyphenate">Modal Header</h2>
                    </header>
                    <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
                        <p>Sit nulla est ex deserunt exercitation anim occaecat. Nostrud ullamco deserunt aute id consequat veniam incididunt duis in sint irure nisi. Mollit officia cillum Lorem ullamco minim nostrud elit officia tempor esse quis. Cillum sunt ad dolore quis aute consequat ipsum magna exercitation reprehenderit magna. Tempor cupidatat consequat elit dolor adipisicing.</p>
                        <p>Dolor eiusmod sunt ex incididunt cillum quis nostrud velit duis sit officia. Lorem aliqua enim laboris do dolor eiusmod officia. Mollit incididunt nisi consectetur esse laborum eiusmod pariatur proident. Eiusmod et adipisicing culpa deserunt nostrud ad veniam nulla aute est. Labore esse esse cupidatat amet velit id elit consequat minim ullamco mollit enim excepteur ea.</p>
                    </div>
                    <footer class="slds-modal__footer">
                        <commandbutton class="slds-button slds-button_neutral" onclick="closeModal(); return false;">Cancel</commandbutton>
                        <commandbutton class="slds-button slds-button_brand" onclick="return false;">Save</commandbutton>
                    </footer>
                </div>
            </section>
            <div class="slds-backdrop slds-backdrop_open"></div>
        </div>
        <script>
            function closeModal() {
                $('#myModal').modal('hide');
            }
        </script>
        <!--MODAL END -->

    </apex:form>
</apex:page></textarea></div><div class="fusion-text fusion-text-51"><p>Controller:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-20 > .CodeMirror, .fusion-syntax-highlighter-20 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-20 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-20 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-20 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_20" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_20" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_20" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-php">public class Contacts_Controller {
    public List <Contact> existing_contacts {get; set;}
    
    public Contacts_Controller(ApexPages.StandardController controller){
        Id Acc_Id = controller.getRecord().id;
        existing_contacts = [SELECT Id, FirstName, LastName, Email FROM Contact where AccountId =: Acc_Id];
    }
    
    public void modal_add_row() {
    }
}</textarea></div><div class="fusion-text fusion-text-52"><p>After those changes, our page would render pretty much similar to what we had at the beginning. The only difference is that now we have &#8216;Add Contacts&#8217; button:</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-dropshadow imageframe-28 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_upd.jpg" class="fusion-lightbox" data-rel="iLightbox[9ef0f9c81ed4014db5a]" data-title="VisualForce Modal Page Updated" title="VisualForce Modal Page Updated"><img decoding="async" width="1903" height="312" alt="VisualForce Modal Page Updated" src="https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_upd.jpg" class="img-responsive wp-image-13759" srcset="https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_upd-200x33.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_upd-400x66.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_upd-600x98.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_upd-800x131.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_upd-1200x197.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2020/04/sample_page_upd.jpg 1903w" sizes="(max-width: 1100px) 100vw, 1200px" /></a></span></div></div><div class="fusion-text fusion-text-53"><p>If I click the button to &#8216;Add Contacts&#8217; &#8211; our added modal will show up:</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-dropshadow imageframe-29 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/04/Lightning_Modal_Preview_Generic.jpg" class="fusion-lightbox" data-rel="iLightbox[44cb28faf8140aa9aa3]" data-title="Lightning Modal Preview Generic" title="Lightning Modal Preview Generic"><img decoding="async" width="1599" height="760" alt="Lightning Modal Preview Generic" src="https://www.tech-vision.us/wp-content/uploads/2020/04/Lightning_Modal_Preview_Generic.jpg" class="img-responsive wp-image-13761" srcset="https://www.tech-vision.us/wp-content/uploads/2020/04/Lightning_Modal_Preview_Generic-200x95.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/04/Lightning_Modal_Preview_Generic-400x190.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/04/Lightning_Modal_Preview_Generic-600x285.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/04/Lightning_Modal_Preview_Generic-800x380.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/04/Lightning_Modal_Preview_Generic-1200x570.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2020/04/Lightning_Modal_Preview_Generic.jpg 1599w" sizes="(max-width: 1100px) 100vw, 1200px" /></a></span></div></div><div class="fusion-text fusion-text-54"><h2>Adding Logic to Mass add Contacts Within the Modal</h2>
<p>Let&#8217;s replace our random text with our small table to mass generate contacts. It will consist of basic <strong>PageBlock</strong> and <strong>PageBlockTable</strong> with columns. For each row, we&#8217;ll add a row index and a button to delete the temporary record. At the bottom of the modal, there will also be a link to add more rows.</p>
<p>Here is how it looks:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-21 > .CodeMirror, .fusion-syntax-highlighter-21 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-21 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-21 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-21 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_21" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_21" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_21" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/html"><apex:pageBlock id="modal" title="Add Contacts">
	<apex:variable value="{!1}" var="sr" />
	<apex:pageBlockTable value="{!new_contacts}" var="c">
		<apex:column headerValue="Sr.">
			<apex:outputText value="{!sr}" />
		</apex:column>
		<apex:column headervalue="First Name">
			<apex:inputText value="{!c.FirstName}" />
		</apex:column>
		<apex:column headervalue="Last Name">
			<apex:inputText value="{!c.LastName}" />
		</apex:column>
		<apex:column headervalue="Email">
			<apex:inputText value="{!c.Email}" />
		</apex:column>
		<apex:column headerValue="Remove">
			<div style="width:20px;height:20px;overflow: hidden;margin-left: 25%;">
				<img decoding="async" title="Remove" style="cursor: pointer; max-width: fit-content;" src="/img/func_icons/util/trash20.gif" onclick="remove_Contact('{!sr-1}')" />
			</div>
		<apex:variable value="{!1+sr}" var="sr" />
		</apex:column>
	</apex:pageBlockTable>
</apex:pageBlock></textarea></div><div class="fusion-text fusion-text-55"><p><strong>Here is a very important part</strong>. We can&#8217;t use controller methods by using buttons from modal. This is because our buttons are technically located outside of the pageblock where we have our main contacts table.</p>
<p>For that reason, we have to use <strong><a href="https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_actionFunction.htm" target="_blank" rel="noopener noreferrer">apex:actionFunction</a>. </strong> You can read more about it <a href="https://developer.salesforce.com/forums/?id=906F0000000BTIPIA4" target="_blank" rel="noopener noreferrer">here</a>. So in our case we&#8217;ll need 3 functions. To add row, delete row, and add new contacts to the main list by clicking &#8216;Save&#8217; button. As we use those functions, we want to make sure that we re-render. That way modal or main page will always reflect the most recent information. Here is how it looks:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-22 > .CodeMirror, .fusion-syntax-highlighter-22 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-22 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-22 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-22 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_22" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_22" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_22" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/html"><apex:actionFunction action="{!modal_save}" name="save_contacts" reRender="main" oncomplete="closeModal();" />
<apex:actionFunction action="{!modal_remove_contact}" name="remove_Contact" reRender="modal">
	<apex:param value="" assignTo="{!row_Index}" name="xyz" />
</apex:actionFunction>
<apex:actionFunction action="{!modal_add_row}" name="add_rows" reRender="modal"/></textarea></div><div class="fusion-text fusion-text-56"><p>As far as the controller, I&#8217;ve added all the above functions plus one to actually save new contacts. Let&#8217;s move on to the next step so that I can demo the final result</p>
<h2>Lightning Modal within the VF page  + Logic to Mass Generate Contacts</h2>
<p>Alright, if I were to put everything together, this is what I&#8217;d get:</p>
<p>Page:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-23 > .CodeMirror, .fusion-syntax-highlighter-23 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-23 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-23 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-23 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_23" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_23" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_23" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/html"><apex:page standardController="Account" extensions="Contacts_Controller" lightningStylesheets="true" applyHtmlTag="false" showHeader="false">
    <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" />
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <apex:slds />
    <style>
        .modal {
            display: none;
        }
    </style>
    <apex:form>
        <apex:actionFunction action="{!modal_save}" name="save_contacts" reRender="main" oncomplete="closeModal();" />
        <apex:actionFunction action="{!modal_remove_contact}" name="remove_Contact" reRender="modal">
            <apex:param value="" assignTo="{!row_Index}" name="xyz" />
        </apex:actionFunction>
        <apex:actionFunction action="{!modal_add_row}" name="add_rows" reRender="modal"/>
        <h1>Here is a list of all contacts that are related to {!Account.Name}</h1>
        <apex:pageBlock id="main">
            <apex:pageMessages/>
            <apex:pageBlockButtons location="top">
                <apex:commandButton action="{!Cancel}" value="Cancel" />
                <apex:commandButton action="{!modal_add_row}" value="Add Contacts" reRender="modal" oncomplete="$('#myModal').modal({backdrop:'static'}).show(); return false;" />
                <apex:commandButton action="{!save_new_contacts}" reRender="main" value="Save" />
            </apex:pageBlockButtons>
            <apex:pageBlockSection columns="1">
                <apex:pageBlockTable value="{!existing_contacts}" var="c">
                    <apex:column value="{!c.FirstName}" />
                    <apex:column value="{!c.LastName}" />
                    <apex:column value="{!c.Email}" />
                </apex:pageBlockTable>
            </apex:pageBlockSection>
        </apex:pageBlock>

        <!--MODAL START -->
        <div id="myModal" class="modal slds-scope">
            <section role="dialog" tabindex="-1" class="slds-modal slds-fade-in-open slds-modal_medium" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1">
                <div class="slds-modal__container">
                    <header class="slds-modal__header">
                        <h2 id="modal-heading-01" class="slds-modal__title slds-hyphenate">Modal Header</h2>
                    </header>
                    <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
                        <apex:pageBlock id="modal" title="Add Contacts">
                            <apex:variable value="{!1}" var="sr" />
                            <apex:pageBlockTable value="{!new_contacts}" var="c">
                                <apex:column headerValue="Sr.">
                                    <apex:outputText value="{!sr}" />
                                </apex:column>
                                <apex:column headervalue="First Name">
                                    <apex:inputText value="{!c.FirstName}" />
                                </apex:column>
                                <apex:column headervalue="Last Name">
                                    <apex:inputText value="{!c.LastName}" />
                                </apex:column>
                                <apex:column headervalue="Email">
                                    <apex:inputText value="{!c.Email}" />
                                </apex:column>
                                <apex:column headerValue="Remove">
                                    <div style="width:20px;height:20px;overflow: hidden;margin-left: 25%;">
                                        <img decoding="async" title="Remove" style="cursor: pointer; max-width: fit-content;" src="/img/func_icons/util/trash20.gif" onclick="remove_Contact('{!sr-1}')" />
                                    </div>
                                    <apex:variable value="{!1+sr}" var="sr" />
                                </apex:column>
                            </apex:pageBlockTable>
                        </apex:pageBlock>
                        <table border="0" style="width:100%;" cellspacing="0" cellpadding="0">
                            <tr>
                                <td style="text-align:right !important;border:none !important;">
                                    <a class="labelClass" onclick="add_rows(); return false;">Add Rows</a>
                                </td>
                            </tr>
                        </table>
                    </div>
                    <footer class="slds-modal__footer">
                        <commandbutton class="slds-button slds-button_neutral" onclick="closeModal(); return false;">Cancel</commandbutton>
                        <commandbutton class="slds-button slds-button_brand" onclick="save_contacts(); return false;">Save</commandbutton>
                    </footer>
                </div>
            </section>
            <div class="slds-backdrop slds-backdrop_open"></div>
        </div>
        <script>
            function closeModal() {
                $('#myModal').modal('hide');
            }
        </script>
        <!--MODAL END -->

    </apex:form>
</apex:page></textarea></div><div class="fusion-text fusion-text-57"><p>Controller with comments:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-24 > .CodeMirror, .fusion-syntax-highlighter-24 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-24 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-24 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-24 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_24" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_24" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_24" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-php">public class Contacts_Controller {
    //Defining two lists for new and existing contacts
    public List <Contact> existing_contacts {get; set;}
    public List <Contact> new_contacts {get; set;}
    //Row index will be used to number rows in modal
    public Integer Row_Index {get; set;}
    //Account ID will be used for new contacts and for save button to return to Account record
    public id Acc_Id {get; set;}
    
    public Contacts_Controller(ApexPages.StandardController controller){
        //Here we basically set variables and get existing contacts
        new_contacts = new List <Contact>();
        Acc_Id = controller.getRecord().id;
        existing_contacts = [SELECT Id, FirstName, LastName, Email FROM Contact where AccountId =: Acc_Id];
    }
    
    public void modal_add_row() {
        /*
        Once you click on a button to add contacts it will pre-generate first record. If you click 
        add more contacts, it will reuse this function again.
		*/
        Contact c = new Contact();
        c.AccountId = Acc_Id;
        new_contacts.add(c);
    }
    
    public void modal_remove_contact(){
        //By knowing row index for each new contact, we can easily remove it from the list
        new_contacts.remove(Row_Index);
    }
    
    public void modal_save() {
        /*
        Here we add new contacts to already existing ones to display in the same table.
        Also, once contacts are added to the main list, new contacts list will be cleared,
        because we don't want these temporary records to be there once we revisit modal again.
		*/
        existing_contacts.addAll(new_contacts);
        new_contacts.clear();
    }
    
    public PageReference save_new_contacts() {
        
        //Defining a new list specifically for new contacts
        List <Contact> Insert_List = new List <Contact>();
        for(Contact c: existing_contacts){
            //Iterating over main list to find records without ID
            if(c.id == NULL){
                Insert_List.add(c);
            }
        }
        
        PageReference pageRef = new PageReference('/'+Acc_Id);
        //If there are records without ID, that means these are our new contacts.
        if(!Insert_List.isEmpty()){
            try{
                //Insert and return back to the Account page
                insert Insert_List;
        		return pageRef;
            } catch(Exception e){
                ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.Error,e.getMessage()));
            	return null;
            }
        }
        return pageRef;
    }
}</textarea></div><div class="fusion-text fusion-text-58"><p>If you did everything right, then when you click the button to add contacts, you should see something like this:</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-dropshadow imageframe-30 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Preview_with_Contact.jpg" class="fusion-lightbox" data-rel="iLightbox[c854bdde88aeaf4ffea]" data-title="Lightning Modal Preview with Contact" title="Lightning Modal Preview with Contact"><img decoding="async" width="1337" height="519" alt="Lightning Modal Preview with Contact" src="https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Preview_with_Contact.jpg" class="img-responsive wp-image-13762" srcset="https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Preview_with_Contact-200x78.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Preview_with_Contact-400x155.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Preview_with_Contact-600x233.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Preview_with_Contact-800x311.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Preview_with_Contact-1200x466.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Preview_with_Contact.jpg 1337w" sizes="(max-width: 1100px) 100vw, 1200px" /></a></span></div></div><div class="fusion-text fusion-text-59"><p>The last step would be to click &#8216;Save&#8217; on a page to save our new Contact in the database. You can obviously add more contacts as you need. You can even add multiple rows all at once.</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-dropshadow imageframe-31 hover-type-none fusion-animated" style="border-radius:5px;-webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);box-shadow: 3px 3px 7px rgba(0,0,0,0.3);" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Save_Contact.jpg" class="fusion-lightbox" data-rel="iLightbox[8429045d65449461dc0]" data-title="Lightning Modal Save Contact" title="Lightning Modal Save Contact"><img decoding="async" width="1348" height="366" alt="Lightning Modal Save Contact" src="https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Save_Contact.jpg" class="img-responsive wp-image-13763" srcset="https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Save_Contact-200x54.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Save_Contact-400x109.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Save_Contact-600x163.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Save_Contact-800x217.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Save_Contact-1200x326.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2020/05/Lightning_Modal_Save_Contact.jpg 1348w" sizes="(max-width: 1100px) 100vw, 1200px" /></a></span></div></div><div class="fusion-text fusion-text-60"><p>Once this is done, verify that new contact is actually saved.</p>
<h2>Final Thoughts</h2>
<p>I hope this guide helped you to learn something new. You can now relatively easily implement similar modals onto your VisualForce pages. If you know a better solution, feel free to leave a comment.</p>
<p>Stay tuned for other how-tos!</p>
</div><div class="fusion-clearfix"></div></div></div></div></div></p>
<p>The post <a href="https://www.tech-vision.us/salesforce-adding-lightning-modal-to-a-visualforce-page/">Salesforce | Adding Lightning Modal to a VisualForce Page</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.tech-vision.us/salesforce-adding-lightning-modal-to-a-visualforce-page/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
		<item>
		<title>Salesforce &#124; The Number of Business Hours Between Two Date/Time Fields</title>
		<link>https://www.tech-vision.us/salesforce-the-number-of-business-hours-between-two-date-time-fields/</link>
					<comments>https://www.tech-vision.us/salesforce-the-number-of-business-hours-between-two-date-time-fields/#comments</comments>
		
		<dc:creator><![CDATA[Oleksandr Makarenko]]></dc:creator>
		<pubDate>Fri, 25 Oct 2019 01:56:36 +0000</pubDate>
				<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Salesforce]]></category>
		<guid isPermaLink="false">https://www.tech-vision.us/?p=13668</guid>

					<description><![CDATA[<p>At times there is a need to calculate business hours spent on certain things in Salesforce. In following guide I'll explain how you can get the difference between two date/time fields relatively to your work hours and holiday schedule. Calculate Business Hours by Using Formula Fields Let's start from the basics. For a simple  [...]</p>
<p>The post <a href="https://www.tech-vision.us/salesforce-the-number-of-business-hours-between-two-date-time-fields/">Salesforce | The Number of Business Hours Between Two Date/Time Fields</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="fusion-fullwidth fullwidth-box fusion-builder-row-6 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-flex-wrap:wrap;" ><div class="fusion-builder-row fusion-row"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-5 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="--awb-bg-size:cover;"><div class="fusion-column-wrapper fusion-column-has-shadow fusion-flex-column-wrapper-legacy"><div class="fusion-text fusion-text-61"><p>At times there is a need to calculate business hours spent on certain things in Salesforce. In following guide I&#8217;ll explain how you can get the difference between two date/time fields relatively to your work hours and holiday schedule.</p>
<h2>Calculate Business Hours by Using Formula Fields</h2>
<p>Let&#8217;s start from the basics. For a simple calculation between two dates you could use the  following:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-25 > .CodeMirror, .fusion-syntax-highlighter-25 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-25 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-25 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-25 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_25" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_25" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_25" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh">Date_Field_1__c - Date_Field_2__c</textarea></div><div class="fusion-text fusion-text-62"><p>Formula above will return the number difference in days.</p>
<p>If you need to calculate the difference between two date/time fields you could use this:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-26 > .CodeMirror, .fusion-syntax-highlighter-26 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-26 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-26 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-26 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_26" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_26" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_26" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/jsx">IF(
  datetime_1 - datetime_2 > 0 ,
  TEXT( FLOOR( datetime_1 - datetime_2 ) ) & " days "
  & TEXT( FLOOR( MOD( (datetime_1 - datetime_2 ) * 24, 24 ) ) ) & " hours "
  & TEXT( ROUND( MOD( (datetime_1 - datetime_2 ) * 24 * 60, 60 ), 0 ) ) & " minutes",
  ""
)</textarea></div><div class="fusion-text fusion-text-63"><p>If you need to calculate business hours between two date/time fields the Salesforce formula becomes more complex.</p>
<p>Here is how it looks:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-27 > .CodeMirror, .fusion-syntax-highlighter-27 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-27 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-27 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-27 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_27" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_27" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_27" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/jsx">ROUND( 8 * (
   ( 5 * FLOOR( ( DATEVALUE( date/time_1 ) - DATE( 1900, 1, 8) ) / 7) +
    MIN(5, 
     MOD( DATEVALUE( date/time_1 ) - DATE( 1900, 1, 8), 7) +
     MIN( 1, 24 / 8 * ( MOD( date/time_1 - DATETIMEVALUE( '1900-01-08 16:00:00' ), 1 ) ) )
    ) 
   )
 -
   ( 5 * FLOOR( ( DATEVALUE( date/time_2 ) - DATE( 1900, 1, 8) ) / 7) +
     MIN( 5,
      MOD( DATEVALUE( date/time_2 ) - DATE( 1996, 1, 1), 7 ) +
      MIN( 1, 24 / 8 * ( MOD( date/time_2 - DATETIMEVALUE( '1900-01-08 16:00:00' ), 1) ) )
    )
   ) 
  ), 
0 )</textarea></div><div class="fusion-text fusion-text-64"><p>The good thing is that it&#8217;s easy to implement. You just need to replace &#8216;<strong>date/time</strong>&#8216; fields with yours.</p>
<p>All the above formulas are explained in developer documentation that can be found <a href="https://developer.salesforce.com/docs/atlas.en-us.usefulFormulaFields.meta/usefulFormulaFields/formula_examples_dates.htm" target="_blank" rel="noopener noreferrer">here</a>. Please take a moment to read and get familiar.</p>
<p>However, there are disadvantages to using such approach. The last formula does not take into consideration holidays, time zones, different work hours <em>(in case you have multiple locations)</em>.</p>
<p>Luckily there is a way around it. It is more complex, however, the results are more accurate. Instead of the formula field, we&#8217;ll use Apex Trigger. The <strong>BusinessHours Class</strong> should take care of all calculations. We just need to ensure that the data is valid.</p>
<p>For more info on BusinessHours class please click <a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_businesshours.htm" target="_blank" rel="noopener noreferrer">here</a>.</p>
<p>First, let&#8217;s add business hours to Salesforce. To do so, you need to go Setup -&gt; Start typing &#8216;business&#8217; in search bar.</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-none imageframe-32 hover-type-none fusion-animated" style="border-radius:5px;" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><img decoding="async" width="503" height="355" alt="Salesforce business Hours Setup" title="Salesforce business Hours Setup" src="https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_business_hours_setup.jpg" class="img-responsive wp-image-13671" srcset="https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_business_hours_setup-200x141.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_business_hours_setup-400x282.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_business_hours_setup.jpg 503w" sizes="(max-width: 1100px) 100vw, 503px" /></span></div></div><div class="fusion-sep-clear"></div><div class="fusion-separator fusion-full-width-sep" style="margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div><div class="fusion-sep-clear"></div>
<div class="fusion-text fusion-text-65"><p>Go ahead a click <strong>New Business Hours</strong> button. New window will open for you to specify the name, time zone and work hours for each day.</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-none imageframe-33 hover-type-none fusion-animated" style="border-radius:5px;" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_business_hours_add_more.jpg" class="fusion-lightbox" data-rel="iLightbox[96fb202d48e8ec15897]" data-title="Salesforce Business Hours Add More" title="Salesforce Business Hours Add More"><img decoding="async" width="1206" height="695" alt="Salesforce Business Hours Add More" src="https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_business_hours_add_more.jpg" class="img-responsive wp-image-13672" srcset="https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_business_hours_add_more-200x115.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_business_hours_add_more-400x231.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_business_hours_add_more-600x346.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_business_hours_add_more-800x461.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_business_hours_add_more-1200x692.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_business_hours_add_more.jpg 1206w" sizes="(max-width: 1100px) 100vw, 1200px" /></a></span></div></div><div class="fusion-sep-clear"></div><div class="fusion-separator fusion-full-width-sep" style="margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div><div class="fusion-sep-clear"></div>
<div class="fusion-text fusion-text-66"><p>For our example, let&#8217;s add one Business Hours Record and call it &#8216;<strong>Main Office</strong>&#8216;. Next we need to add holidays. To do so, go to <strong>Setup</strong> -&gt; Type in search bar &#8216;<strong>Holidays</strong>&#8216;.</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-none imageframe-34 hover-type-none fusion-animated" style="border-radius:5px;" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_setup.jpg" class="fusion-lightbox" data-rel="iLightbox[fa998bc51e9d70ba70c]" data-title="Salesforce Holidays Setup" title="Salesforce Holidays Setup"><img decoding="async" width="504" height="357" alt="Salesforce Holidays Setup" src="https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_setup.jpg" class="img-responsive wp-image-13676" srcset="https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_setup-200x142.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_setup-400x283.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_setup.jpg 504w" sizes="(max-width: 1100px) 100vw, 504px" /></a></span></div></div><div class="fusion-sep-clear"></div><div class="fusion-separator fusion-full-width-sep" style="margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div><div class="fusion-sep-clear"></div>
<div class="fusion-text fusion-text-67"><p>Click &#8216;New&#8217; button to add all necessary holidays. For each holiday there is an option to set it as recurring holiday. All the rest holidays that have different date each year need to be added separately.</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-none imageframe-35 hover-type-none fusion-animated" style="border-radius:5px;" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_more.jpg" class="fusion-lightbox" data-rel="iLightbox[ff4c7c59e279ef59126]" data-title="Salesforce Holidays Add More" title="Salesforce Holidays Add More"><img decoding="async" width="841" height="547" alt="Salesforce Holidays Add More" src="https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_more.jpg" class="img-responsive wp-image-13679" srcset="https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_more-200x130.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_more-400x260.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_more-600x390.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_more-800x520.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_more.jpg 841w" sizes="(max-width: 1100px) 100vw, 841px" /></a></span></div></div><div class="fusion-sep-clear"></div><div class="fusion-separator fusion-full-width-sep" style="margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div><div class="fusion-sep-clear"></div>
<div class="fusion-text fusion-text-68"><p>The last step here is to assign holidays to business hours. You just need to go back to business hours record that you&#8217;ve created earlier and add holidays. Go ahead and click Add/Remove button under Holidays related list to assign holidays to business hours.</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-none imageframe-36 hover-type-none fusion-animated" style="border-radius:5px;" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_to_hours.jpg" class="fusion-lightbox" data-rel="iLightbox[e0a4cca24903ab774da]" data-title="Salesforce Holidays Add to Business Hours" title="Salesforce Holidays Add to Business Hours"><img decoding="async" width="1656" height="634" alt="Salesforce Holidays Add to Business Hours" src="https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_to_hours.jpg" class="img-responsive wp-image-13699" srcset="https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_to_hours-200x77.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_to_hours-400x153.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_to_hours-600x230.jpg 600w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_to_hours-800x306.jpg 800w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_to_hours-1200x459.jpg 1200w, https://www.tech-vision.us/wp-content/uploads/2019/10/salesforce_holidays_add_to_hours.jpg 1656w" sizes="(max-width: 1100px) 100vw, 1200px" /></a></span></div></div><div class="fusion-sep-clear"></div><div class="fusion-separator fusion-full-width-sep" style="margin-left: auto;margin-right: auto;margin-top:30px;width:100%;"></div><div class="fusion-sep-clear"></div>
<div class="fusion-text fusion-text-69"><h2>Calculate Business Hours by Using Trigger (Single Location)</h2>
<p>Once all set, we are ready to move forward with our trigger. Let&#8217;s say we need to know how much time is spent on a case during business hours.</p>
<p>We&#8217;ll use the following fields:</p>
<ul>
<li><strong>Date/Time Open</strong> (<em>API &#8211; CreatedDate</em>)</li>
<li><strong>Date/Time Closed</strong> (<em>API &#8211; ClosedDate</em>)</li>
<li><strong>Elapsed Time</strong> (<em>API &#8211; Elapsed_Time__c</em>)</li>
</ul>
<p>For this example, our trigger will work on <strong>before update</strong> event type. At first, we need to select our default <strong>business hours</strong> record. If it has been found, it&#8217;s safe to proceed with the trigger.</p>
<p>Since Case <strong>Date/Time Opened</strong> field is actually<strong> CreatedDate, </strong>there is no need to validate if it&#8217;s empty<strong>.</strong> The date will be auto-generated when the case is created. We just need to make sure that <strong>Date/Time Closed</strong> (API &#8211; ClosedDate) is not empty and is updated. We don&#8217;t want a trigger to fire for other updates to a case.</p>
<p>Next, we&#8217;ll use BusinessHours Class to calculate time. The end result will be saved in the <strong>Elapsed Time</strong> custom field. Since the trigger is set on &#8216;<strong>before update</strong>&#8216;, there is no need to perform DML operation.</p>
<p>Trigger with comments is listed below:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-28 > .CodeMirror, .fusion-syntax-highlighter-28 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-28 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-28 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-28 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_28" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_28" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_28" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/jsx">trigger Business_Hours on Case (before update) {
    //Selecting default business hours (BH) record
    BusinessHours defaultBH = [SELECT Id FROM BusinessHours WHERE IsDefault = true Limit 1];
	//Making sure BH record exists
    if(defaultBH != NULL){
        for(Case caseObj : trigger.new ){
			//Making sure that closed date field is populated and is updated
            if(caseObj.ClosedDate != NULL && Trigger.oldMap.get(caseObj.Id).ClosedDate != caseObj.ClosedDate){
				//For BH method we assign (BH record id, start time field, end time field)
				decimal result = BusinessHours.diff(defaultBH.Id, caseObj.CreatedDate, caseObj.ClosedDate );
				//Result from the method is divided by 60*60*100 (milliseconds to be then converted into hours)
				Decimal resultingHours = result/(60*60*1000);
				//Populating result into our custom field & setting number of decimals
				caseObj.Elapsed_Time__c = resultingHours.setScale(1); 
            }  
        }    
    } 
}</textarea></div><div class="fusion-text fusion-text-70"><h2>Calculate Business Hours by Using Trigger (Multiple Locations)</h2>
<p>Let&#8217;s take another example with multiple business hours. This is helpful if you have different locations. Also, let&#8217;s say we want to calculate business hours on <strong>update</strong> &amp; <strong>insert</strong> .</p>
<p>The &#8216;Case&#8217; object will not be best for this example, so let&#8217;s just use a <strong>custom object</strong>. Each record should be tied to a specific location. That way it will be possible to calculate business hours for each place. If you use the same locations for other objects, it is wise to use a lookup that points to a location record itself. If not, the location field can be a simple picklist.</p>
<ul>
<li>Object name: <strong>Custom Object</strong> (<em>API Custom_Object__c</em>);</li>
<li>Date/Time field: <strong>Start Time</strong> (<em>API Start_Time__c</em>);</li>
<li>Date/Time field: <strong>Completed Time</strong> (<em>API Completed_Time__c</em>);</li>
<li>Date/Time field: <strong>Hours Spent</strong> (<em>Hours_Spent__c</em>);</li>
<li>Picklist field: <strong>Location</strong> (<em>API Location__c</em>) OR Formula Text field: (<em>API Location__c</em>). A formula should return location name as text. For example: <strong>Location__r.Name</strong></li>
</ul>
<p>Let&#8217;s also add business hours for different locations. For example: Chicago, New York, Lost Angeles. Please note that Location names should match Business Hours names.</p>
<p>The trigger itself will be very similar to the previous version.  The core logic stays the same, we just add separate rules for insert and update operations. Also, we add Map to hold all of our business hour records. The key for this map will be the location name. As you remember, we name business hours the same as locations. That way we can easily cross-reference location to business hours record and do the math.</p>
<p>If its insert, we want to make sure that<strong> Start Time</strong> and <strong>Completed Time</strong> fields are not empty. Because it will not make sense to do the calculation. For update operation, we also check if fields are not NULL and if they were changed.</p>
<p>Please take a look at trigger below. Comments should help you out with understanding the flow.</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-29 > .CodeMirror, .fusion-syntax-highlighter-29 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-29 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-29 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-29 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_29" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_29" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_29" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/jsx">trigger Business_Hours on Custom_Object__c (before insert, before update) {
	//Selecting all active BusinessHours records
	List<BusinessHours> BusinessHours_List = [SELECT Id, Name FROM BusinessHours WHERE IsActive = true];
	//Adding map where BusinessHours Name will be the key
	Map<String, BusinessHours> LocationName_BusinessHours_Map = new Map<String, BusinessHours> ();
	//Filling the map | Location Name, BusinessHours Object
	for (BusinessHours b : BusinessHours_List) {
		LocationName_BusinessHours_Map.put(b.Name, b);
	}
	for (Custom_Object__c c : Trigger.new) {
        //This part of a trigger only works when we add new records
		if (Trigger.isInsert) {
			//We check if both Start Time & Completed Time fields are not empty
            if (c.Start_Time__c != NULL && c.Completed_Time__c != NULL) {
				//Then we do another check if current record is tied to a location that has business hours record
                if (LocationName_BusinessHours_Map.containsKey(c.Location__c)) {
                    decimal result = BusinessHours.diff(LocationName_BusinessHours_Map.get(c.Location__c).Id, c.Start_Time__c, c.Completed_Time__c);
                    Decimal resultingHours = result / (60 * 60 * 1000);
                    c.Hours_Spent__c = resultingHours.setScale(1);
                } else{
					//Just as a safety net, let's use default business hours in case there is no match between Location name and BH name
					if(LocationName_BusinessHours_Map.get('Default').Id != NULL){
						decimal result = BusinessHours.diff(LocationName_BusinessHours_Map.get('Default').Id, c.Start_Time__c, c.Completed_Time__c);
						Decimal resultingHours = result / (60 * 60 * 1000);
						c.Hours_Spent__c = resultingHours.setScale(1);
					}
				}
            }
        } else if (Trigger.isUpdate) {
			//This part of a trigger only works when we perform update
			//Checking if Start Time or Completed Time has been changed & if they are not empty
			if ((c.Start_Time__c != NULL && c.Completed_Time__c != NULL) && ((c.Start_Time__c != Trigger.oldMap.get(c.id).Start_Time__c) || (c.Completed_Time__c != Trigger.oldMap.get(c.id).Completed_Time__c))) {
                if (LocationName_BusinessHours_Map.containsKey(c.Location__c)) {
                    decimal result = BusinessHours.diff(LocationName_BusinessHours_Map.get(c.Location__c).Id, c.Start_Time__c, c.Completed_Time__c);
                    Decimal resultingHours = result / (60 * 60 * 1000);
                    c.Hours_Spent__c = resultingHours.setScale(1);
                } else{
					if(LocationName_BusinessHours_Map.get('Default').Id != NULL){
						decimal result = BusinessHours.diff(LocationName_BusinessHours_Map.get('Default').Id, c.Start_Time__c, c.Completed_Time__c);
						Decimal resultingHours = result / (60 * 60 * 1000);
						c.Hours_Spent__c = resultingHours.setScale(1);
					}
				}
            } else if (c.Start_Time__c == NULL || c.Completed_Time__c == NULL) {
				//Another safety net that will reset Hours spent in case Start Time OR Completed time becomes empty after update.
				//That way you won't have old & inaccurate data from past calculations.
                c.Hours_Spent__c = NULL;
            }
        }
    }
}</textarea></div><div class="fusion-text fusion-text-71"><p>The trigger is ready to go. You just need to replace object and field APIs with your&#8217;s. I&#8217;m hoping you&#8217;ve learned something new today. Now you should be able to calculate number of business hours spent between two date/time fields in Salesforce. Please let me know if there is an easier way to do this. Feel free to post your suggestions!</p>
<p><strong>Test Class Update:</strong></p>
<p>Here is a very basic test class that I&#8217;ve put together. As is it will cover about 57% of the code.</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-30 > .CodeMirror, .fusion-syntax-highlighter-30 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-30 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-30 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-30 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_30" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_30" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_30" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/jsx">@isTest
public class Business_Hours_Test {
    static testMethod void Main_Test(){
        Case c = new Case();
        c.Status='New';
        insert c;
        
        test.startTest();
        c.Status = 'Closed';
        update c;        
        test.stopTest();
    }
}</textarea></div><div class="fusion-text fusion-text-72"><p>The reason is that <strong>ClosedDate</strong> on the <strong>Case</strong> object won&#8217;t populate when changing the <strong>Status</strong> field on &#8216;<strong>before update</strong>&#8216; trigger. The simplest workaround would be to set a trigger to work on &#8216;<strong>after update</strong>&#8216;. But in this case, you&#8217;ll have to consume SOQL query to get the case record &amp; perform DML (update operation).</p>
<p>Feel free to comment if you have any suggestions!</p>
</div><div class="fusion-clearfix"></div></div></div></div></div></p>
<p>The post <a href="https://www.tech-vision.us/salesforce-the-number-of-business-hours-between-two-date-time-fields/">Salesforce | The Number of Business Hours Between Two Date/Time Fields</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.tech-vision.us/salesforce-the-number-of-business-hours-between-two-date-time-fields/feed/</wfw:commentRss>
			<slash:comments>26</slash:comments>
		
		
			</item>
		<item>
		<title>Salesforce &#124; The Easiest Way to Write IF Formulas</title>
		<link>https://www.tech-vision.us/salesforce-the-easiest-way-to-write-if-formulas/</link>
					<comments>https://www.tech-vision.us/salesforce-the-easiest-way-to-write-if-formulas/#comments</comments>
		
		<dc:creator><![CDATA[Oleksandr Makarenko]]></dc:creator>
		<pubDate>Wed, 02 Oct 2019 03:13:51 +0000</pubDate>
				<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Salesforce]]></category>
		<guid isPermaLink="false">https://www.tech-vision.us/?p=13625</guid>

					<description><![CDATA[<p>Hi there! Today, I'd like to share the easiest way to write IF formulas in Salesforce. This became an issue because at some point I've been spending too much time on them. In most cases it was eaither missing parentheses or else statement. Epecially when formula field has been written by some one else  [...]</p>
<p>The post <a href="https://www.tech-vision.us/salesforce-the-easiest-way-to-write-if-formulas/">Salesforce | The Easiest Way to Write IF Formulas</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="fusion-fullwidth fullwidth-box fusion-builder-row-7 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-flex-wrap:wrap;" ><div class="fusion-builder-row fusion-row"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-6 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="--awb-bg-size:cover;"><div class="fusion-column-wrapper fusion-column-has-shadow fusion-flex-column-wrapper-legacy"><div class="fusion-text fusion-text-73"><p>Hi there! Today, I&#8217;d like to share the easiest way to write IF formulas in Salesforce. This became an issue because at some point I&#8217;ve been spending too much time on them. In most cases it was eaither missing parentheses or else statement. Epecially when formula field has been written by some one else and you have to update it.</p>
<h2>Step 1: Understanding IF Formulas</h2>
<p>So here is the basic IF formula:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-31 > .CodeMirror, .fusion-syntax-highlighter-31 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-31 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-31 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-31 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_31" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_31" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_31" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh">IF(logical_test, value_if_true, value_if_false)</textarea></div><div class="fusion-text fusion-text-74"><p>Please also take a look at the help section from Salesforce located <a href="https://help.salesforce.com/articleView?id=customize_functions_i_z.htm&amp;type=5" target="_blank" rel="noopener noreferrer">here</a>.</p>
<p>So from the example above we test if certain condition evaluates to true, the formula will return &#8216;<strong>value_if_true</strong>&#8216;, otherwise it will return &#8216;<strong>value_if_false</strong>&#8216;.</p>
<p>Here is exact same formula but in graphic:</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-max-width:64%;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-none imageframe-37 hover-type-none" style="border-radius:5px;"><a href="https://www.tech-vision.us/wp-content/uploads/2019/10/basic-if-else-formula-large.png" class="fusion-lightbox" data-rel="iLightbox[076df7554d8bd3cdfa6]" data-title="Salesforce Basic If Else Formula" title="Salesforce Basic If Else Formula"><img decoding="async" width="950" height="365" alt="Salesforce Basic If Else Formula" src="https://www.tech-vision.us/wp-content/uploads/2019/10/basic-if-else-formula-large.png" class="img-responsive wp-image-13630" srcset="https://www.tech-vision.us/wp-content/uploads/2019/10/basic-if-else-formula-large-200x77.png 200w, https://www.tech-vision.us/wp-content/uploads/2019/10/basic-if-else-formula-large-400x154.png 400w, https://www.tech-vision.us/wp-content/uploads/2019/10/basic-if-else-formula-large-600x231.png 600w, https://www.tech-vision.us/wp-content/uploads/2019/10/basic-if-else-formula-large-800x307.png 800w, https://www.tech-vision.us/wp-content/uploads/2019/10/basic-if-else-formula-large.png 950w" sizes="(max-width: 1100px) 100vw, 950px" /></a></span></div></div><div class="fusion-text fusion-text-75"><p>Let&#8217;s write a basic formula as an example. Say we have the following fields:</p>
<p><strong>Invoice Due Date</strong> (Type: Date Formula) &#8211; this is where we&#8217;ll display the result;<br />
<strong>Custom Checkbox</strong> (Type: Checkbox) &#8211; Custom_checkbox__c;<br />
<strong>Delivery Date</strong> (Type: Date) &#8211; Delivery_Date__c;</p>
<p>We have the requirement to determine what will be our &#8216;<strong>Invoice Due Date</strong>&#8216;. If &#8216;<strong>Delivery Date</strong>&#8216; is not empty, then &#8216;<strong>Invoice Due Date</strong>&#8216; formula should display the &#8216;<strong>Delivery Date</strong>&#8216;. Otherwise, it will display nothing.</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-32 > .CodeMirror, .fusion-syntax-highlighter-32 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-32 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-32 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-32 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_32" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_32" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_32" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh">if(NOT(ISBLANK(Delivery_Date__c )), Delivery_Date__c , NULL)</textarea></div><div class="fusion-text fusion-text-76"><h2>Step 2: How to do Multiple IF ELSE Statements In a Formula Field?</h2>
<p>Let&#8217;s try to model the situation where we need to have multiple if-else conditions in our formula.</p>
<p>As an example: if a &#8216;<strong>Delivery Date</strong>&#8216; is not empty then show &#8216;<strong>Delivery Date</strong>&#8216;. If &#8216;<strong>Delivery Date</strong>&#8216; AND &#8216;<strong>Custom Checkbox</strong>&#8216; is checked, then add 10 more days to an &#8216;<strong>Invoice Due Date</strong>&#8216;</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-max-width:64%;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-none imageframe-38 hover-type-none" style="border-radius:5px;"><a href="https://www.tech-vision.us/wp-content/uploads/2019/10/advanced-if-else-formula-large.png" class="fusion-lightbox" data-rel="iLightbox[644e589c76b0671f67e]" data-title="Advanced If Else Salesforce Formula" title="Advanced If Else Salesforce Formula"><img decoding="async" width="1207" height="625" alt="Advanced If Else Salesforce Formula" src="https://www.tech-vision.us/wp-content/uploads/2019/10/advanced-if-else-formula-large.png" class="img-responsive wp-image-13639" srcset="https://www.tech-vision.us/wp-content/uploads/2019/10/advanced-if-else-formula-large-200x104.png 200w, https://www.tech-vision.us/wp-content/uploads/2019/10/advanced-if-else-formula-large-400x207.png 400w, https://www.tech-vision.us/wp-content/uploads/2019/10/advanced-if-else-formula-large-600x311.png 600w, https://www.tech-vision.us/wp-content/uploads/2019/10/advanced-if-else-formula-large-800x414.png 800w, https://www.tech-vision.us/wp-content/uploads/2019/10/advanced-if-else-formula-large-1200x621.png 1200w, https://www.tech-vision.us/wp-content/uploads/2019/10/advanced-if-else-formula-large.png 1207w" sizes="(max-width: 1100px) 100vw, 1200px" /></a></span></div></div><div class="fusion-text fusion-text-77"><p>So this time, when first criteria evaluates to true I have to add another IF statement. For our second IF rule we no longer need to check if &#8216;<strong>Delivery Date&#8217;</strong> is not empty because its already verified in first IF satement.</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-33 > .CodeMirror, .fusion-syntax-highlighter-33 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-33 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-33 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-33 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_33" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_33" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_33" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh">if(NOT(ISBLANK(Delivery_Date__c )), IF(Logical_test, value_if_true, value_if_false) , NULL)</textarea></div><div class="fusion-text fusion-text-78"><p>OR</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-34 > .CodeMirror, .fusion-syntax-highlighter-34 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-34 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-34 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-34 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_34" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_34" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_34" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh">if(NOT(ISBLANK(Delivery_Date__c )), IF(Custom_Checkbox__c = true, Delivery_Date__c +10, Delivery_Date__c) , NULL)</textarea></div><div class="fusion-text fusion-text-79"><p>Obviouslty you may have as many IF satements as you want. You are only limited by the formula size.</p>
<h2>Step 3: Best Practice On Writing IF Formulas</h2>
<p>When the formula gets more and more IF statements it gets hard to track all the parentheses and else statements. For that reason I&#8217;m suggesting to use universal variable &#8211; <strong>NULL</strong>.</p>
<p>A<strong> NULL</strong> variable can temporarily fill the void in formula until you figure out the necessary condition.</p>
<p>Let&#8217;s take as a exmple our previous formula. We knew from the beginning that our first TRUE statement will be broken down into another IF. So let&#8217;s see how it&#8217;d look like with NULLs:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-35 > .CodeMirror, .fusion-syntax-highlighter-35 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-35 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-35 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-35 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_35" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_35" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_35" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh">if(NOT(ISBLANK(Delivery_Date__c )), IF(Custom_Checkbox__c = true, NULL, NULL) , NULL)</textarea></div><div class="fusion-text fusion-text-80"><p>Let&#8217;s add one more IF to our first FALSE value:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-36 > .CodeMirror, .fusion-syntax-highlighter-36 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-36 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-36 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-36 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_36" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_36" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_36" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh">if(NOT(ISBLANK(Delivery_Date__c )), IF(Custom_Checkbox__c = true, NULL, NULL) , if(Custom_Checkbox__c = false, NULL, NULL))</textarea></div><div class="fusion-text fusion-text-81"><p>The formula will always validate because you already have all 3 components set for each IF. And in case you&#8217;ve missed coma or something, you can always do a step back.</p>
<p>With this approach, you don&#8217;t have to worry about syntax that much. You just need to enter TRUE/FALSE values in place of <strong>NULL</strong>.</p>
<p>And again, the trick here is to pre-build a formula with <strong>NULL</strong> values for all TRUE/FALSE conditions. Once done, replace all necessary <strong>NULL</strong>s with actual values.</p>
<p>I&#8217;m hoping this method can save you some time while working with IF type formulas.</p>
</div><div class="fusion-clearfix"></div></div></div></div></div></p>
<p>The post <a href="https://www.tech-vision.us/salesforce-the-easiest-way-to-write-if-formulas/">Salesforce | The Easiest Way to Write IF Formulas</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.tech-vision.us/salesforce-the-easiest-way-to-write-if-formulas/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Salesforce &#124; Render VisualForce Block if Subquery List Size &gt; 0</title>
		<link>https://www.tech-vision.us/salesforce-render-visualforce-block-if-subquery-list-size-0/</link>
					<comments>https://www.tech-vision.us/salesforce-render-visualforce-block-if-subquery-list-size-0/#respond</comments>
		
		<dc:creator><![CDATA[Oleksandr Makarenko]]></dc:creator>
		<pubDate>Sun, 22 Sep 2019 17:45:38 +0000</pubDate>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Salesforce]]></category>
		<guid isPermaLink="false">https://www.tech-vision.us/?p=13587</guid>

					<description><![CDATA[<p>At certain times there is a need to conditionally render visaulforce content on your layouts. In Salesforce such places couble be VisalForce pages, email templates. Before writing custom controllers, let's check if we can resolve the issue with standard tools. Step 1: Create a VisualForce Page As an example, let's use Accounts and Contacts.  [...]</p>
<p>The post <a href="https://www.tech-vision.us/salesforce-render-visualforce-block-if-subquery-list-size-0/">Salesforce | Render VisualForce Block if Subquery List Size &gt; 0</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="fusion-fullwidth fullwidth-box fusion-builder-row-8 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-flex-wrap:wrap;" ><div class="fusion-builder-row fusion-row"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-7 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="--awb-bg-size:cover;"><div class="fusion-column-wrapper fusion-column-has-shadow fusion-flex-column-wrapper-legacy"><div class="fusion-text fusion-text-82"><p>At certain times there is a need to conditionally render visaulforce content on your layouts. In Salesforce such places couble be VisalForce pages, email templates. Before writing custom controllers, let&#8217;s check if we can resolve the issue with standard tools.</p>
<h2>Step 1: Create a VisualForce Page</h2>
<p>As an example, let&#8217;s use Accounts and Contacts. On our page, we&#8217;d like to show a table with contacts if they exist under the account. If there are no contacts under the account, we&#8217;ll show a message that there are no related contacts for this account.</p>
<p>Here is our page as an example:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-37 > .CodeMirror, .fusion-syntax-highlighter-37 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-37 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-37 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-37 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_37" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_37" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_37" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh"><apex:page standardController="Account" lightningStylesheets="true">
    <apex:form style="width:564px;margin:100px auto;">
       <apex:pageBlock title="Accounts & Contacts">
           <apex:pageBlockSection showHeader="false">
               <apex:outputField value="{!account.name}"/>
           </apex:pageBlockSection>
           <apex:pageBlockSection columns="1" title="Related Contacts">
               <apex:pageBlockTable value="{!Account.contacts}" var="ct">
                   <apex:column value="{!ct.name}"/>
                   <apex:column value="{!ct.phone}"/>
               </apex:pageBlockTable>
           </apex:pageBlockSection>
       </apex:pageBlock>
    </apex:form>
</apex:page></textarea></div><div class="fusion-text fusion-text-83"><p>To render the page, simply click &#8216;Preview&#8217; button after its saved. It will open a new tab.</p>
<blockquote>
<p>Most likely you&#8217;ll see empty form. This is because your page is not tied to any of the accounts. To fix that simply add</p>
<p>?id=XXXXXXXXXXXXXXXXXX</p>
<p>where XXXXXXXXXXXXXXXXXX is the ID of one of your accounts.</p>
<p>Full URL will look like: https://c.c23.visual.force.com/apex/vf_page_name?id=XXXXXXXXXXXXXXXXXX</p>
</blockquote>
<p>Alright, so once done this page will look like this:</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-none imageframe-39 hover-type-none fusion-animated" style="border-radius:5px;" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-sample-page.jpg" class="fusion-lightbox" data-rel="iLightbox[5bb40adce3278828511]" data-title="Visualforce Sample Page" title="Visualforce Sample Page"><img decoding="async" width="573" height="270" alt="Visualforce Sample Page" src="https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-sample-page.jpg" class="img-responsive wp-image-13600" srcset="https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-sample-page-200x94.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-sample-page-400x188.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-sample-page.jpg 573w" sizes="(max-width: 1100px) 100vw, 573px" /></a></span></div></div><div class="fusion-text fusion-text-84"><h2>Step 2: Add Variable to Count Related Records</h2>
<p>Now, we just need to find out what is the count of related contacts. To do so, we&#8217;ll use apex variable with apex repeat. Let&#8217;s say our variable will have a name &#8216;<strong>count</strong>&#8216; with initial value &#8216;0&#8217;.</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-38 > .CodeMirror, .fusion-syntax-highlighter-38 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-38 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-38 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-38 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_38" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_38" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_38" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh"><apex:variable var="count" value="{!0}"/></textarea></div><div class="fusion-text fusion-text-85"><p>More about variables you can read <a href="https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_variable.htm" target="_blank" rel="noopener noreferrer">here</a>.</p>
<p>Now we just need to iterate through all related records and increment our variable by 1 for each record. To do so, we&#8217;ll use &#8216;<strong>Apex Repeat</strong>&#8216;.</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-39 > .CodeMirror, .fusion-syntax-highlighter-39 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-39 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-39 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-39 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_39" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_39" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_39" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh"><apex:variable var="count" value="{!0}"/>
<apex:repeat value="{!Account.contacts}">
	<apex:variable var="count" value="{!count + 1}"/>
</apex:repeat></textarea></div><div class="fusion-text fusion-text-86"><p>Make sure to add variable before block with related contacts. That way we first get the count of related records. After that we can render other blocks.</p>
<p>So our updated page will have the following look:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-40 > .CodeMirror, .fusion-syntax-highlighter-40 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-40 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-40 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-40 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_40" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_40" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_40" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh"><apex:page standardController="Account" lightningStylesheets="true">
    <apex:form style="width:564px;margin:100px auto;">
       <apex:pageBlock title="Accounts & Contacts">
           <apex:pageBlockSection showHeader="false">
               <apex:outputField value="{!account.name}"/>
           </apex:pageBlockSection>
           <apex:variable var="count" value="{!0}"/>
           <apex:repeat value="{!Account.contacts}">
               <apex:variable var="count" value="{!count + 1}"/>
           </apex:repeat>
           size is {!count}
           <apex:pageBlockSection columns="1" title="Related Contacts">
               <apex:pageBlockTable value="{!Account.contacts}" var="ct" >
                   <apex:column value="{!ct.name}"/>
                   <apex:column value="{!ct.phone}"/>
               </apex:pageBlockTable>
           </apex:pageBlockSection>
       </apex:pageBlock>
    </apex:form>
</apex:page></textarea></div><div class="fusion-text fusion-text-87"><p>As you may&#8217;ve noticed, I&#8217;ve added one more line that is &#8216;<strong>size is {!count}</strong>&#8216;. This is just to double check if our added variable works. After previewing you should see the following:</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-none imageframe-40 hover-type-none fusion-animated" style="border-radius:5px;" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-sample-page-with-size.jpg" class="fusion-lightbox" data-rel="iLightbox[c2ea200e5c28c2caf21]" data-title="Visualforce Sample Page With Size" title="Visualforce Sample Page With Size"><img decoding="async" width="573" height="287" alt="Visualforce Sample Page With Size" src="https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-sample-page-with-size.jpg" class="img-responsive wp-image-13607" srcset="https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-sample-page-with-size-200x100.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-sample-page-with-size-400x200.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-sample-page-with-size.jpg 573w" sizes="(max-width: 1100px) 100vw, 573px" /></a></span></div></div><div class="fusion-text fusion-text-88"><h2>Step 3: Add &#8216;Renderer&#8217; Conditions to VF elements</h2>
<p>Since our account has just one contact, size will be shown as 1.</p>
<p>To conditionally render elements on our visualforce page we will use &#8216;Render&#8217; attribute. If we want to render contacts block if the number of contacts greater than 0, we need to use the following:</p>
<blockquote>
<p>rendered=&#8221;{!count &gt; 0}&#8221;</p>
</blockquote>
<p>If count is greater than 0, the formula will return &#8216;true&#8217;, otherwise, it will return &#8216;false&#8217;.</p>
<p>The next step is to add notice message that will notify user if there are no related contacts for this account. For this example, we&#8217;ll use the apex message, but feel free to use any other elements for your case.</p>
<p>For this notice message we&#8217;ll also use renderer attribute, but this time with the opposite criteria:</p>
<blockquote>
<p>rendered=&#8221;{!count == 0}&#8221;</p>
</blockquote>
<p>The final markup of the page will look the following:</p>
</div><style type="text/css" scopped="scopped">.fusion-syntax-highlighter-41 > .CodeMirror, .fusion-syntax-highlighter-41 > .CodeMirror .CodeMirror-gutters {background-color:var(--awb-color1);}.fusion-syntax-highlighter-41 > .CodeMirror .CodeMirror-gutters { background-color: var(--awb-color2); }.fusion-syntax-highlighter-41 > .CodeMirror .CodeMirror-linenumber { color: var(--awb-color8); }</style><div class="fusion-syntax-highlighter-container fusion-syntax-highlighter-41 fusion-syntax-highlighter-theme-dark" style="opacity:0;margin-top:0px;margin-right:0px;margin-bottom:20px;margin-left:0px;font-size:14px;border-width:1px;border-style:solid;border-color:#e0dede;"><div class="syntax-highlighter-copy-code"><span class="syntax-highlighter-copy-code-title" data-id="fusion_syntax_highlighter_41" style="font-size:14px;">Copy to Clipboard</span></div><label for="fusion_syntax_highlighter_41" class="screen-reader-text">Syntax Highlighter</label><textarea class="fusion-syntax-highlighter-textarea" id="fusion_syntax_highlighter_41" data-readOnly="nocursor" data-lineNumbers="1" data-lineWrapping="" data-theme="oceanic-next" data-mode="text/x-sh"><apex:page standardController="Account" lightningStylesheets="true">
    <apex:form style="width:564px;margin:100px auto;">
       <apex:pageBlock title="Accounts & Contacts">
           <apex:pageBlockSection showHeader="false">
               <apex:outputField value="{!account.name}"/>
           </apex:pageBlockSection>
           <apex:variable var="count" value="{!0}"/>
           <apex:repeat value="{!Account.contacts}">
               <apex:variable var="count" value="{!count + 1}"/>
           </apex:repeat>
           size is {!count}
           <apex:pageMessage summary="Account has no contacts" severity="warning" rendered="{!count == 0}" />
           <apex:pageBlockSection columns="1" title="Related Contacts" rendered="{!count > 0}">
               <apex:pageBlockTable value="{!Account.contacts}" var="ct">
                   <apex:column value="{!ct.name}"/>
                   <apex:column value="{!ct.phone}"/>
               </apex:pageBlockTable>
           </apex:pageBlockSection>
       </apex:pageBlock>
    </apex:form>
</apex:page></textarea></div><div class="fusion-text fusion-text-89"><p>In case our account does not have related contacts, apex visualforce page will look this way:</p>
</div><div class="fusion-image-element fusion-image-align-center in-legacy-container" style="text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);"><div class="imageframe-align-center"><span class=" fusion-imageframe imageframe-none imageframe-41 hover-type-none fusion-animated" style="border-radius:5px;" data-animationType="slideInLeft" data-animationDuration="0.3" data-animationOffset="top-into-view"><a href="https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-page-message.jpg" class="fusion-lightbox" data-rel="iLightbox[1bd88e93348f48a3efa]" data-title="Visualforce Page Message" title="Visualforce Page Message"><img decoding="async" width="573" height="264" alt="Visualforce Page Message" src="https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-page-message.jpg" class="img-responsive wp-image-13612" srcset="https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-page-message-200x92.jpg 200w, https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-page-message-400x184.jpg 400w, https://www.tech-vision.us/wp-content/uploads/2019/09/visualforce-page-message.jpg 573w" sizes="(max-width: 1100px) 100vw, 573px" /></a></span></div></div><div class="fusion-text fusion-text-90"><p>Now you&#8217;ve learned how to conditionally render certain blocks of your visualforce page based on count of the related records. Obviously, there could be all kinds of variations to rendered attribute. As an example, you could only count contacts that have email address.</p>
<p>All in all, we&#8217;d love to hear from you! Let us know your feedback &amp; If you have a better solution &#8211; feel free to comment!</p>
<p>Stay tuned for more awesome how to&#8217;s.</p>
</div><div class="fusion-clearfix"></div></div></div></div></div></p>
<p>The post <a href="https://www.tech-vision.us/salesforce-render-visualforce-block-if-subquery-list-size-0/">Salesforce | Render VisualForce Block if Subquery List Size &gt; 0</a> appeared first on <a href="https://www.tech-vision.us">Tech Vision - Salesforce Best Practices</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.tech-vision.us/salesforce-render-visualforce-block-if-subquery-list-size-0/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
