Page 1 of 1

Validation Before Dialog Closed [solved]

PostPosted: Wed Feb 14, 2018 5:16 pm
by DaveL17
I have a device dialog with a list element where the user can make selections and press a button to add an item to the list.

I want to validate the action (device not already in the list, etc.) but placing the validation code and returning an errorDict within the button callback doesn't seem to work. So instead I call validateDeviceConfigUi from within the button callback and do something like:

Code: Select all
        a, b, c = self.validateDeviceConfigUi(valuesDict, typeId, devId)

        if not a:
            indigo.server.log(u"Error adding device.")

So if the validation returns false, then a is False and will throw the log message.

Is there a more straightforward way to do validation within a callback, or is this my best bet?

Re: Validation Before Dialog Closed

PostPosted: Wed Feb 14, 2018 6:21 pm
by jay (support)
I don't think I'm following the scenario: can you post the code (or some subset) of your button's callback including what you're returning when there's an error?

Re: Validation Before Dialog Closed

PostPosted: Wed Feb 14, 2018 8:27 pm
by DaveL17
The headline: Never mind. I was making it too complicated.

The scenario: a user opens a device dialog, pulls a device from a dropdown list and clicks an Add button. The added device is then added to the list control. The user could theoretically add 10 or 20 or 50 devices and I want to validate each choice as it's made so they don't get to the point of saving the dialog and having prior choices fail validation. I was trying to do a typical validation/errorMsgDict but the add button wouldn't cause the errorMsgDict to fire on the dialog. So then I went down a rabbit hole to pull in validateDeviceConfigUi, but it's overkill. I can do the validation from within the button callback and reject the add as needed. I can further limit possible fails by limiting the devices available for selection.

I still haven't decided if I want to show any error notification in the event log or to the dialog.

Re: Validation Before Dialog Closed

PostPosted: Wed Feb 14, 2018 8:39 pm
by Colorado4Wheeler
I do almost the exact same thing in multiple plugins, including the HKB that's being beta tested now:

Code: Select all
   #
   # Add device or action
   #
   def serverButtonAddDeviceOrAction (self, valuesDict, typeId, devId):
      try:
         errorsDict = indigo.Dict()
         
         if "deviceLimitReached" in valuesDict and valuesDict["deviceLimitReached"]: return valuesDict
         if valuesDict["device"] == "-line-":
            errorsDict["showAlertText"] = "You cannot add a separator as a HomeKit device."
            errorsDict["device"] = "Invalid device"
            errorsDict["action"] = "Invalid action"
            return (valuesDict, errorsDict)

                          ...... truncated for demonstration purposes

      except Exception as e:
         self.logger.error (ext.getException(e))   
         
      return (valuesDict, errorsDict)      


I actually do quite a bit in this function, including a substantial amount of device validation against the form they fill out before they hit the button.

Re: Validation Before Dialog Closed

PostPosted: Wed Feb 14, 2018 8:58 pm
by DaveL17
Fudge nuggets.

So you can pass an errorDict() from the callback. I was trying this:

Code: Select all
                error_msg_dict['foo'] = u"Error!"
                error_msg_dict['showAlertText'] = u"Error!"
                return False, valuesDict, error_msg_dict

but I was getting an exception on the bool.

I am good now. Thanks!

Re: Validation Before Dialog Closed

PostPosted: Thu Feb 15, 2018 9:49 am
by jay (support)
DaveL17 wrote:
Fudge nuggets.

So you can pass an errorDict() from the callback. I was trying this:

Code: Select all
                error_msg_dict['foo'] = u"Error!"
                error_msg_dict['showAlertText'] = u"Error!"
                return False, valuesDict, error_msg_dict

but I was getting an exception on the bool.

I am good now. Thanks!


Yes, that's exactly why I wanted to see the code... :lol:

Re: Validation Before Dialog Closed

PostPosted: Thu Feb 15, 2018 9:58 am
by DaveL17
jay (support) wrote:
Yes, that's exactly why I wanted to see the code... :lol:

Yeah, yeah. What is this--StackOverflow? :D

Re: Validation Before Dialog Closed

PostPosted: Thu Feb 15, 2018 10:29 am
by Colorado4Wheeler
DaveL17 wrote:
Yeah, yeah. What is this--StackOverflow?

Well, obviously... :shock:

Re: Validation Before Dialog Closed

PostPosted: Thu Feb 15, 2018 11:14 am
by jay (support)
DaveL17 wrote:
Yeah, yeah. What is this--StackOverflow? :D


Honestly? I was just too lazy to dig up an example but I knew if I saw the code I could probably spot the issue... :mrgreen:

Re: Validation Before Dialog Closed

PostPosted: Thu Feb 15, 2018 11:20 am
by Colorado4Wheeler
We know it's not StackOverflow because for some reason there has be a preponderance of super old threads being reopened and there isn't a mod in here stomping on it and saying "this was already answered in xyz thread and I'm locking this topic forever". :lol:

Well that and the trolling and flaming that those who consider the questions on SO to be so rudimentary as to say "why did you bother even living today?"

Re: Validation Before Dialog Closed

PostPosted: Thu Feb 15, 2018 11:38 am
by DaveL17
jay (support) wrote:
Honestly? I was just too lazy to dig up an example but I knew if I saw the code I could probably spot the issue... :mrgreen:

Where's the fun in that? :twisted:

All kidding aside, here's my (working) example for the future.

Devices.xml
Code: Select all
            <!-- Add Device -->
            <Field id="addDevice" type="button">
                <Label/>
                <Title>Add Device</Title>
                <CallbackMethod>customDeviceAdd</CallbackMethod>
            </Field>

customDeviceAdd:
Code: Select all
    def customDeviceAdd(self, valuesDict, typeId="", devId=None):

        dev_list = literal_eval(valuesDict['dynamicDeviceList'])  # List of tracked devices
        dev = indigo.devices[int(valuesDict['deviceMenu'])]  # Device to be added

        # If the device is a valid choice
        if type(dev) in [indigo.DimmerDevice, indigo.RelayDevice, indigo.SensorDevice]:

            new_dev  = tuple([unicode(dev.id), unicode(dev.name)])  # Create tuple for new dev
            dev_list.append(new_dev)  # Add tuple to list of tracked devices
            valuesDict['dynamicDeviceList'] = unicode(dev_list)  # Replace list of tracked devices with updated list

            return valuesDict

        # If the device is not a valid choice (this shouldn't be the case
        # because valuesDict['deviceMenu'] should only pass compatible
        # device types).
        else:

            error_msg_dict = indigo.Dict()
            error_msg_dict['deviceMenu'] = u"Error message."
            error_msg_dict['showAlertText'] = u"Error message."

            return valuesDict, error_msg_dict


Re: Validation Before Dialog Closed

PostPosted: Thu Feb 15, 2018 11:40 am
by DaveL17
Colorado4Wheeler wrote:
We know it's not StackOverflow because for some reason there has be a preponderance of super old threads being reopened and there isn't a mod in here stomping on it and saying "this was already answered in xyz thread and I'm locking this topic forever". :lol:

Well that and the trolling and flaming that those who consider the questions on SO to be so rudimentary as to say "why did you bother even living today?"

Right? And my original question would've been edited twice, down voted into oblivion, and then locked.