Статьи

Создание пользовательского элемента формы кредитной карты с полимером

В этой статье мы создадим пользовательский элемент для формы оплаты кредитной картой, используя библиотеку Polymer . Окончательная форма будет выглядеть примерно так:

Форма кредитной карты

Разметка, которая определяет эту форму оплаты, так же тривиальна, как эта:

<credit-card amount="$300"></credit-card> 

Как и ожидалось, под этим пользовательским элементом скрыт дополнительный уровень абстракции, который заботится обо всех сложностях, сопровождающих типичную форму оплаты кредитной картой. Использование пользовательского элемента помогает изолировать любые потенциальные будущие проблемы и сохраняет верхний слой разметки чистым и семантическим.

Форма оплаты кредитной картой будет состоять из:

  • Адрес электронной почты
  • Номер кредитной карты
  • Срок годности
  • Номер CVC

Если вы никогда ранее не использовали библиотеку Polymer или вам необходимо освежить свои знания об основных понятиях веб-компонентов, то вы можете сначала прочитать мои предыдущие статьи о SitPoint:

Эти статьи должны помочь вам освоиться с минимальными знаниями, необходимыми для понимания этой статьи.

Базовая настройка проекта

Прежде чем мы начнем создавать наш пользовательский элемент, мы быстро настроим папку проекта, установив Polymer и все необходимые зависимости через Bower.

 $ bower install --save Polymer/polymer 

Это позволит установить библиотеку Polymer и полизаполнения веб-компонента в папке bower_components .

 bower_components/ ├── core-component-page ├── webcomponentsjs └── polymer 

Обратите внимание, что после перехода на v0.5.0, polyfill platform.js был переименован в webcomponents.js и теперь поддерживается отдельно.

Разработка разметки

Основной подход к созданию пользовательского элемента заключается в том, чтобы сначала решить, как мы собираемся использовать его в нашей разметке, а затем вернуться назад, чтобы создать шаблон пользовательского элемента. В этом случае мы намерены использовать наш пользовательский элемент, указав сумму, подлежащую выплате, с помощью атрибута amount <credit-card> ,

 <credit-card amount="$300"></credit-card> 

Мы credit-card.html с создания файла credit-card.html в корне папки нашего проекта и импортируем файл polymer.html , необходимый для определения пользовательского элемента.

 <link rel="import" href="bower_components/polymer/polymer.html"> 

Мы объявим наш новый элемент <credit-card> с помощью атрибута name <polymer-element> :

 <polymer-element name="credit-card"> <template> <!-- More to come --> </template> </polymer-element> 

Все необходимые стили и разметка, необходимые для разработки нашего пользовательского элемента, будут находиться внутри <template> . Я использовал стандартные элементы управления формой вместе с соответствующими метками для доступности.

 <template> <form> <fieldset name="personalInfo"> <label for="email">Email</label> <input type="email" id="email" placeholder="[email protected]"> </fieldset> <fieldset name="cardInfo"> <label for="cardNum" required>Card Number</label> <input type="tel" id="cardNum" placeholder="0000 0000 0000 0000"> <label for="cardExp" required>Expires</label> <input type="tel" id="cardExp" placeholder="MM/YY"> <label for="cardCVC" required>CVC</label> <input type="tel" id="cardCVC" placeholder="***"> </fieldset> <input type="submit" value="Donate {{amount}}"> </form> </template> 

В приведенном выше HTML нет ничего необычного, кроме следующей строки:

 <input type="submit" value="Donate {{amount}}"> 

Значения внутри {{ }} называются выражениями Polymer. Они предоставляют возможность привязывать данные, указанные в Light DOM (при использовании пользовательского элемента), в Shadow DOM (шаблон пользовательского элемента). В данном случае я имею в виду значение, указанное в атрибуте amount <credit-card> :

 <credit-card amount="$300"></credit-card> 

И это будет переведено на:

 <input type="submit" value="Donate $300"> 

И последнее, что нужно сделать для определения атрибутов в пользовательском элементе, это то, что вам также нужно объявить их в верхней части основного элемента, прежде чем вы сможете их использовать. Это делается следующим образом:

 <polymer-element name="credit-card" attributes="amount"> 

Указывая несколько атрибутов для одного и того же пользовательского элемента, вы можете разделить их через пробел или запятую.

Стилизация пользовательского элемента

Стили могут быть определены в теге шаблона следующим образом:

 <template> <style> /* ... */ </style> </template> 

Или мы можем записать их в новый файл CSS, а затем импортировать файл с помощью тега link .

В попытке сделать нашу настройку более модульной и масштабируемой для обработки будущих улучшений, мы будем использовать второй подход, создав новый файл CSS, credit-card.css , который будет содержать все необходимые стили для нашего пользовательского элемента.

 <template> <link rel="stylesheet" href="credit-card.css"> <form> [...] </form> </template> 

В этой статье основное внимание уделяется функциональному аспекту пользовательского элемента, а не дизайну. Стилизация довольно стандартна, если вы знаете о следующих моментах:

  • По умолчанию все пользовательские элементы установлены как display: inline . Следовательно, в этом случае нам пришлось явно объявить наш элемент как display: block .
  • :host ссылается на сам пользовательский элемент и имеет самую низкую специфичность. Это позволяет пользователям переопределять ваши стили извне.

Регистрация элемента

Регистрация элемента позволяет распознавать его как пользовательский элемент в браузере поддержки. Как правило, элемент можно зарегистрировать напрямую, вызвав конструктор Polymer() ,

 Polymer([ tag-name, ] [prototype]); 

