When Salesforce is life!

Category: Post Page 16 of 27

[Salesforce] Summer17 Awesome Features Selection

.summer17 .title{
font-size:16pt;
}
.summer17 a{
color:red;
}
.summer17 img{
max-width: 400px;
}

Salesforce Summer ’17 release notes have been online for weeks and now it’s my turn to show you my favourite ones.

I’ve been busy recently with my work but also for our first joint Milano & Cagliari Salesforce DUG and for the Milano Essentials 2017.

I presented a huge deck for Summer 17 at our first meetup: this deck is only a selection of the gigantic official release notes.

In this post I’ll highlight an even smaller selection of the amazing features we find in the next release of the platform we all love.

The release is centered on Lightning Experience and we can see all the efforts Salesorce is putting to make LEX becoming fully compliant (and better for sure) to Classic UI.

Restyled Lightning Experience Migration Assistant (Classic)

The first improvement is related to the new and restyled Migration Assistant:

The assistant is meant to help you gradually migrate to LEX highlighting:

  • Problems related to components that may not work in LEX (e.g. custom buttons, links, …)
  • A list of profiles that are more or less ready to switch to LEX
  • An extensive check list on the actions to be completed to enable LEX
  • A component to enable users to LEX on the fly

Users that cannot be switched don’t have the Lightning Experience User permission:

Once you are 100% sure that certain users cannot switch to Classi anymore, change their profiles or apply a permission set with the following permission:

Keyboard Shortcuts (LEX)

Press Ctrl + / or Cmd + / to show a popup with the most useful shortcuts for LEX or the Lightning Cloud Console:

LEX app

LEX Cloud Console

Simplified Favorites List (LEX)

The Favorites list has been improved and easily accessible on the global actions section of the main app:

External Search Engines with Federated Search (GA)

A new type of External Data Source has been added, allowing to use the Federated Search protocol: basically you can search from Salesforce Global Search into an external service.

The configuration is easy:

Streamlined Handling of Potential Duplicates (LEX)

Duplicate checking is enhanced in LEX.

Conigure your Matching Rule:

Activate the Duplicate Rule deciding whether record creation must be blocked or display only a warning upon duplicate found:

And this is the result:

Not Blocking:

Blocking:

If the rule matches to many record on current dataset (more than 100) the rule is not activated:

Person Accounts Show All Cases in Related Lists (LEX)

If a Case is related to a Person Account by AccountId or ContactId fields, then it is shown in the “Cases” related list on the Account.

Compact Case Feed (LEX)

Feeds can be filtered by type, nodes are closed by default but you can expande all nodes:

Create, Edit, Delete Case Comments (LEX)

Create your Case Comments directly from the publisher using a Quick Action.

View, Edit and Delete them from the Case Comments related list.

Partner Central Community Template

It’s been designed with PRM in mind.

  • Overview of entire partner life cycle
  • Partner recruitment, onboarding, channel sales, channel marketing in one place
  • Automate lead ditribution
  • Configure quick actions to get partners access to company’s channel sales pipeline
  • Share sales data in a central repository
    Integrates with Service Cloud features (partners can open cases)
  • Customize global search
  • Like other Lightning communities:
    • Build custom pages and use custom branding
    • Expose wathever CRM objects suites to your needs
    • Customize content on partner geo-location

Communities Workspaces

Enable Communities Workspace (from

Setup > Communities Settings

) to have a better place for managing your communities.

Connect Your Content Management System (CMS) to Your Community (Beta)

CMS Connect lets you bring your AEM content, such as headers, footers, and banners, into your community.

Dynamically render your components, CSS, and JavaScript on community pages for consistent branding, authentication, and ease of maintenance.

CMS Connect is available in communities that are based on Customer Service (Napili), Partner Central, and any Lightning Bolt solutions.

When creating a new CMS connection set the base CMS server url and a root path to configure language and components to access the
proper CMS artifacts:

Define the language you’ll be using on your site:

Define up to 10 CSS and 10 JS file per CMS connection:

By defining multiple CMS connections, define the load order (css and script files):

From the Community Builder you can now set the header and footer:

You can even import specific CMS components:

Communities fully supported by Change Sets

Change sets are now available for Lightning communities and Salesforce Tabs and Visualforce communities.

Create, customize, and test your community in your sandbox environment and then migrate the community to production when testing is complete.

Communities are located under the Network component type.

Keep in mind that:

  • you can only make updates with change sets, create the community in the target ORG first
  • When you deploy an inbound change set, it completely overwrites the community in the destination org (e.g. deletes pages)
  • Navigation Menu items are supported. However, for menu items that link to objects, list views are reset to the default list view. Also, custom list views for standard objects aren’t included as dependency
  • Community migration is also supported via the Metadata API

Analyze and Improve Community Performance (Dev Prev)

