vaildations in PromptOptions class of botframework - botframework

I have waterfall style dialog and I am using PromptOptions to prompt user for an input and if in case the input is wrong, I use retry prompt to notify the user that input is wrong. For example:
step_context.prompt('dialog_name', prompt = PromptOptions(prompt = 'Please enter your age', retry_prompt = 'Age should be greater than zero'))
To verify the input, I use custom validator which I can pass when adding this dialog to dialog set. For example:
self.add_dialog(NumberPrompt('dialog_name', Validator))
My question is PromptOptions has an optional argument called validations to which I can pass objects. What is that argument used for? Can that be used to pass my validator?

As you've seen, validations is part of PromptOptions. Since your validator can access the prompt options as part of the PromptValidatorContext, you can access the validations through the prompt options in your validator.
The validations are not used by the SDK and there is no predefined purpose for them. You can use them however you wish.

Related

requireCheckbox method signature meaning on the DataValidationBuilder class

Unfortunately, the Apps Script documentation page about DataValidation builder is missing information about the requireCheckbox method.
When you type it in via a script file, though, autocompletion offers 3 overloads:
no args:
requireCheckbox()
1 arg:
requireCheckbox(Object checkedValue)
2 args:
requireCheckbox(Object checkedValue, Object uncheckedValue)
What parameters of an object can I use in these arguments and what purposes they may serve?
CHECKBOX cell by default, has two values:
TRUE, when checked and
FALSE when unchecked.
Depending on the number of arguments provided to requireCheckbox, different values are used:
No argument:
The default values are used.
One argument:
The provided argument, when checked
Blank, when unchecked
Two arguments:
The provided arguments are used for checked and unchecked states respectively.
Sample code:
function yesNoDV() {
//Changes checked state to 'Yes' and Unchecked state to 'No'
SpreadsheetApp.getActive()
.getRange('Sheet1!A1')
.setDataValidation(
SpreadsheetApp.newDataValidation()
.requireCheckbox('Yes', 'No')
.build()
);
}
Object is the default type Google's documentation uses when more specific types do not apply. You can safely interpret it as an analog for any (and in fact, the #types TypeScript package for Google Apps Script has those parameters annotated with any).
Also, as of 2021, the documentation has information on all method overloads. To quote from it, the overloads function is as follows.
No arguments
Sets the data validation rule to require that the input is a boolean value; this value is rendered as a checkbox.
One argument
Sets the data validation rule to require that the input is the specified value or blank. When the input matches the specified value the cell is rendered as a checked checkbox. When the input is blank the cell is rendered as an unchecked checkbox.
Two arguments
Sets the data validation rule to require that the input is one of the specified values. When the input is checkedValue the cell is rendered as a checked checkbox. When the input is uncheckedValue the cell is rendered as an unchecked checkbox.
The meaning of each overload hasn't changed from that outlined in TheMaster's answer.

Is is possible to use variable in dialog prompt in LUIS?