Где:

  • tag-name совпадает с атрибутом name в <polymer-element> . Это необязательно, если <script> который вызывает Polymer, не находится вне <polymer-element> Polymer <polymer-element> .
  • [prototype] содержит открытые свойства и методы, используемые для определения поведения пользовательского элемента.

Самый простой способ вызвать Polymer — разместить встроенный скрипт внутри <polymer-element> Polymer <polymer-element> :

 <polymer-element name="tag-name"> <template> [...] </template> <script>Polymer();</script> </polymer-element> 

Для элементов, которые не требуют пользовательских свойств или методов, вы можете использовать атрибут noscript :

 <polymer-element name="tag-name" noscript> [...] </polymer-element> 

Для краткости мы зарегистрируем наш пользовательский элемент, явно указав имя тега следующим образом:

 <script> Polymer('credit-card', { /* More to come */ }); </script> 

Использование библиотек JavaScript с пользовательскими элементами

На практике поведение пользовательского элемента может зависеть от внешней библиотеки JavaScript. В этом разделе вы познакомитесь с базовым примером использования внешних файлов JavaScript в сочетании с вашим пользовательским элементом.

Давайте улучшим условия оплаты для наших пользователей:

  • Форматирование номера кредитной карты в группы из 4 цифр общей длиной не более 16 цифр.
  • Форматирование даты истечения срока в MM/YY .

Мы будем использовать превосходную библиотеку jquery.payment от Stripe, которая решает эти проблемы с юзабилити и, в свою очередь, нуждается в работе библиотеки jQuery. В двух словах, у нас есть два сценария, которые нужно включить прямо перед закрывающим <polymer-element> , так как нам не нужен JavaScript для загрузки пользовательского элемента.

 <polymer-element name="credit-card" attributes="amount"> <template> [...] </template> <script src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script> <script src='//cdnjs.cloudflare.com/ajax/libs/jquery.payment/1.2.1/jquery.payment.min.js'></script> <script> Polymer('credit-card', {}); </script> </polymer-element> 

Библиотека Polymer предоставляет набор полезных методов обратного вызова для внедрения настраиваемого поведения на разных этапах жизненного цикла создания настраиваемого элемента:

  • created — экземпляр элемента создан.
  • ready — экземпляр элемента был вставлен в DOM.
  • detached — экземпляр элемента был удален из DOM.
  • attributeChanged — Атрибут элемента был добавлен, удален или обновлен.

Больше информации о методах жизненного цикла доступно в руководстве разработчика API

 <script> Polymer('credit-card', { ready: function() { var cardNum = this.$.cardNum, cardExp = this.$.cardExp, cardCVC = this.$.cardCVC, creditCard = this.$.creditCard, $cardNum = jQuery(cardNum), $cardExp = jQuery(cardExp), $cardCVC = jQuery(cardCVC), $creditCard = jQuery(creditCard); /* Formatting input fields */ $cardNum.payment('formatCardNumber'); $cardExp.payment('formatCardExpiry'); $cardCVC.payment('formatCardCVC'); /* Card validation on Form submission */ $creditCard.submit(function(e){ var cardExpiryVal = $cardExp.payment('cardExpiryVal'), cardType = jQuery.payment.cardType($cardNum.val()), isValidNum = jQuery.payment.validateCardNumber($cardNum.val()), isValidExp = jQuery.payment.validateCardExpiry(cardExpiryVal), isValidCVC = jQuery.payment.validateCardCVC($cardCVC.val(), cardType); if (isValidNum && isValidExp && isValidCVC) { /* Success */ } else { /* Validation failed */ } }); } }); </script> 

Polymer предоставляет удобный способ автоматического поиска узлов внутри Shadow DOM, используя this.$.id . $ конечно это сокращенный псевдоним для jQuery . Следовательно, чтобы избежать любых потенциальных конфликтов, мы использовали идентификатор jQuery во всем коде. Кроме того, если вы хотите найти узлы, используя имя класса вместо идентификатора, то у вас есть два варианта:

Получите прямой доступ к Shadow DOM, используя:

 this.shadowRoot.querySelector('.classname'); 

Или добавьте идентификатор ( #container ) в пользовательский элемент и затем используйте:

 this.$.container.querySelector('.classname'); 

Использование пользовательского элемента

Включите файл credit-card.html в ваш документ, а затем использовать пользовательский элемент так же просто, как написать:

 <head> <link rel="import" href="credit-card.html"> </head> <body> <credit-card amount="$300"></credit-card> </body> 

Chrome и Opera теперь полностью поддерживают веб-компоненты в своих последних версиях. IE, Firefox и Safari, однако, все еще отстают . Чтобы включить поддержку этих браузеров, необходимо также включить webcomponents.js webcomponents.js:

 <head> <!-- Load platform support before any code that touches the DOM. --> <script src="bower_components/webcomponentsjs/webcomponents.min.js"></script> <link rel="import" href="credit-card.html"> </head> 

Ознакомьтесь с полным кодом вместе с демонстрацией на Plunker. Я также создал репозиторий проектов на Github для пользовательского элемента кредитной карты.

Вывод

Это не функциональная форма оплаты кредитной картой и далеко не полная. Тем не менее, демонстрация должна быть достаточно хороша, чтобы дать вам возможность начать создавать собственные компоненты дизайна в виде пользовательских элементов с использованием библиотеки Polymer.