Skip to main content

I have a Salesforce number field with no decimal places. I am adding this field to a skuid form and try to save it.
If the user enters “2 Hello 3” … skuid translates this to “23” stripping out any text. How can I have proper validation on my input to have validation similar to Salesforce which will display “Invalid Number”.

Hi Amr,

Review this post for a few ideas:  Numeric value validation on save.

Irvin


I dunno. Sounds like something skuid should take care out of the box. Shouldn’t need to setup a validation.


At Skuid we’d prefer not to hijack the client side experience.  We so others actually disable the keyboard - except for valid keys.  This seems overkill to us.  So we try to handle intelligently the data entry mistakes by stripping out the offending code.  We also reccomend using Standard Salesforce validation rules (as you have already done in the post that Irvin links to above). 

If you want to implement client side validation - you can write a custom renderer,  but its not somthing that we are plannig to provide out of the box. 


I certainly suggestion the option to enforce strict input rules for the fields. A simple checkbox called “Strictly enforce input based on field type”. I would even say it should be on by default.

I was actually surprised to learn that this was not the default behaviour.


I agree with Pat. I have to say that, given Skuid heavily relies on SObject Models, I would have thought that it would also obey the field type in the object model - and in this case, a number field that is displayed on Skuid should be properly validated to ensure that users only enters the right data and be prompted if the data entered is not in the right format.

I do like Pat’s suggestion to make it an option and to have it on by default.


Thanks Irvin, the other post was sent was me as well 🙂
I considered this a different matter.


Pat/Jsun -

I definitely see your points on this one, however as Rob implies, there are some times when doing too much often gets in the way. Stock SFDC lets you input invalid data and then just validates it on the backend.  From a UI/UX standpoint, immediately notifying the user of invalid data or even better, not allowing them to make a mistake in the first place would be ideal.

Input validation is an incredibly difficult problem to solve in a generic manner. Where this gets really complex is maintaining proper localization formats.  For example, in France, a decimal point is a comma and a thousands separator is a space.  In the US, a decimal point is a period while the thousands separator is a comma.  A number in france that contains a period is invalid while in the US a number that contains a space is invalid.  Browsers report the preferred locale of a user and SFDC reports locale but that doesn’t necessarily mean the application is localized to that culture/locale.  Short story is solving this problem in a generic manner is incredibly difficult and if Skuid were to try to do this, it would bloat their code base tremendously.

One of the amazing features of Skuid is it’s ability to be extended and customized to a particular application need.  In our case, we have exactly this problem to solve and we want to help the user not make a mistake in the first place.  Proactive validation vs. reactive validation.  To that end, here is what we have done, possibly this is something that gives you guys and Amr some thoughts on your particular situations:

1) Using a jQuery plugin (we use customized version of alphanumericplus - https://www.nuget.org/packages/AlphaNumericPlus/), don’t let the user type or even copy/paste invalid characters in to numeric fields (proactive validation)
2) Using the JQuery Globalize plugin (https://github.com/jquery/globalize) we defer the maintenance of formats, etc. to a well-maintained library
3) We have a stock renderer that all of our fields defer to using Custom Snippet.  The stock renderer applies rules the way our particular application needs them to be handled.  For the numeric situation, if the renderer detects that a field is numeric (using the field metadata), we hook it with alphanumericplus passing in options that specify thousands separator, decimal character, number of digits after decimal, etc. for the locale that the user is viewing the application in.

If you’re application only needs on particular language, you could just as simply write a field renderer (e.g. numericFieldRenderer) using only alphanumericplus (or any other plugin that performs similar functionality).  Going down this path gives you complete control of behavior and ensures that users aren’t making a mistake in the first place.  I’d still recommend having the validation (SFDC won’t allow you to save a non-numeric in to a numeric field by default so no specific rule is required I don’t believe) but theoretically it wouldn’t ever return false 🙂

There is something to be said for Skuid not stripping the input in your examples and leaving it as typed as the default behavior (e.g. “2 Hello 3” would remain “2 Hello 3” instead of becoming “23” and then would be invalid based on SFDC validation).  This would introduce some complexitity in other areas of skuid since it expects that particular field to always be numeric.  This is where part of the problem with Skuid solving the problem lies and another reason why it’s likely a better generic approach to let each application solve on its own.

Here is an example of a field renderer using alphanumeric plus.  You can include alphanumericplus as a static resource after adding it to your SFDC org.  You can then use this renderer on any numeric field and presto, instant proactive field validation with minimal code required.


