# Prevent or Limit Special Characters

**URL:** <https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172>\
**Category:** Ignition\
**Tags:** perspective\
**Created:** [May 3, 2023, 1:01am UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172 "2023-05-03T01:01:21Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![mdemaris](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mdemaris/32/54639_2.png) [@mdemaris](https://forum.inductiveautomation.com/u/mdemaris)\
**Post date:** [May 3, 2023, 1:01am UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/1 "2023-05-03T01:01:21Z")

</div>

Has anyone created a way to prevent/limit special character entry into text/numeric fields?

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [May 3, 2023, 1:25am UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/2 "2023-05-03T01:25:08Z")

</div>

The two components have entirely different approaches.

Text Field:  
There's no way to "prevent" a user from typing restricted characters, but you can amend the value of the Text Field and remove any such characters with a script like this in the valueChanged script of `props.value` (you'll also need to set `props.deferUpdates` to have a value of `false`):

```auto
if currentValue and currentValue.value:
    disallowed = ["*", "[", "]"]
    reassembled = "".join([checked_char for checked_char in currentValue.value if checked_char not in disallowed]) 
    if reassembled != currentValue.value:
        if previousValue:
            self.props.value = previousValue.value
        else:
            self.props.value = ""

```

The Numeric Entry Field doesn't really allow for this sort of approach, but it natively prevents symbols which don't make sense for numbers. Your best option with the Numeric Entry Field is to simply supply valid maximum and minimum values and let the component perform its own validation.

---

<div class="post-metadata">

