IPub\Phone – práce s tel. čísly ve formulářích, šablonách a databázích jednoduše
- akadlec
- Člen | 1326
IPub\FormPhone
Pokud ve formulářích řešíte získání tel. čísla od vašeho návštěvníka/klienta, víte že to je občas docela problém, každý jej zadává jak se mu zlíbí a jeho validace je docela problematická. A tak jsem vytvořil formulářový element který je založený na další knihovně IPub\Phone
Práce s touto extension je velice jednoduchá. Stačí si extension zaregistrovat (pokud chcete využívat všechny její featurky) a pak jednoduše vložit element pro vložení tel. čísla:
$form = new Nette\Application\UI\Form;
$form
->addPhone('phone_number', 'Your phone number');
Element samozřejmě disponuje i vlastním validátorem. Chcete-li omezit možnost zadání čísla jen na vybrané země, stačí je specifikovat:
$form = new Nette\Application\UI\Form;
$form
->addPhone('phone_number', 'Your phone number')
->addRule(FormPhone\Forms\PhoneValidator::PHONE, 'Invalid phone.')
->setAllowedCountries(['CZ', 'SK', 'PL']);
Případně se dá také udělat validace na typ tel. čísla jako je pevná linka, mobil apod.
$form = new Nette\Application\UI\Form;
$form
->addPhone('phone_number', 'Your phone number')
->addRule(FormPhone\Forms\PhoneValidator::PHONE, 'Invalid phone.')
->setAllowedPhoneTypes(['mobile', 'fixed_line']);
Když se pole pro tel. číslo vykreslí ve formuláři, je tvořeno dvěmi políčky – jedno je select pro výběr země a tedy mezinárodního předčíslí a pak samotné číslo.
K dispozici je taky klientská část s JS validací, stačí přilinkovat patřičné JS soubory a to je vše. Kromě JS validace je v JS taky dostupná maska, tj. input box pro zadání čísla se vám naformátuje podle zvolené země, takže pro ČR to bude 234 456 789 tedy s mezerami mezi 3číslí
IPub\Phone
Tato knihovna je jakýmsi jádrem pro všechny knihovny pracujícím z tel. číslem. Implementuje PHP port z Googlí knihovny.
Práce s touto extension je docela jednoduchá. Hlavní prvek je vytvoření entity ze zadaného čísla, a tak z čísel co máte v DB máte možnost vytvořit validní čísla, případně zjistíte že čísla jsou nevalidní.
$phoneNumber = IPub\Phone\Entities\Phone::fromNumber($numberFromDB, $countryOrNothing);
V $phoneNumber pak budete mít entitu nesoucí informace o tel. čísle a to včetně naformátované hodnoty pro národní i mezinárodní zobrazení.
Další funkcionalitou je validátor pro formuláře. Pokud nechcete používat rozšíření pro formuláře zmíněné výše, ale chcete jen validátor, je to jednoduché, stačí jej vložit do textového pole:
$form = new Nette\Application\UI\Form;
$form
->addText('phone_number', 'Your phone number')
->addRule(Phone\Forms\PhoneValidator::PHONE, 'Invalid phone.', ['GB', 'US', 'CZ']);
Celá validace je pak postavena na tom, že uživatel musí zadat číslo celé jak po něm chcete. Pokud tedy chcete mít možnost zadat libovolné číslo, tak nastavíte automatickou detekci a pokud uživatel nevyplní číslo v mezinárodním formátu tak mu zobrazíte hlášku. Pokud víte že čísla budou jen CZ a SK tak si zvolíte tyto země a tady už může být číslo zadáno zkráceně…o dalších možnostech a nastaveních se pak samozřejmě dočtete v malém quick startu
K dispozici je taky klientská část s JS validací, stačí přilinkovat patřičné JS soubory a to je vše.
Pokud nechcete jen validovat formuláře ale s číslem i dále pracovat, je zde k dispozici i malý helper a macro pro latte
IPub\DoctrinePhone
No a pokud ve svých projektech využíváte Doctrinu tak je pro vás připravena knihovna co rozšíří doctríní datové typy o telefonní číslo a tak když v entitě načtete tel. číslo, bude přetvořeno na objekt nesoucí kompletní informace o čísle a stejně tak jej můžete entitě předat a ta se pak pomocí událostí postará o jeho korektní uložení v mezinárodním formátu tak aby bylo možne jej vždy bez problému rozparsovat.
Kdyby někoho napadlo jak to třeba vylepšit či udělat něco jinak, tak klidně napište.
Editoval akadlec (31. 12. 2015 10:44)
- sucho
- Člen | 57
Ahoj vyzerá to pekne skúšal som to integrovať
ale pri SK krajine vyzerá tá maska dosť zle na mobilnom čísle
stále to ponúka ako pevnú linku v tvare __/___ ___ __
skúšal som meniť aj AllowedPhoneTypes na rôzne aj EMERGENCY a žiadna zmena v SK maske
$form->addPhone('phone', _('Telefón'))
->setAllowedCountries(['CZ', 'SK'])
->setAllowedPhoneTypes([\IPub\Phone\Phone::TYPE_MOBILE])
->addCondition(UI\Form::FILLED)
->addRule(\IPub\FormPhone\Forms\PhoneValidator::PHONE, _('Zadajte telefónne číslo v správnom formáte'));
povezme že máme mobilné číslo 0901 234 567
a ono to prerobí na 09/012 345 67 alebo 90/123 456 7_
správne po výbere krajiny by malo byť (v selecte +421) a (v inpute
901 234 567)
chcem sa opýtať či o masku sa stará ipub/form-phone alebo
giggsey/libphonenumber-for-php
a ako by sa to dalo vyriešiť
Editoval sucho (1. 2. 2016 10:16)
- F.Vesely
- Člen | 369
Doplnek vypada moc pekne, funguje az na jednu chybku. Pokud mam
$form->addPhone('phone')
->addCondition(Form::FILLED)
->addRule(PhoneValidator::PHONE, 'Enter valid telephone.');
tak mi nefunguje JS validace, protoze addCondition()
dava do
data-nette-rules
jako control [phone]
a ne
[phone][number]
.
- Kaliver
- Člen | 12
@akadlec Myslim, ze vzorove cislo momentalne generujes cez
getExampleNumber()
v giggseyho kniznici. Ta vsak prebera len
$regionCode
a nasledne je tam natvrdo nastaveny type
FIXED LINE.
public function getExampleNumber($regionCode)
{
return $this->getExampleNumberForType($regionCode, PhoneNumberType::FIXED_LINE);
}
Takze tvoj script bude fixne v pripade SK nastavovat masku pre pevnu linku.
Nechcel by si to upravit, tak ze by si vyuzil funkciu
getExampleNumberForType()
?
Editoval Kaliver (17. 2. 2016 11:29)
- Landsman
- Člen | 152
akadlec napsal(a):
obě? Protože tohle je chyba pokud není registrována extension IPub\Phone
To musíš přidat 2 extension? Proč?
Nakonec jsem to vyřešil jednodušeji: http://jsfiddle.net/dKRGE/3/
- akadlec
- Člen | 1326
@F.Vesely hele nevim jak to zkoušíš, ale mě ta validace funguje ok. Můžeš když tak gist či příklad někde?
@Kaliver hele doplnil sem možnost generovat example number zvoleného typu. Jen to asi nebude řešit tvůj problém v JS kde se ty templaty generujou ze selectu země. Leda by se pro SK generovaly dvě verze předčíslí :(
@Landsman Proč 2 extension? No jednoduše proto, protože jedna rozšiřuje druhou. IPub/Phone je jádro, má v sobě veškerou funcionalitu práce s číslem a k tomu je jako doplněk IPub/FormPhone co ti do formu přináší možnost jednoduše implementovat zadávání tel. čísla. Netuším cos řešil, ale to cos postnul v jsfiddle je úplně něco jiného než řeší tahle sada doplňků. To tvoje je jen primitivní input maska pole, nikoliv validace že zadané číslo je ok a je reálné.
PS: Všem sorry za poněkud delší odmlku :)
PSS: Všechny tři doplňky prošly refactorem a pojedou vám v nejnovějším nette 2.4. Enjoy ;)
- akadlec
- Člen | 1326
Myslíš do inputu co generuje ipub/form-phone? Pokud jo a generuješ form automaticky přes nette, tak aktuálně nijak. Pokud děláš ruční render tak pak přímo v šabloně:
{input phones-number:number class => 'my-class'}
Já osobně nemám rád nastavování CSSek v phpku tak sem to tam nedal, ale teoreticky by to šlo dodělat, nějaký setter co bude přidávat atributy generovanému inputu.
- MartinS
- Člen | 2
Ahoj,
je možné docílit html5 validního prvku? Je pravda že id
„frm-registerForm-registerProfileFactoryForm-phone“ neexistuje.
Html Error: The „for“ attribute of the „label“ element must refer to a
non-hidden form control
<div class="form-group">
<label for="frm-registerForm-registerProfileFactoryForm-phone">Telefonní číslo:</label>
<select name="phone[country]" id="frm-registerForm-registerProfileFactoryForm-phone-country" data-ipub-forms-phone="" data-settings='{"field":"phone[number]"}'><option data-mask="999 999 999" value="CZ">+420 (Česká republika)</option></select><input name="phone[number]" id="frm-registerForm-registerProfileFactoryForm-phone-number" type="text" class="form-control" data-nette-empty-value="" data-nette-rules='[{"op":"optional"},{"op":":filled","rules":[{"op":"IPub\\FormPhone\\Forms\\PhoneValidator::validatePhone","msg":"Zadejte platné telefonní číslo."}],"control":"phone"}]'>
</div>
- sten192
- Člen | 2
Ahoj, rozsirenie som sa pokusal instalovat podla navodu na GtHube.
V config.neon mam nasledovne riadky (extensions):
phone: IPub\Phone\DI\PhoneExtension
formPhone: IPub\FormPhone\DI\FormPhoneExtension
Nette mi vsak vyhadzuje nasledovnu chybu:
Strict standards
Declaration of IPub\FormPhone\Controls\Phone::getControlPart() should be compatible with Nette\Forms\Controls\BaseControl::getControlPart()
V com moze byt problem? Pouzivam Nette 2.4
- CZechBoY
- Člen | 3608
@F.Vesely No, tam chybí ten návratovej typ, ne?
Editoval CZechBoY (15. 8. 2017 16:42)
- cafesk8
- Člen | 103
Zdravím,
při vložení ipub.formPhone.js mi console píše chybovou hlášku
$(...).ajaxSuccess is not a function
na řádku 481:
// Autoload for ajax calls
$(document).ajaxSuccess(function () {
// Autoload plugin
IPub.Forms.Phone.load();
});
Místo nette.ajax.js používám v projektu Naja.js.
Skripty mám vložené následovně:
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
<script src="https://nette.github.io/resources/js/netteForms.min.js"></script>
<script src="/assets/js/Naja.js"></script>
<script src="/assets/js/ipub.formPhone.js"></script>
<script src="/assets/js/live-form-validation.js"></script>
<script src="/assets/js/app.js"></script>
Nevíte v čem by mohl být problém?
Díky
Editoval cafesk8 (19. 6. 2018 12:03)
- cafesk8
- Člen | 103
Zdravím,
mám ajaxový formulář, kde mám přidané povinné pole pro české telefonní číslo. Celé to vypadá takto:
protected function createComponentNewWhatever()
{
$form = new Nette\Application\UI\Form;
$form->setRenderer(new \AlesWita\FormRenderer\BootstrapV4Renderer);
$form->getElementPrototype()->class = 'ajax';
$form->addProtection('Vypršel časový limit, odešlete formulář znovu');
# zde je ještě spousta dalších prvků formuláře
$form->addPhone('nv_telefon', 'Telefon:')
->setAllowedCountries(['CZ'])
->addRule(\IPub\FormPhone\Forms\PhoneValidator::PHONE, 'Musíte zadat platné tel. číslo.')
->setRequired('Musíte zadat Vaše tel. číslo.');
$form->addSubmit('nv_submit', 'Přidat vozidlo');
$form->onSubmit[] = [$this,'handleZkontrolujForm'];
$form->onSuccess[] = [$this,'handleNewWhatever'];
return $form;
}
public function handleZkontrolujForm(Form $form)
{
if ($this->isAjax()) {
$this->redrawControl('formSnippet');
}
}
public function handleNewWhatever(Form $form)
{
$this->flashMessage('Úspěšně přidáno.','success');
$form->reset();
if ($this->isAjax()) {
$this->redrawControl('formSnippet');
$this->redrawControl('flashes');
}
}
Vše mi fungovalo, včetně live validace apod. Problém nastal až při přidání pole pro telefon. Při načtení se mi krásně načte pole kde jsou — --- — pro vyplnění tel. čísla. Problém nastane až poté, co formulář odešlu. Ať již je číslo validní a formulář se vyresetuje a zobrazí se success flash message, či nikoliv (např. 123 456 789) a zobrazí se hláška, že musím vyplnit platné tel. číslo, tak mi z pole zmizí takový ten placeholder — --- — a můžu do pole zadávat jakékoliv znaky a také jakýkoliv počet znaků.
Nevíte někdo v čem by mohl být problém?
- akadlec
- Člen | 1326
Ad select, tahle featura tam neni, ale mohla by se dodělat.
Ad js formátování čísel, problém je v JS. Když se ti form načte
napoprvé klasickým requestem, tak se spustí potřebný JS který aktivuje
formátování. Když ale uděláš ajaxový request, tak dojde k překreslení
DOMu kde máš právě ten input, ale už se znova nezavolá. Řešením je abys
v onSuccess metodě toho ajaxu znova initnul JS pro tel. číslo. Samotné
řešení je pak na tom jak máš ty JS řešeny. Jedno z nich může být
takové že si udělat extension pro nette ajax (pokud jej používáš) která
bude dělat ten init po onSuccess
- cafesk8
- Člen | 103
akadlec napsal(a):
Ad select, tahle featura tam neni, ale mohla by se dodělat.
Ad js formátování čísel, problém je v JS. Když se ti form načte napoprvé klasickým requestem, tak se spustí potřebný JS který aktivuje formátování. Když ale uděláš ajaxový request, tak dojde k překreslení DOMu kde máš právě ten input, ale už se znova nezavolá. Řešením je abys v onSuccess metodě toho ajaxu znova initnul JS pro tel. číslo. Samotné řešení je pak na tom jak máš ty JS řešeny. Jedno z nich může být takové že si udělat extension pro nette ajax (pokud jej používáš) která bude dělat ten init po onSuccess
Díky za odpověď, select si zatím pouze schovám a JS jsem vyřešil takto, třeba to někomu v budoucnu pomůže (používám Naja.js namísto nette.ajax.js):
function LoaderExtension(naja) {
naja.addEventListener('complete', reInitPhone.bind(this));
function reInitPhone() {
IPub.Forms.Phone.load();
}
return this;
}
naja.registerExtension(LoaderExtension);
document.addEventListener('DOMContentLoaded', naja.initialize.bind(naja));
Zajímavé je, že v JS pluginu je už a nefungovalo to (asi to bude tím, že Naja.js oproti nette.ajax.js nemá funkci ajaxSuccess ?):
// Autoload plugin
IPub.Forms.Phone.load();
// Autoload for ajax calls
$(document).ajaxSuccess(function () {
// Autoload plugin
IPub.Forms.Phone.load();
});
Editoval cafesk8 (20. 6. 2018 9:25)