A new awesome Chrome Extension has been delivered to analyze Communities preformances, the Salesforce Community Page Optimizer.

  • Overall score against major Lightning best practices
  • Waterfall of network requests
  • Timelines gives a profile of each component’s rendering life
  • Memory Usage
  • Components displays the life cycle of each component, to target potential leaks or unexpected rendering behavior
  • Cost tab displays the amount of time each component was busy processing: the lower the better
  • List of all actions performed on the page, along with their timing information
Improve Community Performance with Browser Caching

f you use many components in your Lightning community, improve community performance with browser caching.

Performance is about the same for the first page load, but subsequent page loads are faster.

The cache is encrypted and secure.

Share Public Links to Your Files (LEX)

Create public links sharable outside the Community:

Chatter Rich Publisher Apps for Communities (Pilot)

Use Chatter Rich Publisher Apps to integrate your custom apps into the Chatter publisher and to view the app’s payload in a feed.

Enjoy More Room for Files

Attachments and Documents should be migrated to Salesforce Files in LEX.

To increase adoption, new limits have been pushed.

Previously, the maximum number of files per org was 10 million.

We’ve tripled this limit, raising it to 30 million.

The number of daily content versions (files that you can add or modify in a 24-hour period) has increased from 36,000 to 200,000.

The delivery bandwidth limit has doubled from 10 GB to 20 GB.

Open More Tabs from Setup with Right-Click (LEX)

Simple but usefull enhancements for Developers and admins: setup links can now be opened with right click.

Find Your Way to Object Manager More Quickly (LEX)

The Object Manager tab lets you access quick actions, recent list views, and recent items. It also gives you a shortcut to create a new object

Object setup pages have been enhanced as well: object details always visible, scrolling details page, quick find search.

Block Execution of JavaScript in the HYPERLINK Function (Critical Update)

You cannot execute JS on HYPERLINK function on formula fields anymore.

HYPERLINK("javascript:window.location.reload()","TEXT")

  • Custom button or link to execute onClick JavaScript.
    • See Custom Buttons or Links (Classic)
  • Lightning Experience Quick Action button.
    • Create JavaScript in a Lightning Experience component executed through a Quick Action button (LEX)
  • Custom Visualforce page with an Apex controller to redirect to the correct URL.
    • Take this approach if you can execute client-side conditional logic to redirect the user to where you want. Create an empty Visualforce page and an Apex controller.
      Pass the required values from the link to the controller. Then execute the logic to determine the URL in the controller method, to perform the redirect

Embed your Flows in Lightning Pages (GA)

There is a brand new (and GA) flow components on your Lightning App Builder:

Dynamically Update Flow Screen Fields (Pilot)

Turn your flows into guided UIs that respond to users’ inputs and selections: display fields based on defined conditions.

This lower the number of flow steps needed to implement your scripts.

New Time Field Type (Pilot)

The Time type tracks time or indicates date-independent time.

You can use it to indicate business hours, preferred contact times, repeated event times, …

The Time type is essentially a timestamp without the date included.

The Time type uses a 24-hour notation.

You can display time in HH:MM, for example, 14:40
Time can include milliseconds (HH:MM:SS.MS): e.g. 14:40:50.617.

Time values are not localized or associated with a time zone, e.g. if you enter 15:00, for 3 pm, all users see the same value.

Define Default Values at the Field Level for Picklists

Define a default formula to define a default value based on the context: if the formula returns a blank value, that the value default is used.

SAML Single Logout (SLO) Is Available (Beta)

If enabled, logging out of your org logs you out of all connected apps (where Salesforce is the Identity Provider and the connected apps are Service Providers).

Balance security and usability when determining whether to use it. Logging the user out of all connected apps improves security, but not necessarily usability.

Override Standard Actions with Lightning Components

Override View, New, Edit, and Tab object actions using Lightning components:

Overrides that use Lightning components don’t affect Salesforce Classic.

If you override a standard action with a Visualforce page, it overrides the action in Salesforce Classic, Lightning Experience, and Salesforce1.

If you override a standard action with a Lightning component, it overrides the action in Lightning Experience and Salesforce1, but the standard Salesforce page is used in Salesforce Classic.

A Lightning record page for an object takes precedence over an override of the object’s View action.

That is, if you override the View action for an object, and you also create and assign a Lightning record page for the object, the Lightning record page is used. The override has no effect. This is true whether the override uses a Lightning component or a Visualforce page

force:hasRecordId

Enable the component to be assigned the ID of the current record and adds the component’s attribute recordId.

force:hasSObjectName

Enable the component to be assigned the API name of current record’s sObject type and adds the component’s attribute sObjectName.

Lightning Data Service (Beta)

Use Lightning Data Service to load, create, edit, or delete a record in your component, without using Apex code.

  • Lightning Data Service handles sharing rules and field-level security for you.
  • Lightning Data Service also improves performance and user-interface consistency
    Use the new force:recordData component (force:recordPreview deprecated)
  • Target record complies with the UI API
  • targetFields shows a simplified version of the object and updates when the Lightning Data Service detects a record change
    e.g. v.targetFields.name is equivalent
    to v.targetRecord.fields.Name.value