**Author:** ![mdemaris](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mdemaris/32/54639_2.png) [@mdemaris](https://forum.inductiveautomation.com/u/mdemaris)\
**Post date:** [May 3, 2023, 1:29am UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/3 "2023-05-03T01:29:27Z")

</div>

What's the difference between

> [@cmallonee](#):
>
> `currentValue and currentValue.value:`

?

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [May 3, 2023, 1:32am UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/4 "2023-05-03T01:32:14Z")

</div>

`currentValue` is a Qualified Value object, which can sometimes initialize as `None` leading to NoneType issues when attempting to immediately reference `currentValue.value`, which is the actual value of the property.

---

<div class="post-metadata">

**Author:** ![mdemaris](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mdemaris/32/54639_2.png) [@mdemaris](https://forum.inductiveautomation.com/u/mdemaris)\
**Post date:** [May 3, 2023, 1:40am UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/5 "2023-05-03T01:40:13Z")

</div>

OK, so what your snippet does is compare the original string (previous value), to the invalid-character-checked string that the user typed. Correct?

So if I'm going to take the user's input and update the table data, after checking for the characters not allowed, I can simply run the update query.

How about creating an inheritable script that would use something like a table of special characters to disallow? Not sure how that would work out. If it's an actual table, then I'd have to create a dictionary/list to loop through? Compare characters, remove, reassemble...

Does that seem realistic?

---

<div class="post-metadata">

**Author:** ![mdemaris](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mdemaris/32/54639_2.png) [@mdemaris](https://forum.inductiveautomation.com/u/mdemaris)\
**Post date:** [May 3, 2023, 1:45am UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/6 "2023-05-03T01:45:41Z")

</div>

Well, I just got the None Type error, lol

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/b/e/bea0963e2e9903c1cc78fa7dbf712ba7f406170d.png)

I think it doesn't like the `previousValue.value`

Do I need to instantiate it somehow? Well, now it works fine for some reason. Erred three times, now it's happy.

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [May 3, 2023, 1:46am UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/7 "2023-05-03T01:46:08Z")

</div>

> [@mdemaris](#):
>
> I can simply run the update query.

Well, sort of. Before you do anything, remember that this is being done in the valueChanged script, meaning this value has already been changed - so any table update should not occur here, lest it happen with the "invalid" characters included. What my script does is AFTER the user has input the invalid characters - and that value has been received and applied to the property - we then amend the value and replace it with the old value. But if your script to update a table is located elsewhere - like some Button click - then yes, you're safe to apply the sanitized value.

There's no reason you can't make a project level script which sanitizes inputs. For security reasons, your SQL should prevent any disallowed characters. Never rely on someone else for security where you can avoid it - even if you're a Database.

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [May 3, 2023, 1:47am UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/8 "2023-05-03T01:47:24Z")

</div>

Hmmm. Thinking about it, `previousValue.value` would definitely be `None` the first time the script executes if you never gave the Text Field a value to start with. 🤦‍♂️ I edited the original script suggestion.

---

<div class="post-metadata">

**Author:** ![mdemaris](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mdemaris/32/54639_2.png) [@mdemaris](https://forum.inductiveautomation.com/u/mdemaris)\
**Post date:** [May 5, 2023, 9:40pm UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/9 "2023-05-05T21:40:35Z")

</div>

Thanks a bunch! I'm going to run with this and see how far I can take it, 🙂

---

<div class="post-metadata">

**Author:** ![mdemaris](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mdemaris/32/54639_2.png) [@mdemaris](https://forum.inductiveautomation.com/u/mdemaris)\
**Post date:** [May 5, 2023, 9:57pm UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/10 "2023-05-05T21:57:54Z")

</div>

What do you think of this for a project script?

```auto
def charTest01(cValue, pValue):
# Compare the current value and previous value of text field
# look for any forbidden characters
# remove said characters
# leave sanitized string
	
	if cValue:
		disallowed = ["*","[","]","#","%","&"]
		reassembled = "".join([checked_char for checked_char in cValue if checked_char not in disallowed])
		if reassembled != cValue:
			if pValue:
				return pValue
			else:
				return ""

```

Edit: when passing values to the function, I'm going to have to use `currentValue` and `previousValue` aren't I?

---

<div class="post-metadata">

**Author:** ![mdemaris](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mdemaris/32/54639_2.png) [@mdemaris](https://forum.inductiveautomation.com/u/mdemaris)\
**Post date:** [May 5, 2023, 10:00pm UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/11 "2023-05-05T22:00:58Z")

</div>

Question on using `currentValue`: Why do we need to say `if currentValue`? What does that do exactly?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 5, 2023, 10:36pm UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/12 "2023-05-05T22:36:10Z")

</div>

A few different things are happening with `if currentValue and currentValue.value:`

1. Python evaluates different things as 'false' - besides the singleton False, also numeric values equal to 0, empty collections, empty strings, _and_ the singleton None (AKA `null` in other languages).
2. Python automatically coerces whatever expression is given in the `if` statement into a boolean; no need to type check.
3. Python evaluates boolean expressions joined with `and` lazily; if the first is false, the second will not be evaluated.

So, if `currentValue` is `None` (null) when that statement is entered, the statement will _immediately_ exit, and the second line of the `if`, checking `currentValue.value`, will not throw the TypeError that it otherwise would because `NoneType has no attribute value`.

---

<div class="post-metadata">

**Author:** ![mdemaris](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mdemaris/32/54639_2.png) [@mdemaris](https://forum.inductiveautomation.com/u/mdemaris)\
**Post date:** [May 6, 2023, 12:52am UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/13 "2023-05-06T00:52:19Z")

</div>

And one more question for clarity:  
`currentValue.value` is the value or text already in the text field, and `previousValue.value` is what was typed, then captured when focus moved to another component?

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [May 7, 2023, 10:20pm UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/14 "2023-05-07T22:20:27Z")

</div>

No.

Assuming your component has no starting value, here's a step-by-step flow of what's happening, with some unimportant steps omitted for brevity:

1. Component initializes in session.
2. User supplies character to Text Field ("a").
3. `TextField.props.value` in the session is set to "a".
4. The change script for `TextField.props.value` is executed, where `previousValue` (QualifiedValue object) is `None`, and `currentValue` is a QualifiedValue object which contains information about the current value ("a") of the Text Field.
5. In your scenario, this script verifies validity of the string content, before potentially replacing the "new" value with what it was before.
6. User supplies character to Text Field ("s").
7. `TextField.props.value` in the session is set to "as".
8. The change script for `TextField.props.value` is executed, where `previousValue` is no longer `None`, and now had a `value` attribute of "a", and `currentValue` is a QualifiedValue object which contains information about the current value ("as") of the Text Field.

---

<div class="post-metadata">

**Author:** ![mdemaris](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mdemaris/32/54639_2.png) [@mdemaris](https://forum.inductiveautomation.com/u/mdemaris)\
**Post date:** [May 8, 2023, 4:45pm UTC](https://forum.inductiveautomation.com/t/prevent-or-limit-special-characters/73172/15 "2023-05-08T16:45:05Z")

</div>

Doh! 🤦‍♂️  
I had the current and previous backwards in my reply. Must have been a long day.
