I would like to use formik with MUI. There doesn't seem to be a clear path to do this, the documentation does not make sense and the examples are nonsensical with compared to the docs.
For example. This page is at the top level of formik's examples. It is the only example that I can find on formik's site where MUI is integrated.
The example uses the hooks method. There doesn't seem to be an example of the component method
The example imports the button and the text field from the core material UI package. However, in this sandbox, components are imported from #mui/material and form formik-mui. Why two different package? Why isn't this covered in the docs?
All I want to do is build a formik form with mui styling and I can't find any docs for that.
For example, if I want to use a MUI text field, there are online examples that suggest using this method. However, once again I cannot find this in the docs and there is no explanation as to what is happening here or how I apply any props to this text field.
<Form>
<Field
type="email"
name="email"
component={TextField}
color={"error"}
/>
What am I missing here? I just want to build declarative formik forms with MUI.
MuI and Formik are well documented, the only issue is the connection part is missing in both documentations.
For declarative formik you should switch from hook to render prop.
<Formik
//
initialValues={{ email: '' } as FormValues}
onSubmit={handleOnSubmit}
>
{(formik: FormikProps<FormValues>) => (
<Form>
</Form>
)}
</Formik>
To clear a little bit your confusion with the connection part.
Mui don't use Formik so you must code an all form fields the connection to formik yourself.
<TextField
name="email"
label="Email"
value={formik.values.email}
onChange={formik.handleChange}
error={formik.touched.email && Boolean(formik.errors.email)}
helperText={formik.touched.email && formik.errors.email}
/>
For those repetative work it exists these neat library formik-mui.
If you use the library, it's just the following template left.
Attention: The TextField comes from formik-mui
import { TextField } from 'formik-mui';
<Field
component={TextField}
name="email"
label="Email"
/>
Related
I use ngxErrors to display errors for a form control and it works great. Is there any way to get similar functionality for a form or a form group? Currently, I display a form error like this:
<div *ngIf="form.hasError('loginFailed')">
Login Failed
</div>
The bummer is, when I detect that there is a form error (e.g. after the login form is submitted) as opposed to control error, I set it like this:
this.form.setErrors({ loginFailed: true });
this.cdr.detectChanges();
Where this.cdr is an instance of ChangeDetectorRef. This is necessary because I'm using OnPush change detection strategy. So basically it's like calling $scope.$apply() from AngularJS all over again.
What I would really like to do is something more like how ngxErrors does it:
<div ngxErrors="myForm">
<div ngxError="loginFailed" [when]="['dirty', 'touched']">
The login has failed
</div>
But ngxErrors expects myForm to be a control.
This feature is not currently baked into ngxErrors, but I submitted a PR. https://github.com/UltimateAngular/ngxerrors/pull/18
The working syntax is a slight modification of the above:
<div ngxErrors>
<div ngxError="loginFailed" [when]="['dirty', 'touched']">
The login has failed
</div>
</div>
I learned that you do not have to tell child components the form, the FormGroupDirective is available to children automatically.
See this library https://www.npmjs.com/package/ng-error-messages for show error messages based on validation rules:
<input placeholder="Texto:" formControlName="text">
<div errorMessage="text" alias="Super Texto" ></div>
What is the best way to submit a form to an Angular 2 app? I.e. from a non-angular website, to an Angular app?
You cannot simply put the app as the action URL with method="GET" as Angular 2 uses "matrix URL notation" and the browser will add the form fields as regular params (?= , &=).
For example this approach does not work, assuming the URL is an Angular 2 app:
<form method="GET" action="http://myangular2app.com/search;">
<input name="q">
<input type="submit" value="Go">
</form>
The browser will navigate to a URL like http://myangular2app.com/search;?q=mysearch when it needs to be http://myangular2app.com/search;q=mysearch (no question mark).
You can utilise two-way binding with use of the ngModel directive
<input name="q" [(ngModel)]='name'>
You will need to import the forms modules to utilise two-way binding; as well as the Http module for the request:
import { FormsModule } from '#angular/forms';
import { Http } from '#angular/http';
Use this for the call:
this.http.get("http://myangular2app.com/search;q="+mysearch)
If you are new to Angular2 I would recommend you spend a bit of time looking of the Angular2 tutorial 'Tour of Heroes'
This walks you through creating a simple web application involving (among other things) forms, data binding and HTTP requests
I use Keycloak 1.7.0-Final. The user must agree with Term and Conditions at registration.
I enabled "Terms and Conditions" in Authentication > Required actions, But nothing is shown on the registration page.
Also, I cannot find where to configure specific Terms and Condition files for each language.
Could you help?
Thank you.
By default existing users cannot have this page. You need to configure "Terms and Conditions" as "Default Action", then this will be applied by default for all new users.
For existing users, you need to put it manually unser "Users" > "Required actions".
Dont forget to customize the terms page under //themes/base/login/terms.ftl
You will see terms and conditions once the user has filled in the registration form and submits registration. You will have to override the terms.ftl (build your own theme) page if you want it customized and add your own messages locale - see Keycloak Docs - Themes ...
Enable terms and conditions
Regularly you must enable "Terms and Conditions" in Authentication > Required Actions as Enabled and Default Action. By default, this will show a dedicated page after the registration form page, using the template terms.ftl.
Using a checkbox for accepting terms and conditions in the registration page
For this purpose you must specify terms and conditions as Enabled, but not a Default Action. Otherwise you will see the dedicated page using terms.ftl. The problem here is that Keycloak has not a way to enable a checkbox to accept the terms and conditions in the registration page.
Nonetheless, doing a little of reverse engineering I found that when you accept the conditions the user will have an attribute called terms_and_conditions:
In order to reproduce this, you just need to create a custom attribute, named terms_and_conditions, with a numeric value, that seems to be the current time (Date.now()). Being that said, you need an HTML like:
<form>
<!-- other inputs -->
<div>
<input
type="checkbox"
id="terms"
name="user.attributes.terms_and_conditions"
value="<generated value, e.g. 1668029792010>" />
<label for="terms">I accept the terms and conditions</label>
</div>
<div>
<button type="submit">Create user</button>
</div>
</form>
This approach should also be valid if you create that user using the API.
i18n
If your are using a checkbox in the registration page, you can use the standard internationalisation strategy: using the messages properties files. It would probably have a link that reference the content of the "terms and conditions" in the current language. To get the lang code to construct the URL use ${locale.currentLanguageTag}.
Show a page for each language
On the other hand, if you want to use the typical Keycloak strategy using terms.ftl, then you must use the same layout as always and the text will change using the internationalisation.
But if the content of the terms and conditions is very long, then it should be better to create pages for each language, e.g. terms-en.ftl, terms-fr.ftl, etc. These ftl files will only contain the content in the corresponding language and they will be loaded using a code like:
<#include "terms-fr.ftl" />
e.g.
<#if (locale.currentLanguageTag!"en") == "en">
<#include "terms-en.ftl" />
<#else>
<#include "terms-es.ftl" />
</#if>
I hope this helps
You can use Keycloakify to create a theme.
Here is the section related to customizing Terms and conditions.
As I understand it - I cannot use Recurly.js v3 for this... the hosted pages are not very pretty - so we want to style our own, however it seems like the coupon code field is not supported - and its very necessary for our business model.
Am I missing something?
It's definitely supported. Just add an input and use the data-recurly="coupon" attribute:
<input type="text" data-recurly="coupon">
You can see it in the pricing section of the R.JS docs.
I have integrated this into my application in few weeks ago. You can add the following to your page for the coupon code field.
<input type="text" name="couponcode" placeholder="Coupon Code" data-recurly="coupon_code" >
You can get the value by input field name name="couponcode". Following is the PHP code.
'coupon-code' => sanitize_text_field($_POST['couponcode'])
In some forms, Chrome autofill prompts with Credit card autofill.
EDIT:Adding screenshot. This is not the same as browser autocomplete. You need not have entered the value in the same form before.
How should I write my HTML form so the browser detects these as Credit card fields and triggers this behavior?
An example of it working with a Stripe form would be ideal.
This question is pretty old but I have an updated answer for 2019!
You can now tell your browser which fields are for credit card info just by naming the <input> correctly.
The following answer is from my original answer from here: https://stackoverflow.com/a/41965106/1696153
Here's a link to the official current WHATWG HTML Standard for enabling autocomplete.
Google wrote a pretty nice guide for developing web applications that are friendly for mobile devices. They have a section on how to name the inputs on forms to easily use auto-fill. Eventhough it's written for mobile, this applies for both desktop and mobile!
How to Enable AutoComplete on your HTML forms
Here are some key points on how to enable autocomplete:
Use a <label> for all your <input> fields
Add a autocomplete attribute to your <input> tags and fill it in using this guide.
Name your name and autocomplete attributes correctly for all <input> tags
Example:
<label for="frmNameA">Name</label>
<input type="text" name="name" id="frmNameA"
placeholder="Full name" required autocomplete="name">
<label for="frmEmailA">Email</label>
<input type="email" name="email" id="frmEmailA"
placeholder="name#example.com" required autocomplete="email">
<!-- note that "emailC" will not be autocompleted -->
<label for="frmEmailC">Confirm Email</label>
<input type="email" name="emailC" id="frmEmailC"
placeholder="name#example.com" required autocomplete="email">
<label for="frmPhoneNumA">Phone</label>
<input type="tel" name="phone" id="frmPhoneNumA"
placeholder="+1-555-555-1212" required autocomplete="tel">
How to name your <input> tags
In order to trigger autocomplete, make sure you correctly name the name and autocomplete attributes in your <input> tags. This will automatically allow for autocomplete on forms. Make sure also to have a <label>! This information can also be found here.
Here's how to name your inputs:
Name
Use any of these for name: name fname mname lname
Use any of these for autocomplete:
name (for full name)
given-name (for first name)
additional-name (for middle name)
family-name (for last name)
Example: <input type="text" name="fname" autocomplete="given-name">
Email
Use any of these for name: email
Use any of these for autocomplete: email
Example: <input type="text" name="email" autocomplete="email">
Address
Use any of these for name: address city region province state zip zip2 postal country
Use any of these for autocomplete:
For one address input:
street-address
For two address inputs:
address-line1
address-line2
address-level1 (state or province)
address-level2 (city)
postal-code (zip code)
country
Phone
Use any of these for name: phone mobile country-code area-code exchange suffix ext
Use any of these for autocomplete: tel
Credit Card
Use any of these for name: ccname cardnumber cvc ccmonth ccyear exp-date card-type
Use any of these for autocomplete:
cc-name
cc-number
cc-csc
cc-exp-month
cc-exp-year
cc-exp
cc-type
Usernames
Use any of these for name: username
Use any of these for autocomplete: username
Passwords
Use any of these for name: password
Use any of these for autocomplete:
current-password (for sign-in forms)
new-password (for sign-up and password-change forms)
Resources
Current WHATWG HTML Standard for autocomplete.
"Create Amazing Forms" from Google. Seems to be updated almost daily. Excellent read.
"Help Users Checkout Faster with Autofill" from Google in 2015.
From this answer https://stackoverflow.com/a/9795126/292060, it looks like Chrome is either matching a regex pattern on the field name, or the form is explicitly using the x-autocompletetype attribute, like this (This example uses "somename" to avoid mixing issues matching on the name):
<input type="text" name="somename" x-autocompletetype="cc-number" />
Practically, you could do both, picking a name that matches, and the x-autocompletetype:
<input type="text" name="ccnum" x-autocompletetype="cc-number" />
Do you have a view-source of the input box in your screenshot? That would show if it's matching on the name or on the x-autocompletetype attribute.
The answer I linked to has several links for more information; I didn't repeat them here.
Some other comments:
I know Chrome pops a question whether to save the credit card information (I don't), but I don't know if it is popping that question regardless of how it detected it. That is, I'm not sure if Chrome will autocomplete separate fields of credit cards along with other fields, or if it needs to save the whole thing as a credit card.
Your question was how to do it, not whether to. But from the comment in your question, I agree that you might not want to autocomplete the credit card fields. Personally I find it disconcerting when it happens, even knowing it's local in my browser (I especially feel this way about the CVV, and get a surprising amount of resistance when I report it). However, there are posts that find it frustrating when a customer wants to use it, has Chrome set up with credit cards, and a website blocks it.
Thanks #goodeye for directing me to the correct answer.
To trigger the Credit Card autofill,
SSL must be enabled on your form
Most variants of standard credit card field names should work if SSL is enabled.
Here is a link to the regexes Chrome uses to trigger detection
As of 04-12-2022 (from the link above)
/////////////////////////////////////////////////////////////////////////////
// credit_card_field.cc
/////////////////////////////////////////////////////////////////////////////
// ... snipped ...
const char kCardNumberRe[] =
"card.?number|card.?#|card.?no|cc.?num|acct.?num"
"|nummer" // de-DE
"|credito|numero|número" // es
"|numéro" // fr-FR
"|カード番号" // ja-JP
"|Номер.*карты" // ru
"|信用卡号|信用卡号码" // zh-CN
"|信用卡卡號" // zh-TW
"|카드"; // ko-KR
Chrome is using autocomplete attribute in inputs for autofill. This will probably be used by other browsers in future if not yet.
autocomplete's actual use is to say whether autocomplete is enabled or not by specifying autocomplete="off". But chrome uses the same for autofill.
Autofill and autocomplete are different, so don't get confused.
Autofill is what chrome uses to fill up forms from what is stored in your autofill settings in your chrome browser.
Autocomplete is what all browsers use to remember what you may have entered previously in the same form by suggesting values as you type. So when you use autocomplete="off" on an input, browser stops suggesting these values.
Coming back to the solution, for autofill to work use cc-number for card number, cc-name for card holder name, cc-csc for cvc and cc-exp for card expiry date in your autocomplete attribute.
Here is a sample that will be compatible with chrome autofill:
<div>
<label for="frmNameCC">Name on card</label>
<input name="ccname" id="frmNameCC" required placeholder="Full Name" autocomplete="cc-name">
</div>
<div>
<label for="frmCCNum">Card Number</label>
<input name="cardnumber" id="frmCCNum" required autocomplete="cc-number">
</div>
<div>
<label for="frmCCCVC">CVC</label>
<input name="cvc" id="frmCCCVC" required autocomplete="cc-csc">
</div>
<div>
<label for="frmCCExp">Expiry</label>
<input name="cc-exp" id="frmCCExp" required placeholder="MM-YYYY" autocomplete="cc-exp">
</div>
If you have credit cards saved in your chrome browser right now, try clicking Run code snippet button above and you can see chrome autofill in action.
Source: https://developers.google.com/web/updates/2015/06/checkout-faster-with-autofill
Chrome also scans thru placeholders.
Example: <input placeholder='dd-mm-yyyy'/> will trigger it to become a credit card field.