(dojo) dojox.form.Manager not firing observers - dojo

I have a customer dialog widget that I am attempting to use dojox.form.Manager on.
I have just stumbled across this control and it looks to do most of what I was implementing (unified onchange events) but much more. There is just one problem, the observer events will not fire.
I have a form element containing multiple digits, form, and custom widgets. Each is set up something like
<form id="resd_tab_details"dojoType="dojox.form.Manager">
<input type="checkbox" dojoType="dijit.form.CheckBox" name="w01" value="w01"
observer="testfunction1">
</form>
I can attach to the form set values and everything else I have tried, except the events.
What might I be doing wrong?

IIRC an observer is a method name on a form manager, not a standalone function. While you didn't give the complete example to test, your naming suggest that you use a standalone function.
You can define a method on the form manager either inline (see an example in its "tests" subdirectory), or in the code by subclassing a manager.

like this...
js portion
dojo.mixin(dijit.byId('frmMngr1'), {
'prvUpdate':function(){
console.log("clicked a check box");
}
})
html portion:
<form dojoType='dojox.form.Manager' id='frmMngr1'><input dojoType='dijit.form.CheckBox' observer='prvUpdate' checked name='title' />

Related

How to make a Input field in AEM/CRX required?

since our AEM guy is out of office at the moment, i need to fix something in our CRX. I have a form with a checkbox in my website, where authors can set a text next to it. Now i am trying to add the functionality to set this checkbox to be required from the authoring dialog.
I was able to find a textfield which has this property in authoring, but in the html in CRX i only see the code required=${required}, where other fields like label are shown like ${properties.label} and have a corresponding node in CRX. I don't understand how the required is implemented and need help here.
I already tried to add required=${required} to my checkbox input markup, but this did not work, since in the authoring dialog there still was no checkbox/switch to make the field required (which was kinda expected).
this is the line in the markup which should be required if the author sets it to required in the authoring dialog:
<input required="${required}" type="checkbox" name="campaignform-termsofservice"/>
this is the whole html of the checkbox i want to be able to make required:
<div data-sly-test="${!empty}" class="form__text">
<label class="maut-checkbox--container">
<input required="${required}" type="checkbox" name="campaignform-termsofservice"/>
<span class="maut-checkbox--checkmark"></span>
<span>${properties.checkboxtext #context='html'}</span>
<div>${properties.tncText}</div>
<div style="color:white;" class="authoring-error" data-sly-test="${wcmmode.edit && !tncDate.tncLinkActivationDate}">${'b2x.maut.campaignform.dialog.tos.activationmessage' # i18n, source='user'}</div>
<input type="hidden" name="maut.field.tnc" value="${tncDate.tncLinkActivationDate}" />
</label>
</div>
Now i only need to figure out how i can show the option to set it to required in the authoring dialog.
Thanks in advance
If you want to know how the required=${required} is implemented then first of all in html of the component look for something like data-sly-use.required. This will have a expression like =com.project.yourProject.className or some js file.
Lets discuss about the java case which is the most common way. What data-sly-use does is that it creates an object of the class that you gave in the expression. In your case your object is required. Then you need to check the java class that the expression evaluates to. Commonly all the backend logic code will be their and if some manipulations or validations are required to be done with the data that the author enters in the dialog will be their. This class will also contain annotations that maps the class variables with the property value of the dialog.
Hope this explains from where this ${required} came from. It will be more clear to you if you look into the java class that is referred to by the data-sly-use expression.

Angular 2 - display one component as drop down in another and grabbing the selected value in parent component

This is my very first Angular 2 project. I created a component (category) that would pull a list of categories from a service stack API and show as a dropdown like this:
<select (change)="onSelect($event.target.value)" [(ngModel)]="selectedCategory.Id">
<option *ngFor="let category of categoriesToDisplay"
value={{category.Id}}>{{category.Name}}
</option>
</select>
Selected Category is: {{selectedCategory.Id}} and Name is {{selectedCategory.Name}}
I have another component (AddExpense) which is a form, where the user can add in the amount, category and hit submit that would POST to another endpoint. For AddExpense component, this is how the .html looks
<form [formGroup]="expense" (ngSubmit)="fileExpense($event)">
Spent <input type="number" formControlName="amt" />
for <input type="text" formControlName="name" />
on <input type="date" formControlName="transdate" />
and file it under category <show-category></show-category>
<button type="submit">Add Expense</button>
</form>
My question is how do I figure out which category from the drop down was selected in the add expense form, when the drop down itself is rendered via the show-category component and pass it on as a form control item for add-expense component's .ts to use?
I might be needing to use the Input and output decorator, but not sure how to nab that particular item thats selected in the dropdown and pass it on as input to the add expense component.
Sounds like you're displaying your first component (ShowCategory) in the second (AddExpense).
Now there is a couple way to do this,
The most obvious is to use Output, ShowCategory will then emit (See EventEmitter and Output example) whenever the selected value is changed.
In the template of AddExpense, you'd simply have to write something like this,
<show-category (change)="category = $event.category"></show-category>
But that's ugly, and frankly it would've been cool if we can do this and let Angular handle the two-way binding,
<show-category [(ngModel)]="category"></show-category>
Turns out it's doable, you can check out documentation for NgModel here, but what's actually useful is an example implementation for a real control like a checkbox
You might've noticed in the example that NgModel is not mentioned anywhere, and that's because we only have to create the mechanism for NgModel to write/read value from your component.
If you search on Google for NgModel ValueAccessor, there's a bunch of blog posts to help you out.
Lastly, I personally doesn't suggest doing what you're doing now if the ShowCategory component is that simple, that increases complexity a little bit, and ShowCategory isn't doing much for now. But what you provided might very well be a minimum working example, so what do I know.
Happy coding!

How to disable the button if some input field is not filled?

IBM web experience factory uses dojo library, I am wondering if the I set <input type="text" name="usrname" required> in the consumer model, does the button still work if the input is not filled?
Well, HTMLFormElement has a method called checkValidity() which you can use.
So, in your case, you could use the :input selector with dojo/query to query all input elements inside a form (includes buttons, checkboxes, textfields, text areas and select boxes) and then use the onChange event to check if the form is valid and change the buttons disabled attribute.
For example:
query("[name=myForm] :input").on("change", function(evt) {
var isInvalid = !evt.target.form.checkValidity();
query("button[type=submit]").attr("disabled", isInvalid);
});
Now all you need to do is to make sure that your button is initially disabled/enabled depending on the initial state of the form.
A full example can be found on JSFiddle: http://jsfiddle.net/j8L6j77g/

Work around to POST requirement

I need to be able give users a link to my site with a parameter that will control their experience on the destination page, but, of course, Moqui does not allow parameters to be passed as a GET transaction. What are ways that I can work around that? It needs to be something that can be sent in an email, via sms and audibly.
An error message would be helpful know exactly what you are running into, but it sounds like the constraint to mitigate XSRF attacks.
The error message for this situation explains the issue and the recommended solution: "Cannot run screen transition with actions from non-secure request or with URL parameters for security reasons (they are not encrypted and need to be for data protection and source validation). Change the link this came from to be a form with hidden input fields instead."
You can pass URL parameters to screens to be used in code that prepares data for presentation, but not to transitions for code that processes input. The solution is to use a hidden form with a link or button to submit the form (that can be styled as a link or button or however you want). This is slightly more HTML than a plain hyperlink with URL parameters, but not a lot more and there are examples in various places in the Moqui itself.
If you are using an XML Screen/Form you can use the link element to do this with the #link-type attribute set to "hidden-form" or "hidden-form-link" (which just uses a hyperlink styled widget instead of a button styled one). If the #link-type attribute is set to "auto" (which is the default) it will use a hidden-form automatically if link goes to a transition with actions.
In plain HTML one possible approach looks something like this:
<button type="submit" form="UserGroupMemberList_removeLink_0">Remove</button>
<form method="post" action=".../EditUserGroups/removeGroup" name="UserGroupMemberList_removeLink_0">
<input type="hidden" name="partyId" value="EX_JOHN_DOE">
<input type="hidden" name="userGroupId" value="ADMIN">
</form>
Note that the button element refers to the form to submit, so can be placed anywhere in the HTML file and the form element can be placed at the end or anywhere that is out of the way (to avoid issues with nested forms which are not allowed in HTML).

disabling a submit button till validation

Is there a way using dojo/dijit to disable the submit button till all the fields in a form are valid. Kind of like having a dojo > method > onChange inside the form? So the submit button only becomes enabled when all the form elements have meet their criteria?
Are you using a dijit.form.Form widget as your form? If you are, I would suggest connecting to the Form's onValidStateChange event. The docs for this event specifically state your use case:
onValidStateChange
Defined by dijit.form._FormMixin
Stub function to connect to if you want to do something (like disable/enable a submit button) when the valid state changes on the form as a whole. Deprecated. Will be removed in 2.0. Use watch("state", ...) instead.
The best way to see what events are available for a given widget is to look at the API Documentation for the widget you are interested in under the "Event Summary" heading. The dojocampus reference documentation often leaves out examples for references to some of the more obscure features of the widgets.
I would suggest to have a hidden button which will submit the form. When you click visbile button run a javascript function that validates all the input and then clicks on the hidden button to submit the form. Please find the pseudo code below
<form action="register">
<input dojoType="dijit.validation.TextBox"/>
<button onClick="validateall()">submit</button>
<button id="submitForm" type="submit" hidden="true"/>
</form>
function validateAll(){
if(AllOk){
clearErrorMessage();
dojo.byId('submitForm').click();
}else{
showErrorMessage();
}