Find Component Markup Errors Faster with Improved Error Messages

Display more details for Lightning component errors:

It’s now easier for your users to report errors they encounter, and for you to find and fix those errors.

This change affects all users, and doesn’t depend on debug mode being enabled.

The framework logs a browser console warning if your component has a JavaScript function (client-side action) with the same name as an Apex method (server-side action).

The warning is logged only in debug mode and can help in troubleshooting an otherwise hard-to-debug issue.

WARNING: Component 'c:myComponent' has server and client action name conflicts: handleMethod
Use the aura:valueRender Event Instead of a Custom Renderer

When a component is rendered or rerendered, the aura:valueRender event, also known as the render event, is fired.

Handle this event to perform post-processing on the DOM or react to component rendering or rerendering.

The event is preferred and easier to use than the alternative of creating a custom renderer file.

<aura:handler name="render" value="{!this}" action="{!c.onRender}" />
Streamlined Validity Checks for Components

  • If a component is invalid, cmp.get() returns null.

    Previously, the framework returned an InvalidComponent error.

  • If you call cmp.set() on an invalid component, nothing happens and no error occurs.
  • The cmp.isValid() call returns false for an invalid component.

    You don’t need a cmp.isValid() check in the callback in a client-side controller when you reference the component associated with the client-side controller. The framework automatically checks that the component is valid.

    Similarly, you don’t need a cmp.isValid() check during event handling or in a framework lifecycle hook, such as the init event. If you reference a component in asynchronous code, such as setTimeout() or setInterval(), or when you use Promises, a cmp.isValid() call checks that the component is still valid before processing the results of the asynchronous request.

    In many scenarios, the cmp.isValid() call isn’t necessary because a null check on a value retrieved from cmp.get() is sufficient.

    The main reason to call cmp.isValid() is if you’re making multiple calls against the component and you want to avoid a null check for each result.

Use Advanced PDF to Render Visualforce Pages as PDF Files (Pilot)

Advanced PDF renders Visualforce pages as PDF files with broader support for modern HTML standards, such as CSS3, JavaScript, and HTML5.

This change applies to both Lightning Experience and Salesforce Classic.

To use Advanced PDF, set renderAs=”advanced_pdf” in the tag of a Visualforce page with API version 40.0 or later.

Advanced PDF pages time out after rendering for 2 minutes, which includes asynchronous processing time.

Because Advanced PDF is built on Chromium, it’s easy to preview your Visualforce pages in Google Chrome. To preview a page, from Chrome, select File > Print.

Access Visualforce Page Metrics Using the SOAP API

Make a SOQL query in Workbench to get information from the VisualforceAccessMetrics object.

SELECT Id, ApexPageId, DailyPageViewCount, MetricsDate From VisualforceAccessMetrics

Each VisualforceAccessMetrics object tracks the daily page view count in the DailyPageViewCount field.

The date the metrics were collected is specified in MetricsDate, and the ID of the tracked Visualforce page is specified in ApexPageId.

Page views are tallied the day after the page is viewed, and each VisualforceAccessMetrics object is removed after 90 days.

Roll Back Changes in Your Org When Remote JavaScript Methods Throw Exceptions

When a JavaScript method in an Apex class calling a remote action throws an exception, the action isn’t completed.

Previously, when a method threw an exception, the action was completed.

For example, when you created an Apex class that used a remote action to add an account to your org and that method threw an exception, the account was added. Now, the account isn’t added.

With this enhancement, JavaScript remoting methods that throw exceptions no longer cause changes in your org.

Retrieve and Deploy Metadata in Apex

Access to Metadata in Apex with the Metadata Namespace.

Metadata is used for org settings that admins control, or configuration information applied by installed apps and packages.

Previously, accessing metadata required using the Metadata API, but you can now use classes in the Metadata namespace to access metadata components from Apex code.

Metadata access in Apex is currently limited to custom metadata records and page layouts. You can retrieve, create, or update custom metadata, but you cannot delete metadata through Apex.

Details on the features here.

Extended Deadline for TLS 1.0 Disablement in Communities

On July 22, 2017, Salesforce is disabling support for TLS 1.0 for all ORGs in production.

To give admins more time to prepare community users, the TLS 1.0 disablement deadline for Salesforce Communities has been extended to March 2018. The extended March 2018 deadline applies to both Lightning and Visualforce communities.

Partner portals, customer portals, and Force.com and Site.com sites are still subject to the July 2017 deadline.

All licensed and unlicensed community users (guest users) must upgrade to browsers that are compliant with TLS 1.1 or above.

Details on TLS1.0 retirement here.

Be prepared for the deactivation.

  • Add appropriate messaging to your communities to inform your users about TLS 1.0 disablement. Educate both licensed and guest users about browser requirements for TLS version compatibility.
  • Encourage users to check their browsers for compatibility with our test site. If their browser is compliant, the web site displays a “Test passed” message.
  • Ensure that the TLS 1.1 or above is enabled for your API integrations.