In LUIS if you require some parameters for an action, and add a prompt question, if the parameter is missing, it will send the prompt as a dialog option in the answer.
In my case I have 2 required parameters, and if the 2nd one is missing (the quantity) I'd like the prompt asking for clarification to use the value of the other parameter's value.
For example:
query: I would like to buy tickets to toronto.
dialog prompt should
be: How many tickets to toronto?
I tried setting the prompt to something like "how many tickets to {location}" but obviously this doesn't work.
I haven't found any information on this so I think it's just not possible but I'd like confirmation.
I don't think this is possible out of the box. However, I believe it could be done if you start overriding things here and there.
The main problem is that the LuisActionDialog (the dialog that prompts for parameters) is not receiving the original LuisResult model (which makes sense since it's not serializable).
So, I think that to start looking into this, you will have to:
Override the MessageReceived method from the LuisDialog class, in order to create a new dialog that handles the parameters. Please note that overriding the MakeLuisActionDialog method won't be enough, per what I explained before about not receiving the original LuisResult.
Create a new dialog similar to the LuisActionDialog, that will do what the current dialog does but also performs the prompts manipulation that you are looking to have.

How to ask open questions in bot framework?

I am building a chat bot using Bot Framework, C# Bot Builder and FormFlow (with FieldRelfector).
At one step I need to ask an open question to the user like "Add any other relevant information", where I just want to collect some text and store it for later usage.
I tried to define the variable as String:
[Prompt("Add any other relevant information")]
public string OpenText;
In the form chain I have:
.Field(new FieldReflector<MyForm>(nameof(OpenText))
.SetType(null)
.SetActive(state => !state.Finished()))
but that doesn't help, whatever I type the bot answers:
"blah blah" is not a open text option.
How to handle this?
Is there any reason you are using a FieldReflector for that property? I would suggest just defining a normal field for that property (you can have a form with fields defined with FieldReflector and fields defined just with Field).
Just use:
.Field(nameof(MyForm.OpenText), state => !state.Finished())
If there is a reason to use FieldReflector, please update the post with the entire form definition.

Codeigniter form validation, custom check doesn't work if the field is not required

Gah.. I have spent way to long on this, but I believe I have found the problem.
Essentially I have a hidden field which is populated when a user clicks on an image.
It is required that the user has clicked the image but I do not want the generic form error message for a 'required' check with the CI form validation class.
As such I quickly made a image_required function in my extended form validation class, and set a rule such that this rule was applied to the hidden field.
function image_required($str)
{
$CI =& get_instance();
$CI->form_validation->set_message('image_required','Please click the image above.');
if($str != '')
{
return TRUE;
}
else
{
return FALSE;
}
}
If the hidden field was blank no error was being called.
I am led to believe now that this is because CI says this field is empty yet it is not 'required', therefore we will ignore all the other validation rules for the field. Is this correct?
If so how can i go about requiring this field be set but having a custom error message?
bangs head
Thanks
If you look at the source code (v2.1.3) for the '_execute' routine (system/libraries/Form_validation.php) you will see on line 486
// If the field is blank, but NOT required, no further tests are necessary
So you are correct, it needs to be required and then it will process your rule.
In order to fix it so you can have a non-required blank field that still processes rules, you should override the '_execute' method by creating a file called 'MY_Form_validation.php' in the application/libraries folder (I think, you might need to check exactly how you extend an existing library) and then copy the '_execute' method and alter the code to continue on a non-required but blank entry.
I do love CI, but I have to say this does not allow the flexibility required. It is perfectly reasonable to have a field that cannot be empty, but is NOT required. As in, you wouldn't enforce "user MUST enter a value", but they cannot submit a blank. I think someone got confused between EMPTY and REQUIRED.
1) REQUIRED: User MUST put a value in the field and it cannot be empty (i.e. '')
2) EMPTY: User does not HAVE to enter a value, BUT, if they do, it's cannot be empty. This not the same as REQUIRED... Looks like I'll be using a callback again.
REQUIRED incorporates two logical steps (1->Must enter a value, and 2->Cannot be empty) these two steps should be separated logically to allow either / or.
In constraint terms it would be either, REQUIRED, NOT NULL. Or NOT REQUIRED, NOT NULL.

Avoiding duplicate code in input validation

