2

I need to match on a string such as this:

'if Country equals "United States" then Show'

I'm working with the Webforms for Marketers Module in Sitecore. Sitecore is a .NET based CMS. The Webforms for Marketers Modules is a module that provides a GUI for non-developers to design forms with textboxes, drop-down lists, checkboxes, etc... I have requirements to only show certain fields on the form if the user picked a certain option in a previous field. For example: only show the States drop-down list if the user picked "United States" from the Country drop-down list. The problem is, the WFFM module doesn't support conditional renderings of fields so I'm trying to implement it myself with JavaScript. My idea is this:

  • I'll build out the form in the module with all of the possible fields
  • When the page loads, I'll use JavaScript to hide fields that depend on the value of previous fields
  • When a user interacts with a field, I'll run some JavaScript to check the value of the field and determine whether or not I should show one or more of the fields that I hid on page load.

I'm basically writing an interpreter for an if statement; I'm giving the marketers a way to "program" the form. Country is the name of a drop-down list on my page. equals is a condition. "United States" is one of the values in drop-down list. If the user picks United States in the drop-down, then Show the States drop-down list.

So the input for the regex test would always follow this format:

  • always starts with the keyword if
  • followed by 1 or more white-spaces
  • followed by any number of digits, and/or letters and/or white-spaces
    • The name of controls can contain more than one word with spaces and even numbers
      • For example: First Name, or, Address Line 1
  • followed by 1 or more white-spaces
  • followed by the keyword equals
  • followed by 1 or more white-spaces
  • followed by 1 double-quote
  • followed by any number of digits, and/or letters and/or white-spaces
    • The value of the control can contain more than one word with spaces and even numbers
  • followed by 1 double-quote
  • followed by 1 or more white-spaces
  • followed by the keyword then
  • followed by either the keyword Show or the keyword Hide

I've got this much that works but it's not all of the requirements I've listed above. This line matches all the way up to the white-space after the control name.

var pattern = /^if\s+(\d*|\w*)\s+.*$/;

But when I try to match on the double-quote it doesn't work; I don't really know the syntax for matching on the double-quote. I've tried all of the following, none work:

var pattern = /^if\s+(\d*|\w*)\s+["].*$/;

var pattern = /^if\s+(\d*|\w*)\s+\".*$/;

var pattern = /^if\s+(\d*|\w*)\s+\"{1}.*$/;

Any help you can provide will be greatly appreciated!

DougCouto
  • 530
  • 1
  • 3
  • 18
  • I recommend against allowing marketers to make web forms. – zzzzBov Aug 25 '12 at 04:09
  • 1
    @zzzzBov - I recommend against allowing marketers to make _anything_. – nnnnnn Aug 25 '12 at 04:11
  • 1
    @nnnnnn - LOL if only I had that option! – DougCouto Aug 25 '12 at 13:46
  • @Barbosa I was wondering if you could add more details about how you actually got this working? – ADH Mar 22 '16 at 20:50
  • @ADH this was my attempt at writing a "rules engine" for Webforms for Marketers. Keep in mind, this was 4 years ago! If you're working with the latest version of Sitecore and WFFM, I recommend you look at the built-in features available now. Here's an example. I haven't tried it myself but this might be the built-in way of doing what I was trying to do manually 4 years ago - http://zacharykniebel.com/blog/sitecore/2014/june/04/dynamic-form-fields-in-6-steps-in-wffm – DougCouto Mar 23 '16 at 15:10

2 Answers2

1

I'd suggest an expression like this:

/^if\s+([\w\s]+)\s+equals\s+"([\w\s]*)"\s+then\s+(\w*)$/

Which you could use like this:

var expression = // set this to your input
var matches = expression.match(/^if\s+([\w\s]+)\s+equals\s+"([\w\s]*)"\s+then\s+(\w*)$/);

if (matches) { // if matches isn't null
    // matches[1] is the field name
    // matches[2] is the value in quotes
    // matches[3] is the operation to perform

I haven't hardcoded "Hide" and "Show" into the regex - instead it returns whatever string is after "then". I figured that would make it easier to add more operations later. If you want to hardcode these operation names just change the final (\w*) to (Hide|Show). Also this expression will work if the part in quotes is an empty string, which may be valid for some field values.

Demo: http://jsfiddle.net/2UFHN/1/

Note: You said _"any number of digits, and/or letters and/or white-spaces" - for that you just need [\w\s]+. In your expressions you had (\d*|\w*)\s+, which means "zero or more digits OR zero or more word characters FOLLOWED BY by one or more spaces". \w already matches digits (as well as a-z and underscore), so you don't need \d as well.

You might want to add an i flag to your expression, as in /expressionhere/i to make it case insensitve.

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • P.S. You might want to ignore leading and trailing whitespace too. – nnnnnn Aug 25 '12 at 04:15
  • `[\w\s]+` should be `[\d\w\s]+`. – ebohlman Aug 25 '12 at 07:30
  • @ebohlman - No it shouldn't. As I mentioned in my answer, `\w` _already_ matches digits, so including `\d` is redundant. – nnnnnn Aug 25 '12 at 07:31
  • My bad, but `\w` also matches underscores, so to be pedantic it should be `[\da-zA-Z\s]+` (would be nice if JS regexes included POSIX character classes so it would work for non-English languages). – ebohlman Aug 25 '12 at 07:47
  • @ebohlman - Yes, you're right about the underscores. I left `\w` in my answer because the OP had used it, but I did mention the underscores just to make sure OP knew they'd match too. – nnnnnn Aug 25 '12 at 07:53
  • Thanks so much for your ideas! Can I just make one small change? Instead of `'if Country equals "United States" then Show'`, I'd like to wrap the control name, Country in curly-braces. The updated `if` statement would look like this: `'if {Country} equals "United States" then Show'`. I think this will make it easier to match if the Control Name contains white-spaces. – DougCouto Aug 25 '12 at 13:49
  • I'm not sure what you mean by "easier to match", because the regex I've given you already does that - test it out with the demo I provided. But if you want to add curly braces I guess something like this should work: `/^if\s+\{([\w\s]+)\}\s+equals\s+"([\w\s]*)"\s+then\s+(\w*)$/` (If I've gotten it a bit wrong or it needs further tweaking I'd suggest reading up [MDN's regex page](https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Regular_Expressions).) – nnnnnn Aug 25 '12 at 15:06
  • @nnnnnn - didn't mean to suggest your answer doesn't work for me; it worked perfectly! I was more thinking about the marketers - that it would be easier for them to understand the syntax if the control name was a little more identified by being wrapped in curly braces, that's all. thanks for your help! – DougCouto Aug 26 '12 at 18:20
0

Just use "; no need to escape it.

Also, you're apparently trying to match the " without first matching the equals, so it won't match any of your test cases.

/^if\s+(\d*|\w*)\s+".*$/.test("if abc \"xyz\"") // ==> true
/^if\s+(\d*|\w*)\s+".*$/.test("if abc equals \"xyz\"") // ==> false
nneonneo
  • 171,345
  • 36
  • 312
  • 383