I would like to define a component as optionally required (based on another field's value) - validation

I built two custom components using built-in CQ components. The components' JSP's, along with some custom javascript, have a line like below in order to leverage the built-in components (and their formatting, labels, etc.).
<cq:include path="." resourceType="foundation/components/form/dropdown" />
I have one each of my custom dropdown components on a form. I can mark field A and field B as both being required in their respective components' editor dialog. I can provide required messages so that when either field is blank and the form is submitted, I get a message that the fields are required (with my custom messages). However, what I really want to do is hide or disable field B based on the value supplied in field A. I'm handling this manually via jQuery. However, this of course presents a problem on validation. I want field B to be NOT required when it is hidden/disabled and for it to be required when it is enabled/visible. Since the showing/hiding is done client-side, the server-side validation has know knowledge of the change and still expect a value to be provided for field B.
I'm been trying to poke around in the CQ Widgets API to find if there is something I can do on the client side to set/unset the required property so that when the form gets posted it is handled correctly. I'm guessing that there isn't since the validation seems to be happening on post instead of client-side.
Any ideas/thoughts/options?

It turns out that the link from my comment gave me the idea that I can have custom server-side validation for my form, I just wasn't sure how to connect it to the field. It turns out that all I had to do was create a servervalidation.jsp file in my "B" component. CQ will see the servervalidation.jsp and automatically invoke it for my custom component.
I was then able to examine the submitted value of field "A" (by getting the parameter from the request object) and doing some other custom logic for my needs.
I was then able to optionally do this:
FieldDescription field = FieldHelper.getConstraintFieldDescription(slingRequest);
FieldHelper.checkRequired(slingRequest, field);

Related

Is there a way to enable Javascript on bulkEdit form from Dynamics 365 CRM?

Multiple required fields from bulk edit form are not displayed. The labels for that fields appear on form but the textboxes don't appear. I think this happens because we have scripts that run for that fields. I tried to edit customizations.xml and to put BehaviorInBulkEditForm = "Enabled" but it is not working. Is there another way to enable javascript?
As per the Form XML schema, the BehaviorInBulkEditForm attribute goes on the <event> element, careful you're not putting it somewhere else.
The valid values, as per Microsoft KB 949941, are:
Enabled
If you use this value, the field is enabled. Additionally, the code for the event is run when the event is called.
Disabled
If you use this value, the field is disabled.
EnabledButNoRender
If you use this value, the field is enabled. However, the code for the event is not run when the event is called.
I would recommend to stay away from unsupported customizations which will eventually break in future updates.
If it’s worth, then move all the logic to post-update or pre-update plugins which is fail proof server side implementation rather than client side js route.

Attach meta data / custom data to slack messages sent through the API

I am developing a series of Slack apps for my workspace, and some of them are meant to interact with the content (messages) delivered by the other apps : extracting content IDs that may be referred to by other messages
A concrete example :
Suppose I have an app A "FindUser" that is capable of giving me the user profile when a slack user types find me#example.com, and it replies in the thread with a formatted view of the user profile
I am developing an app B "EditTags", which basically gives me a right click option with "edit tags" (see Slack's Interactive Components/Actions), the idea being that a user could first ask app A to find a user, and then right click on the reply from App A and click the "edit tags" action given by the other app. What this app B does it actually retrieve the tags for the user mentionned by the previous message from app A, and in another reply to the thread it gives some controls to either delete an existing tag OR it shows a select with autocomplete to add new tags.
The B app needs to retrieve the user ID that the A app mentionned previously. So I need some way to pass that data directly in the slack message. When looking at the examples, slack does not seem to provide a way to add arbitrary "metadata" to a message, am I wrong ? Do you have workaround for this ? I mean I could totally send the user ID say, in the footer, so I can just read the footer, but I was planning to use the footer for something else... Is there a way to pass metadata hrough properties that would be hidden to the end user ?
Although this does not feel relevant, I am building a slack nodeJS app using the node slack sdk (and especially the #slack/interactive-messages package)
For the most part the Slack API does not provide any official means to attach custom data / meta data to messages. But with some simple "hacks" it is still possible. Here is how:
Approach
The basic approach is to use an existing field of the message as container for your data. Obviously you want to pick a field that is not directly linked to Slack functionality.
Some field are not always needed, so you can just use that field as data container. Or if its needed, you can include the functional value of that field along with your custom data in the data container.
For example for message buttons you could use the value field of a button and structure your code in a way that you do not need it in its original function. Usually its sufficient to know which button the user client (via the name field), so the value field is free to be used for your custom data. Or you can include the functional value of your button along with the custom data in a data container (e.g. a JSON string) in that field.
Serialization
All messages are transported through HTTP and mostly encoded as UTF-8 in JSON. So you want to serialize / de-serialize your data accordingly, especially if its binary data. If possible I would recommend to use JSON.
Length
The maximum allowed length of most fields is documented in the official Slack API documentation. e.g. for the value field for message buttons can contain up to 2.000 characters. Keep in mind that you need to consider the length of your data after serialization. e.g. if you convert binary data into Base64 so it can be transported with HTTP you will end up with about 1.33 characters for every byte.
Contents
In general I would recommend to keep your data container as small as possible and not include the actual data, but only IDs. Here are two common approaches:
Include IDs of your data objects and load the actual objects
from a data store when the request is later processed.
Include the ID of server session and when processing the request you
can restore the corresponding server session which contains all data
objects.
In addition you might need to include functional values so that the functionality of the field you are using still works (e.g. value of a menu option, see below)
Implementation
Dialogs
Dialogs provide an official field for custom data called state. Up to 3.000 characters.
Message buttons
For Message buttons you can use the message action fields / value. Up to 2.000 characters. Its also possible to use the name field, but I would advise against it, because the maximum allowed length of that field is not documented.
Message menus
For Message menus you can use the value field of an option or the name field of the menu action.
Usually the value field is the better approach, since you have a documented max length of 2.000 and it gives you more flexibility. However, you will need to combine you custom data with the actual functional value for each option. Also, this will not work for dynamic select elements (like users), where you can not control the value field.
When using the name field note, keep in mind that the maximum allowed length of name is not documented, so you want to keep you data as short as possible. Also, if you want to use more than one menu per attachment you need to include the actual name of the menu into your data container.
Normal message attachments
Normal message attachments do not contain any suitable field to be used as container for custom data, since all fields are linked to Slack functionality.
Technically you could use the fallback field, but only if you are 100% sure that your app is never used on a client that can not display attachments. Otherwise your data will be displayed to the user.

skip all ModelForm validation conditionally but include it all otherwise

I have a form that has a selector at the top where a user can select none, or choose a couple options where the validation varies depending on the selection.
If they select none, then it needs to save the model ignoring all the fields and just putting in "None" for the one option. If they select one of the others, then it needs to preform validation on all the other fields.
The thing is, the only way for me to get it to save when "None" is selected, is if I set blank=True on all the fields for the model. So I basically have to turn off all the validation.
But then when they select something, I override the clear method and have to do all the validation manually...
Is there any way for me to use all the built in validation based on the option? In other frameworks I've used, there's an array full of rules, and I can just modify that based on whatever and then run the rules automatically off that array.
Is there a method before the clean, clean_fieldname, and any other validation where I can grab the one selected option, and modify the rules for everything else based on it before it does the build in validation?
I just can't seem to figure out how to use the validation in a versatile way in Django. It seems that if I'm not using them in one specific scenario, it falls down to having to do it all manually. I am fairly new to it, so I'm likely missing something.
Thanks

How to force Wicket "onchange" AJAX events to be triggered if fields fail validation conditions

The specific case I've got in mind is as follows: an AjaxFormComponentUpdatingBehavior("onchange") is added to a TextField in a form. The behavior verifies the text for certain conditions (either the model object or the form component model, doesn't matter), based on which it might display a message (or hide it, if it has already been shown).
The problem is, there are also validators added to the TextField. One of the possible (and likely) scenarios consists of the user typing in, first, a value that causes the message to be displayed by the AJAX request. If, then, he/she types in a value that doesn't pass validation, the message should disappear, but it does not.
Apparently, either the onUpdate() method for the AJAX behavior is not called at all, or I am failing in my attempts to insert a check for non-validated entries (I have tried to test for both null values and empty strings, to no avail; I have no idea what exactly Wicket's validators do to models when data is invalid).
I am wondering if someone who actually understands validators (or AJAX, actually) has any ideas on where the problem could be.
I can post edit and post code if someone tells me this is not a general issue tying validators and AJAX, but most likely a programming mistake. I still believe the former and thus I'll refrain from posting code sections, in order to keep the discussion on an API/theoretical frame.
Thanks.
When using an AjaxFormComponentUpdatingBehavior, if any of the IValidators fail their validation, onError() will be called instead of onUpdate(). Wicket will effectively prevent invalid user input from reaching the IModels in your components, so the component's ModelObject will not be changed at all. The invalid input will probably remain available by means of getInput()/getConvertedInput() (not sure if it will in an AJAX scenario, it sure is in a traditional form submission).
However, take into account that IFormValidators are not executed when using this mechanism. If you've got any, you might be interested in overriding getUpdateModel() so that AjaxFormComponentUpdatingBehavior will not bring maybe-invalid user input into your IModels, and set modelobjects manually when you're certain user input is valid.
Regarding your specific case, you could perform all the required logic in onError() (or rely on Models that will grab data from somewhere else), and just add the components that need refreshing to the AjaxRequestTarget. This is probably what's missing in your scenario.

Validate field and throw exception in JSF, but attach error message to another field?

I have some fields on my page which I want cross-validated. But I don't want error from this validation to be displayed in <h:message> for this fields.
If I add validator to any of the fields, and validator throws exception, error is displayed in <h:message> for this field. On the other hand I HAVE TO throw exception if I want to suppress page from submitting. Just displaying some error message is not enough.
So I created some hidden field on the form, and attached validator there. This validator has access to UIComponents of the fields I want to validate, so it can validate them. When validator throws exception, error shows in <h:message> for hidden field, which I can place anywhere I want.
Everything works, if I put hidden field after the fields I want to validate. (If I put it before, hidden field validation is triggered before even UIComponents of my fields are updated).
The problem is it's nasty hack :) Is there some better way to do it?
The problem is it's nasty hack :) Is there some better way to do it?
Not for the particular functional requirement. It's very true that JSF allows very little fine grained control for cross-validation of multiple fields.
Everything works, if I put hidden field after the fields I want to validate. (If I put it before, hidden field validation is triggered before even UIComponents of my fields are updated).
Components are during validations phase processed in the order as they appear in the component tree. If you have at some point an UIInput at hands which is still to be processed yet, then you need to grab the submitted value by UIInput#getSubmittedValue(). If it is already been processed, then you need to grab the submitted (and converted and validated) value by UIInput#getValue() instead.
So, if you put the hidden field with the validator after the to-be-validated components, then you need UIInput#getValue() to grab the values. If the hidden field is put before the to-be-validated components, then you need UIInput#getSubmittedValue() to grab the values.
i have got this code working for me:
throw new ValidatorException(new ArrayList());
no errors were displayed.

Resources