Suppose you have a subsystem that does some kind of work. It could be anything. Obviously, at the entry point(s) to this subsystem there will be certain restrictions on the input. Suppose this subsystem is primarily called by a GUI. The subsystem needs to check all the input it recieves to make sure it's valid. We wouldn't want to FireTheMissles() if there was invalid input. The UI is also interested in the validation though, because it needs to report what went wrong. Maybe the user forgot to specify a target or targetted the missles at the launchpad itself. Of course, you can just return a null value or throw an exception, but that doesn't tell the user SPECIFICALLY what went wrong (unless, of course, you write a separate exception class for each error, which I'm fine with if that's the best practice).
Of course, even with exceptions, you have a problem. The user might want to know if input is valid BEFORE clicking the "Fire Missles!" button. You could write a separate validation function (of course IsValid() doesn't really help much because it doesn't tell you what went wrong), but then you'll be calling it from the button click handler and again from the FireTheMissles() function (I really don't know how this changed from a vague subsystem to a missle-firing program). Certainly, this isn't the end of the world, but it seems silly to call the same validation function twice in a row without anything having changed, especially if this validation function requires, say, computing the hash of a 1gb file.
If the preconditions of the function are clear, the GUI can do its own input validation, but then we're just duplicating the input validation logic, and a change in one might not be reflected in the other. Sure, we may add a check to the GUI to make sure the missle target is not within an allied nation, but then if we forget to copy it to the FireTheMissles() routine, we'll accidentally blow up our allies when we switch to a console interface.
So, in short, how do you achieve the following:
Input validation that tells you not just that something went wrong, but what specifically went wrong.
The ability to run this input validation without calling the function which relies on it.
No double validation.
No duplicate code.
Also, and I just thought of this, but error messages should not be written in the FireTheMissles() method. The GUI is responsible for picking appropriate error messages, not the code the GUI is calling.
"The subsystem needs to check all the input it receives to make sure it's valid"
Think of the inputs not so much as a list of arguments, but as a message, it gets easier after that.
The message class has an IsValid member function, it remembers if IsValid was called and what the result was. It also remembers its state, if the state changes then it needs to be re validated. This message class also keeps a list of validation errors.
Now, the UI builds a TargetMissiles message, and the UI can validate it, or pass it directly to the MissileFiring subsystem, it checks to see if the message was validated, if not it validates it, and proceeds / fails depending.
The UI gets the message back, with the list of validations already populated.
The messages with their validation sit in a separate library. No code is duplicated.
This sound OK?
This is what Model-View-Controller is all about.
You build up a model (a launch which is composed of coordinates, missile types and number of missiles) and the model has a validate method which returns a list of errors/warnings. When you update the model (on key-up, <ENTER>, button-press) you call the validate method and show the user any warnings, errors, etc. (Eclipse has a little area just under the tools bar in a dialog that does this, you might want to look at that.)
When the model is valid, you activate the launch missiles button so that the user knows that they can launch the missiles. If you have an update event that is called particularly frequently or a part of the validation that is particularly costly, you can have a validate_light method on the model that you use for validating only the parts that are easy to do.
When you switch to a console based UI you build up the model from the command line arguments, call the same validate method (and report errors to stderr) and then launch the missiles.
Double the validation. In many case the validation is trebled (FKs and not null fields in the DB for example). Depending on your platform it may be possible to code the validation rules once. For example your front end and backend code could share C# business classes. Alternatively you could store the validation rule as metadata that both the backend and front end can access an apply.
In reality the fact that you need different responses to a validation problem (for example the Fire Missile button shouldn't even be enabled until the other inputs are valid) there will be different code associated with the same rule.
I'd suggest an input validation class, which takes the input type (an enumeration) in its' constructor, and provides a public IsValid method.
The IsValid method should return a boolean TRUE for valid and FALSE for invalid. It should also have an OUT parameter that takes a string and assigns a status message to that string. The caller will be free to ignore that message if it wants to, or report it up to the GUI if that's appropriate for the context.
So, in pseudocode (forgive the Delphi-like syntax, but it should be readable to anybody):
//different types of data we might want to validate
TValidationType = (vtMissileLaunchCodes, vtFirstName,
vtLastName, vtSSN);
TInputValidator = class
public
//call the constructor with the validation type
constructor Create(ValidationType: TValidationType);
//this should probably be ABSTRACT, implemented by descendants
//if you took that approach, then you'd have 1 descendant class
//for each validation type, instead of an enumeration
function IsValid(InputData: string; var msg: string): boolean;
And then to use it, you'd do something like this:
procedure ValidateForm;
var
validator: TInputValidator;
begin
validator := TInputValidator.Create(vtSSN);
if validator.IsValid(edtSSN.Text,labelErrorMsg.Text) then
SaveData; //it's valid, so save it!
//if it wasn't valid, then the error msg is in the GUI in "labelErrorMsg".
end;
Each piece of data has its own meta data (type, format, unit, mask, range etc.). Unfortunately this is not always specified.
The GUI controlls need to check the input with the metadata and give warnings/errors if the data is invalid.
Example: a number has a range. The range is provided by the metadata, but the range check is provided by the control.

Resources