Critical Update Activation: LockerService in Communities

Critical update since Summer ’16, is enforced for all orgs in Summer ’17.

LockerService, a powerful security architecture for custom Lightning components, is enforced for all Lightning components created in Summer ’17 (API version 40.0) and later.

LockerService isn’t enforced for components with API version 39.0 and lower, which covers any component created before Summer ’17.

  • JavaScript ES5 Strict Mode Enforcement “use strict”
    • JavaScript strict mode makes code more robust and supportable, enforces errors if (e.g.):
      • You must declare variables with the var keyword
      • You must explicitly attach a variable to the window object to make the variable available outside a library
      • The libraries that your components use must also work in strict mode
  • DOM Access Containment
    • A component can only traverse the DOM and access elements created by a component in the same namespace. This behavior prevents the anti-pattern of reaching into DOM elements owned by components in another namespace
    • It’s an anti-pattern for any component to “reach into” another component, regardless of namespace. LockerService only prevents cross-namespace access. Your good judgment should prevent cross-component access within your own namespace as it makes components tightly coupled and more likely to break
  • Restrictions to Global References
    • LockerService applies restrictions to global references: window, element and document objects expose only a subset of their APIs, to guarantee DOM access containment and isolate components
    • Details here
  • Access to Supported JavaScript API Framework Methods Only
    • You can access published, supported JavaScript API framework methods only
    • Previously, unsupported methods were accessible, which exposed your code to the risk of breaking when unsupported methods were changed or removed

When a component is set to at least API version 40.0, which is the version for Summer ’17, LockerService is enabled.

LockerService is disabled for any component created before Summer ’17 because these components have an API version less than 40.0.

To disable LockerService for a component, set its API version to 39.0 or lower.

LockerService is enabled for a component or an application purely based on component version.
The containment hierarchy within an application or a component doesn’t factor into LockerService enforcement.

For consistency and ease of debugging, we recommend that you set the same API version for all components in your app, when possible.

[Salesforce / CloudConsole] How to get if a tab is the primary tab

This is a quick post for the future me that will be struggling with Cloud Console and tab handling.

I wanted to get it a tab is a primary tab, in order to decide whether to open a new page in a new primary tab or in a subtab.

The problem is that if you try to get the primary tab id of a primary tab with the

sforce.console.getEnclosingPrimaryTabId()

function and get the value with the

sforce.console.getEnclosingTabId()

(expecting the same value for primary tabs), we instead get different values, as if the primary tab is enclosed in a super primary tab.

To solve this problem, just get the page info details and check if the enclosing primary tab has the same URL of the enclosing tab, and that’s it:

function isPrimaryTab(callback){
  sforce.console.getEnclosingPrimaryTabId(function (result){
    currentPrimaryTabId = result.id;
    sforce.console.getEnclosingTabId(function (subtabResult){
        thisTabId = subtabResult.id;
        sforce.console.getPageInfo(currentPrimaryTabId, function(pageinfo1){
            sforce.console.getPageInfo(thisTabId, function(pageinfo2){
                return callback && callback(JSON.parse(pageinfo2.pageInfo).url === JSON.parse(pageinfo1.pageInfo).url);
            });
        });
    }); 
  });
});

isPrimaryTab(function(result){
   alert(((result)?'IT IS':'IT IS NOT') + ' A PRIMARY TAB!');
});

[Salesforce / Lightning] Simple Custom Modal Alert

Hello everybody!

This is an “easy peasy” post that comes from a recent two-weeks full immersion on Lightning Components task I got into at work: there will be more content from this activity and a Cagliari DG presentation as well.

For all the TL;DR guys (and again, I’m one of you!), here is the Github Repository.

The Alert Modal shows an alert modal through a custom event fired from your Lightning components:

var evt = $A.get("e.c:AlertEvt");
        evt.setParams({
            "show": true,                     //shos alert
            "mode": 'prompt',                 //alert mode: prompt, alert, toast
            "fixed": false,                   //fixed does not shows any "close" button
            "type": 'info',                   //type of alert: info, success, warning, error
            "message": 'Title Message',       //main title
            "details": 'Message Details. . .' //details message
        });
        evt.fire();

The event is caught up by the AlertCmp Lightning component that shows the request alert:

Besides the prompt mode, you can use the alert mode:

And a toast mode:

You can test the component in the provided Lightning app:

[Salesforce] ORGanizer Chrome Extension 0.6 is Live!

h1.chapter-title{
font-size:20pt;
}
div.post-content a{
color: blue;
font-weight: bold;
}

Another release is on its way!

You should receive the update in the next hours.

Which amazing features have been packed?

And other important enhancements:

  • Show line and column number on Quick Query, Execute Anonymous and Enhanced Formula editors:

  • Drag the Quick Console from the footer:

  • Resize editor’s textarea in Quick Query, Execute anonymous and Enhanced Formula Editor plugins:

  • Make lookup field clickable on query results (not only ID field):

  • Download child query result in JSON / CSV format (previously you could only download the main query results)
  • Child queries result now shows correctly all results (previously was limited to 10)