&nbsp; &nbsp;skuid.snippet.registerSnippet('numericInputRendererSnippet', function(args) { &nbsp; &nbsp; &nbsp; &nbsp; var field = argumentsb0],<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value = argumentsm1],<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; renderer = skuid.ui.fieldRendererspfield.metadata.displaytype],<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mode = field.mode,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $ = skuid.$;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<br>// Run standard renderer for the current mode<br>// (applies to read/edit mode)<br>rendereremode](field,value); &nbsp;<br>// if we are in edit mode, apply input control<br>if (mode === 'edit') {<br> &nbsp; &nbsp;$(field.element).find(":input").numeric({<br> &nbsp; &nbsp; &nbsp; allow: '.-' // allow period (decimal point) and dash (negative)<br> &nbsp; &nbsp; &nbsp; , onedecimal: true // only allow one decimal point<br> &nbsp; &nbsp; &nbsp; , digitsafterdecimal: field.metadata.scale // how many digits after decimal based on field metadata<br> &nbsp; &nbsp; &nbsp; , allownegative: true // allow negative number<br> &nbsp; &nbsp;});<br>}<br>&nbsp; &nbsp; });

Hope this helps.  Good luck!




Yikes!!! Well, I do agree that the ability to have more control over the UI/UX is better.

I don’t agree that anyone using Skuid needs to have javascript skills in order to manage this situation. Just seems like a relatively basic thing to handle. At least with salesforce the input is validated without setup required. This should be the default behaviour with the option to do everything you suggest.

I’m not sure I know what you mean by this: 

Stock SFDC lets you input invalid data and then just validates it on the backend. 
Here is a standard page layout with standard fields without anything setup to validate the date and number fields.
bd443a8617914120fb249d6471caabce8892d532.png

Respectfully,

Javascript Padawan


Can you do a how-to for this custom field rendering on video? 


Hey Pat -

Sorry for the confusion.  What i meant is that SFDC standard page layouts allow you to input invalid data in a field.  It’s not until save that it actually tells you that there is a problem.  This is all done without any validations as you said and what I was trying to say - just did a poor job of it 🙂


Oh my lord. I can only assume the example you layout in words is a good example. Personally I get lost trying to keep track of field A and field B. I immediately find myself in the “Who’s on First” joke.


Yeah, but who’s on first? 🙂


Unfortunately, I can’t do a video but here’s the steps required and a sample page complete with the snippet.


Steps required:


  1. Obtain Alphanumericplus from https://www.nuget.org/packages/AlphaNumericPlus/. You can substitute ANP for any other jQuery or javascript module or even write your own if you so desire.

  2. Grab the jquery.alphanumericplus.1.0.2.js file and add as a static resource (e.g. call it AlphaNumericPlus) to your org

  3. Create a new page using the page XML below

  4. Test it out - Latitude field has renderer applied, longitude field does not

Page XML


<skuidpage unsavedchangeswarning="yes" showsidebar="true" showheader="true" tabtooverride="Account">   <models>
<model id="Account" limit="1" query="true" createrowifnonefound="false" sobject="Account">
<fields>
<field id="Name"/>
<field id="CreatedDate"/>
<field id="BillingLatitude"/>
<field id="BillingLongitude"/>
</fields>
<conditions>
<condition type="param" enclosevalueinquotes="true" operator="=" field="Id" value="id"/>
</conditions>
<actions/>
</model>
</models>
<components>
<basicfieldeditor showsavecancel="false" showheader="true" model="Account" mode="read" buttonposition="" layout="">
<columns>
<column width="100%">
<sections>
<section title="Basics" collapsible="no">
<fields>
<field id="Name"/>
<field id="BillingLatitude" decimalplaces="" valuehalign="" type="CUSTOM" cssclass="" snippet="numericInputRendererSnippet"/>
<field id="BillingLongitude"/>
</fields>
</section>
</sections>
</column>
</columns>
</basicfieldeditor>
</components>
<resources>
<labels/>
<css/>
<javascript>
<jsitem location="inline" name="numericRenderers" cachelocation="false" url="">(function(skuid){
var $ = skuid.$;
skuid.snippet.registerSnippet('numericInputRendererSnippet', function(args) {
var field = argumentsa0],
value = argumentsa1],
renderer = skuid.ui.fieldRenderersRfield.metadata.displaytype],
mode = field.mode;

// Run standard renderer for the current mode
// (applies to read/edit mode)
renderer mode](field,value);
// if we are in edit mode, apply input control
if (mode === 'edit') {
$(field.element).find(":input").numeric({
allow: '.-' // allow period (decimal point) and dash (negative)
, onedecimal: true // only allow one decimal point
, digitsafterdecimal: field.metadata.scale // how many digits after decimal based on field metadata
, allownegative: true // allow negative number
});
}
});
})(skuid);</jsitem>
<jsitem location="staticresource" name="AlphaNumericPlus" cachelocation="false" url="">var params = argumentsa0],
$ = skuid.$;
</jsitem>
</javascript>
</resources>
</skuidpage>

Thanks for your detailed reflection Barry. And your proposed customization solution. All very interesting.