Invalid input for numbers

  • 1
  • Question
  • Updated 4 years ago
  • Answered
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".
Photo of Amr

Amr

  • 256 Points 250 badge 2x thumb

Posted 4 years ago

  • 1
Photo of Irvin Waldman

Irvin Waldman, Champion

  • 9,016 Points 5k badge 2x thumb
Hi Amr,

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

Irvin
Photo of Amr

Amr

  • 256 Points 250 badge 2x thumb
Thanks Irvin, the other post was sent was me as well :)
I considered this a different matter.
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 43,156 Points 20k badge 2x thumb
I dunno. Sounds like something skuid should take care out of the box. Shouldn't need to setup a validation.
Photo of Rob Hatch

Rob Hatch, Official Rep

  • 44,678 Points 20k badge 2x thumb
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. 
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 43,156 Points 20k badge 2x thumb
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.
Photo of Jsun Pe

Jsun Pe

  • 230 Points 100 badge 2x thumb
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.
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,266 Points 10k badge 2x thumb
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 :)  The net result of all this is far superior to stock SFDC page layouts because users are stopped before they make a mistake.  More importantly, we as Skuid consumers have complete control over how we perform validations and even better, Skuid can focus on bringing us cool new features like Charting rather than solving the incredibly difficult task of a generic one-size meets all solution to validation. :)

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.

	    skuid.snippet.registerSnippet('numericInputRendererSnippet', function(args) {	        var field = arguments[0],
            value = arguments[1],
            renderer = skuid.ui.fieldRenderers[field.metadata.displaytype],
            mode = field.mode,
            $ = skuid.$;
            
// 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
   });
}
    });
Hope this helps.  Good luck!
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 43,156 Points 20k badge 2x thumb
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.


Respectfully,

Javascript Padawan
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 43,156 Points 20k badge 2x thumb
Can you do a how-to for this custom field rendering on video? 
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,266 Points 10k badge 2x thumb
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 :)

Regarding Skuid, the problem with having skuid allowing you to type anything (not stripping it like it currently does) and then leveraging built-in SFDC automatic validations (e.g. Error: Invalid number, etc.) is that skuid does a ton of stuff that enables other features to work.  This work is based on data being valid (or at least appearing valid).

Here's an example - Conditional Rendering.  Let's say that you have a conditional rendering rule that states to show a particular field (FieldB) if the value of another field (FieldA) is greater than 10.  If skuid allowed you to type "2 hello 3" in FieldA and didn't strip the invalid portion, each time it evaluated the conditional rendering rule, it would first have to check to see if the value of FieldA was numeric and then if it wasn't, how would it handle conditional rendering - should it show the field?  Hide the field?  By stripping the value, skuid ensures that the data is always the type expected and can avoid the problem all together.  If Skuid were to allow invalid data in a field, the performance hit would be very significant to other areas of the Skuid features since it would have to check the field value for everything it does - and trust me, under the covers, it does a ton of stuff based on field values.  :)  On top of the performance hit, the scenarios that it would need to handle (e.g. invalid data) would be large and handling all those scenarios in all situations would cause significant code bloat to the skuid code base which also would reduce page load performance, etc.  In short, there is a really good reason why skuid strips the invalid data :)

Now, should Skuid have a feature that allows input restrictions based on data type?  Sure, there is something to be said for that but that's really where the complexity of localization, etc. that I mentioned in my previous post comes in to play.  It's really a tough nut to crack and often very specialized to the application.

I'd agree that it would be great to have a way to do this that doesn't require javascript skills.  It is technically possible but comes at a significant "cost" - performance being the large component but also additional code which introduces risk to the skuid platform.

Personally, I'd love to see a declarative solution to this, would be super slick. Just don't see how the risk/reward for Skuid is justified given the all the above.  At the end of the day, it's only a few lines of javascript - a worthwhile trade-off for us as consumers I think.

Think of it this way, how many apps are built on SFDC that have zero lines of Apex written for them and use a 100% declarative approach?  I'm sure there are some out there but most applications have at least one trigger or VF page or something.  Javascript to Skuid is a kin to APEX for SFDC.  Besides, think of all the fun you've had learning javascript that you never would have had the opportunity to do if that were the case :)
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 43,156 Points 20k badge 2x thumb
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.
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,266 Points 10k badge 2x thumb
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 = arguments[0],
            value = arguments[1],
            renderer = skuid.ui.fieldRenderers[field.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 = arguments[0],
$ = skuid.$;
</jsitem>
      </javascript>
   </resources>
</skuidpage>
(Edited)
Photo of Rob Hatch

Rob Hatch, Official Rep

  • 44,678 Points 20k badge 2x thumb
Thanks for your detailed reflection Barry. And your proposed customization solution. All very interesting.