THE SWAG STORE

Do you know ORGanizer is free for all, right?

You can help me keeping it free forever by offering me a pizza or a cappuccino or … drumroll… buying stuff from the brand new ORGanizer Swag Store!

The store is hosted by Zazzle.com: they customize, pack and send the products right to your home/office giving the ORGanizer a small percent maring of the price.

This way you are happy to receive awesome swag and I’m happy as well because I can keep the #BestExtensionEvenr free for all!

Jump to the ORGanizer site to browse all this awesome stuff!

CHANGE SET HELPER

The Change Set Helper plugin has been developed to help daily work with Salesforce outbound Change Sets.

Due to limitations on Salesforce Change Set APIs, the plugin is meant to help you in the tedious work of searching for components, remove components from change set, creating recurring change sets to be included in every change set you make.

The plugin comes with limitations.

The plugin is in early beta, please report malfunctioning features or improvements from the support page.

What can you do with the Change Set Helper?

Open an outbound change set and you’ll se with your eyes!

Click the Download compoments to retrieve a zip file containing the components from the package.

WARNING: This features works if there is only one outbound component with the same name.

Because of dealing with big change set could be frustrating, the plugin is meant to create a template or every change set you work with.

A template is just a reusable change set model you can import in another change set, browse, refine removing certain components, use to remove components from the current change set.

To create a template click on the Create Template button: this operation can take a while especially if the change set has hundreds of components.

Once you hit the button, you’ll see the script automatically pressing the Next link on the change set components table, lurking all the components definitions.

Once the template is completed, you are required to set a name for the template and click the Save Template button.

The Metadata Templates picklist shows the list of all save templates:

The template can be added into a new change set (see next paragraph). Because it is not easy to understand if a component can be added, you can click the Compare Template button: this way the script iterates through all current change set components looking for matching components between the selected template and current change set.

If a subset of the selected template if found inside current change set, you are required to create a new “subset” template with all the components that have not been found, to safely import the template into your change set.

The plugin has been tested with various metadata types, but there can be unsupported components (it depends on how Salesforce shows components on the components table) that I haven’t still checked.

Please report any unwanted behavior.

At the moment of writing, only Person Account record types are not supported: this means that these record types cannot be added through a template and so must be added manually.

By pressing the Remove Template button you can remove a selected template from the list.

The Extract Template CSV donwloads current template in CSV format (this CSV file can be usefull to trigger bugs if you report an error).

Once you select a template, a new table is shown:

You can filter components and save changes made to the template by the Remove from Template link.

If you want help to remove a specific component from current change set click the Remove from Change Set link next to each component’s name: this can save you A LOT OF TIME!

The helper iterates through the chage set components table (clicking the Next button) and if a match is found, clicks the standard Remove link, that triggers for the standard confirmation popup:

[https://organizer.enree.co/img/faq/faq_changeset6.png]

If no match if found, an informative message is displayed:

The plugin works with Packages as well but be aware that packages often includes in their components list also components that cannot be added to a change set (e.g. components that come from managed packages), so it may happen that templates created with a package is not importable on a change set (and vice versa).

The Change Set Helper plugin is hosted on the Add component page as well:

The only difference is the absence of the Create Template, Compare Template and Remove Template buttons.

The Add Template button insert current template into the plugin.

If all the components can be inserted, the script adds the components and goes back to the main change set page.

If un-importable components are found (e.g. Person Account record types, untested components in the beta development), the download of a CSV containing the remaining components is automatically triggered: this way you know what to import manually by yourself.

If this happens, you need to press the Add to Change Set button manually (you don’t see the list of the components you are about to insert).

The plugin adds 3 usefull features:

  • Quick search components: quickly filters the list of selected components type
  • Expand component list link to expand the list by 1000 components (the maximum allowed)
  • The Add to Change Set and Add Again button that simply does the Add action and returns back to current page (and not to the Change Set page)

Remember: this is not a change set manager because the absence of any API that can help this important Salesforce feature, but it is an helper that helps you automate change set management tasks.

Please report back any malfunctioning feature or any smart way to enhance this useful plugin.

To enable/disable this plugin run to the Features section of the plugin’s Options page.

QUICK CONSOLE GAMES

While you are waiting for long running operations (such as deleting a Change Set component among thousands of components using the Change Set Helper plugin), you can relax playing 2 ( more to come in the next releases) simple yet awesome games:

Quicklogin

The Quick Login plugin allow you to login directly from the standard Salesforce login page.

The plugin is automatically attached to the username input text and shows the corresponding ORGanizer accounts matching the input string:

To enable/disable this plugin run to the Features section of the plugin’s Options page.

TIMED PASSWORD SESSION

This plugin is configurable from the Encryption section of the Options page.

If encryption is enabled you can set up Timed Password Sessions.

Set up a maximum password session duration. During this time frame you are never requested for the encryption password when:

  • Copying login link in memory from the popup accounts page
  • Copying password + token from the popup accounts page
  • Showing password on the popup account editing page

This enhances security because if you leave your laptop unattended, after the session is expired none can login on any account anymore, but requires to insert the password to enable the extension.

Once the session is expired the Quicklogin and @login command with Quicklink do not work as well.

GET PASSWORD + TOKEN ON THE FLY

From the ORGanizer’s popup a new button is in place to get you the password and token of an account to use it for other porpouses (e.g. IDE, API, external services, …).

If you haven’t set up Timed Password Sessions and have Encryption enabled, the button asks you for the main encryption password.

SHOW PASSWORD IN EDITOR PAGE

Now you can see the password in clear while editing an ORGanizer account:

INCREASED LICENSE LIMITS

More accounts can be handled:

Total accounts has been increased from 80 to 150, and sync accounts from 60 to 100.

[CSS / Trick] Readonly Input Text

Message for the future me: this is a small CSS trick to make an input text like an output label using CSS:

.inputDisabled{
   pointer-events: none;
   cursor: default;
   background-color: white;
   border: none;
   font: inherit;
}

This is an example:

[Job Skills / Guest Post] Skills Gap Analysis: Is the Tech industry facing a serious talent shortage?

In this cloudy saturday evening I want to share a guest post by Maria Baranowska, Outreach Executive at Mason Frank International, global and niche IT recruitment company, who is passionate about responsible marketing and the growing digital world.

I decided to guest her and this interesting post because nowaday I’m facing an incredibly high shortage of skilled professionals and we are desperatly seeking guys willing to at least learn how to become a Salesforce programmer: and this is surprisingly strange in these times of crisis.

The Tech skills gap is like the monster under the bed. You’re absolutely sure it’s there, but you can’t seem to make it out in the darkness.

According to Fortunethere are currently 607,708 open computing jobs in the US, but only 42,969 computer science students graduated into the workforce“. Globally, there is much debate on the area and what that could mean for the industry in years to come. So how significant is the talent shortage? What does it mean to be ‘unskilled’ in the field? And, ultimately, what does this mean for today’s tech professional?

The graduate numbers in computing are the initial concern. Outside the above stated, the problem seems to be global. In the UK, the number of graduates in the field actually reduced in the last year, despite the country’s widely considered status as European Tech hub, and an increasing number of technical jobs. Furthermore, the talent pool is further depleted by the lack of equal opportunities. Globally, “there is less than 20% women in tech” and university statistics do not indicate a growing trend. ‘Of the 63,000 UK students taking the subject in 2014-15, 85% were male’ according to a report published by Hired. This can be seen reflected in the workplace too. The Mason Frank Salary Survey states, globally, the split of male to female Salesforce professionals is 66% to 33% (1% undisclosed) indicating the industry is still falling behind the equality stakes.

The demand for more tech professionals is definitely still on the rise. The US federal government alone reported needing an additional 10,000 IT and cybersecurity professionals and, according to the same source, “more than two-thirds of all tech jobs are outside the tech sector“.

The lack of graduates within Computing may seem concerning at first, however, there are many arguments that support the idea of there being absolutely no shortage of professionals . According to Hired, around a quarter of today’s Tech professionals do not hold a degree. This could indicate the nature of Tech vocations allows for ‘on the job’ training and education outside of the traditional framework. In 2016, Mason Frank International were responsible for qualifying 30,000 Salesforce professionals through specifically tailored training programmes. Companies are now taking alternative routes to create their own workforce. Microsoft recently announced their own degree programme in order to train a specialised workforce. This approach could be beneficial long term and as we see a rise in alternative education through apprenticeships. Across the world, governments are introducing coding and computing into school curriculums A shifting attitude. towards education also suggests a greater focus on proving technical and soft skills in other ways.

It’s also important to consider external factors. The US, among other countries such as the UK, relies heavily on foreign workers. The outcomes of changing political landscapes may limit opportunities to work abroad and hinder the closing of the skills gap. Technology leaders such as Mark Zuckerberg and Gerard Grech are speaking out against President Trumps recent travel ban in fear of limiting access to the best talent through changing roaming legislation.

The key takeaways of this post are first and foremost an awareness of the potential issues. Considering the pace of Tech growth, our education systems are not moving fast enough to keep up. However, business owners and employers have a responsibility to nurture talent through other avenues and hire more for personality so that training can be given to the right candidates. It’s the only way we can ensure our feature in Tech.

[Salesforce] ORGanizer Chrome Extension hits its first 1000 active users! #PartyHard

I proudly announce that ORGanizer Chrome Extension we have reached the 1000th active ORGanusers!

A big thanks to everyone!

The Extension is free for all, support us to keep it free forever!

Click here and decide to:

  • offer me a coffe, a pizza, a cappuccino, a pasta (I’m italian after all) to thank me for this awesome job
  • share your love for the ORGanizer Chrome Extension on the social channels!

[Salesforce / Apex Runtime] Bug Report: Null exception not thrown

This little and simple post is to get Community’s attention to a possible bug my colleagues and me found few days ago.

It’s about how null checking differs if occurring from outside or inside an Apex Class.

For those who are TL;DR (like me), jump to the following Gist and comment if you have an explanation.

Let’s take this simple class:

public class MyController {
    public Account tst{get;set;}
    public MyController(){
        this.tst = [Select Id, Name From Account limit 1];
    }
    
    public void myMethod(){
        system.debug('Test inside: '+(tst.Name == null)); //Throws null pointer exceptions
        system.debug('Test inside: '+(tst == null));
        system.debug('Test inside: '+json.serializepretty(tst));
    }
}

Let’s take the following anonymous code:

MyController cnt = new MyController();
cnt.tst.Name = 'test';
cnt.tst = null;
system.debug('Test outside: '+(cnt.tst.Name == null));
system.debug('Test outside: '+(cnt.tst == null));
system.debug('Test outside: '+json.serializepretty(cnt.tst));
cnt.myMethod();

Question: What do you think is the debug?

Answer:

19:06:58.24 (32784451)|USER_DEBUG|[5]|DEBUG|Test outside: true
19:06:58.24 (32903967)|USER_DEBUG|[6]|DEBUG|Test outside: true
19:06:58.24 (33182107)|USER_DEBUG|[7]|DEBUG|Test outside: null
19:06:58.24 (33393615)|EXCEPTION_THROWN|[7]|System.NullPointerException: Attempt to de-reference a null object

Yes, that is!

Apparently calling a nullified member of type Sobject of an object instance from outside is somehow handled by the runtime as null, whether you recall a field (cnt.tst.Name == null) or the member itself (cnt.tst == null); while calling the same member from inside an object method, correctly throws a null pointer exception as expected.

This seems related to how Sobjects are handled when used in SOQL relationship fields, such as:

List<Contact> cntList = [Select Id, Account.Name From Contact limit 1];
System.debug('Account is: '+cntList[0].Account);
System.debug('Account.Name is: '+cntList[0].Account.Name);

In this example if the Account parent object is not presente, the debug outputs:

19:18:17.18 (79345369)|USER_DEBUG|[3]|DEBUG|Account is: null
19:18:17.18 (79634328)|USER_DEBUG|[4]|DEBUG|Account.Name is: null

This is somehow confusing.

I get that when dealing with SOQL queries this is useful (no null checking) but dealing with custom Apex Classes this can lead to real confusion.

These are my 2 cents, what do you think?

[Salesforce] ORGanizer Chrome Extension Version 0.5 is live!

Dear ORGanizer users, we have reached beta version 0.5, that means we are half way to version 1.0!

For anyone that doesn’t know what the Salesforce ORGanizer Chrome Extension is, download it for free from the Google Web Store and, believe me, you won’t be disappointed for sure!

As usual, if you find ORganizer useful please cast a vote on the store!

This release comes with important major and minor new features and several UI fixes.

  • OAuth login
  • Automatic data backup
  • Very Important Queries and Scripts (VIQ and VIS)
  • Other improvements

OAuth login

The ORGanizer allow login with username and password along with token if the Login with token flag is active.

If your company’s password policies prevent you from using the ORGanizer to store passwords, from now on you can enable your browser to user OAuth: by requesting an access token the ORGanizer store (only locally and with encryption) an access token so it can requests a valid session Id without knowing the user’s password.

This means that you need to authorize every instance of the ORGanizer you have installed, so you need to input password at least once for every laptop you own.

How does it work?

Create or edit a new Account by clicking on the ORGanizer extension icon and select YES in the Login with OAuth (no password) section:

With this configuration the password field is not mandatory.

The first time you try to login with the above user (or if the authorization of the ORGanizer app has been revoked by admin, read later for how this is done) you are redirected to this internal page:

Remember which username you are about to authorize and click the link.

You are then requested for your username and password:

And to authorize the ORGanizer App (in this screenshot you are seeing the stage app):

This app requires web and API access (otherwise the Extension cannot work).

Once authorized you are then redirected in the following page:

where the access is validated and the access / refresh token stored locally (encrypted, no remote syncronization is done). You can proceed with login or simply close the app.

The next time (ever after days) you login with this user you are automatically provided a valid access token to enter in your ORG.

This authorization process occurs while setting up a new connection or when an App in no more authorized in your ORG.

To revoke an access token, jump to Setup > Users > select the user you want to revoke and go to the OAuth Connected Apps section:

Revoke each OAuth token issued (you can find multiple instances of the Connected App).

If you want to block the whole Salesforce ORGanizer Chrome Extension Connected App jump to Setup > Connected Apps OAuth Usage:

You can even remove the single user that are using it:

Automatic data backup

On the ORGanizer Chrome Extension’s Options page there is a new section:

The extension automagically saves a local copy of current ORGs and Accounts configuration every time you change a value from the Popup (or change encryption password).

You can set the maximum backup stack size (maximum is 100, minimum is 0) and download a specific backup.

Remember that the Reset all data! and Reset all local data! actions affect the backups aswell.

The bigger your ORGs and Accounts configuration is, the bigger is the local storage needed. Keep an eye on the new gauge on the SYNC/LOCAL QUOTA section:

Very Important Queries and Scripts (VIQ and VIS)

You can name queries and scripts you use often in the Very Important Queries and Very Important Scripts sections on the Quick Console.

V.I.Q.

V.I.S.

You can name a new query/script, select a saved one or delete one.

Remember that every query / script is only stored locally and affects the local storage limit seen in the previous chapter.

You can download a backup of all VIQs and VISs in the Options page:

Other improvements

The Quick Describe plugin’s search now filters objects based on key prefix:

The Options page now shows a link to the main site FAQ page and every section has a ? link to get some help.

Reset the Quick Console size and position (it can become too wide or can move outside the window if you are playing with Chrome’s window):

[Salesforce / Javascript] Visualforce tips for Javascript nerds

No secret I love Javascript.

It’s messy to the right point, it can be quick and dirty, it can be elegant, it can be wathever you are: your Javascript code can be a mirror of your personality.

And what’s better that putting together 2 things I like the most?

Yes, I’m talking about Salesforce and Javascript.

Javascript is the core of the new Lightning framework but since the birth of S-Controls (now deprecated) and Visualforce it’s been an importanto tool to expand the standard Salesforce platform.

What do you have to know before starting your Javascript journey with Visualforce?

Use zipped static resources for your scripts

Put all your JS files into a zipped static resource, this way you have aboslute control over the place where files are stored and have no problem finding them.

Use the apex:includeScript

If you use the HTML script tag the resources can be loaded more than once and this can lead to unexpected errors.

Think you are using jQuery and Bootstrap and your page loads them in sequence.

In the same Visualforce you also use a custom Visualforce component which loads jQuery itself: what’s the outcome? Bootstrap is simply erased from jQuery plugins.

The apex:includeScript component loads all the JS files only once, avoiding this kind of conflicts.

Use only one version per library

This is the same scenario of the previous paragraph.

If you load, e.g., jQuery 2 in one point and jQuery 3 on another place, this could lead to conflicts and strange behavior.

Keeping you library version on a static resouces allow you to get the right library version across all Visualforce page and components.

Use jQuery as much as you can

You’ll be using Javascript because you’ll want to create a slick, modern and responsive UI, so why reinvent the wheel?

Some good programmers still lack in jQuery knowledge, if you are one of them keep some time to study the bases of the library and I assure you won’t regret it…and you can be sure you’ll have really few problems for compatibility on different browsers.

Give all your components an ID / class name

When you develop a new Visualforce page take few minutes more that necessary to give all your components a recognizable html ID.

<page id="thePage">
 <pageBlock id="mainPB">
  <apex:pageBlockSection id="customerDataPBS" rendered="{!showCustomerData}">
   <apex:pageBlockSectionItem id="csDataNamePBSI">
    <apex:outputLabel id="csDataNameLBL">Name</apex:outputLabel>
    <apex:outputPanel id="csDataNameVAL">
     <apex:inputField id="csDataNameINP" value="{!account.Name}" />
     <apex:commandButton id="refreshCsNameBTN" 
          value="Refresh Data..." 
          action="{!refreshAccountName}"
          rerender="csDataNameVAL" />
    </apex:outputPanel>
   </apex:pageBlockSectionItem>
  </apex:pageBlockSection>
 </pageBlock>
</page>

This will ease your life if in the near future you decide to use Javascript to access the page’s markup.

Remember that IDs are automatically calculate by the Visualforce render engine, so if you want the exact ID you can use the $Component global variable, so if you want to access the apex:inputField on the previous code:

document.getElementById("{!$Component.thePage.mainPB.customerDataPBS.csDataNamePBSI.csDataNameINP}");

But I recommend not to use this way.

This is not incorrect but as you continue your Visualforce development (sometimes the customers you work with don’t know what they actually want till they want it!) you can change the UI, moving sections on the page, so the ID chain can change over time.

That’s why you can use the “ends with” operator with jQuery to get an HTML component:

var inputField = $('[id$="csDataNameINP"]');

That is easier. The only thing is that you must be sure that you only have one and only one component with that ID.

Sometimes I use class names rather that ID, so for example:

<apex:inputField class="csDataNameINP" value="{!account.Name}" />

This way I don’t care about ID generation and go directly with searching for a specific class name.

var inputField = $('.csDataNameINP');

That is even clearer (this is something I usually do and I like the syntax but it is not a best practice).

Keep coding and may the Force.com be with you!

Page 16 of 27

Powered by WordPress & Theme by Anders Norén