react модальное окно с формой

5ba87e34 d6f9 46aa 9f06 14bc60156130

Данный материал является частью цикла статей «Создаем приложение на React с использованием Redux». Не забудьте посмотреть другие статьи по этой теме :-)

Компоненты модального окна успеха и ошибки

Начнем с создания следующей структуры папок в директории component :

745swKg4Ci 1609172456

Сначала мы собираемся изменить файл SuccessModal.js :

Этот код довольно прост. Мы используем компоненты react-bootstrap для модального внутри функционального компонента. Через объект props мы отправляем разные параметры нашему модальному окну и одно событие. Это событие закроет модальное окно после того, как мы нажмем кнопку.

Таким же образом изменим файл ErrorModal.js :

Далее, нам нужно изменить файл ModalStyles.css :

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

Создание конфигурации для элементов ввода

Мы уже установили библиотеку моментов в предыдущем посте, но если вы еще этого не сделали, сделайте это (она нужна нам для элемента управления datepicker) с помощью следующей команды:

Теперь давайте изменим файл InputConfiguration.js :

Динамическое создание входных элементов

dZatBg ROh 1609172456

7E8ALfb0uL 1609172456

Файл Input.js будет функциональным компонентом, поэтому давайте изменим его соответствующим образом:

На данный момент мы просто импортируем все необходимые нам ресурсы, инициализируем поле ввода и сообщение об ошибке и установим значение для этого сообщения, если элемент управления недействителен, если он должен быть проверен и если сделать его активным. Мы не хотим отображать ошибку, если пользователь вообще не поместил курсор мыши внутри этого компонента. Далее, мы возвращаем это поле ввода (которое на данный момент имеет значение NULL) родительскому компоненту.

Под оператором if и над блоком return мы собираемся добавить код для заполнения свойства inputField :

Завершение компонента CreateOwner

Давайте добавим кнопки к нашему компоненту, чтобы завершить создание компонента.

Внутри тега Form и ниже тега
добавьте этот код:

Мы добавляем две кнопки, и кнопка «Создать» неактивна, пока форма недействительна.

Теперь наша форма выглядит так:

1ThapjWUn4 1609172457

Все работает как надо.

Заключение

Прочитав этот пост, вы узнали:

Спасибо, что прочитали статью, и я надеюсь, что вы нашли в ней что-то полезное.

Источник

Модальные окна на Angular, Angular 2 и ReactJS

В этой статье мы рассмотрим, как создавать всплывающие и перекрывающие элементы на React, Angular 1.5 и Angular 2. Реализуем создание и показ модального окна на каждом из фреймворков. Весь код написан на typescript. Исходный код примеров доступен на github.

Введение

Что такое «всплывающие и перекрывающие» элементы? Это DOM элементы, которые показываются поверх основного содержимого документа.

Это различные всплывающие окна (в том числе модальные), выпадающие списки и менюшки, панельки для выбора даты и так далее.

Замечание: мы не будем рассматривать позиционирование элементов с разными координатами и родителями — это отдельная сложная тема, полная костылями, javascript-ом и обработкой неожиданных событий браузера.

Например, ни один из существующих способов не решает идеально проблему позиционирования, если нам нужно сделать компонент типа select или autocomplete с выпадающим списком возле элемента.

Все способы требуют обработки события resize. В общем, нет тут хорошего решения.

Примеры

Все примеры содержат одинаковую верстку, и состоят из поля ввода с текстом и кнопки. По нажатию на кнопку введенный текст появляется в «модальном» окошке с кнопкой «Закрыть».

Все примеры написаны на typescript. Для компиляции и бандлинга используется webpack. Чтобы запустить примеры, у вас должен быть установлен NodeJS.

Если это делать лень, можно просто открыть в браузере index.html из папки соответствующего примера.

Angular 1.5

Компоненты

В версии 1.5 Angular приобрел синтаксический сахар в виде метода component у модуля, который позволяет объявлять компоненты. Компоненты — это на самом деле директивы, но код их объявления ориентирован на создание кирпичиков предметной области приложения, тогда как директивы больше ориентированы (идеологически, технически все идентично) на низкоуровневую и императивную работу с DOM. Это нововведение простое, но прикольное, и позволяет объявлять компоненты способом, схожим с Angular 2. Никаких новых фич этот способ не привносит, но может кардинально повлиять на структуру приложения, особенно, если раньше вы пользовались

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

В примере я тоже использую эту возможность, поэтому, если вы еще не знакомы с ней, почитать можно здесь.

Два способа

Первый способ императивный, и подходит больше для ad-hoc показа модальных окон, например, для вывода сообщений или запроса у пользователя каких-то параметров. Также этот способ можно применять, если тип компонента неизвестен, или разметка динамическая.

Все довольно просто.

$compile принимает три аргумента, нас интересует только первый. Первый аргумент — это строка, содержащая HTML шаблон, который будет потом преобразован в работающий фрагмент Angular приложения. В шаблоне можно использовать любые зарегистрированные компоненты из вашего модуля и его зависимостей, а также любые валидные конструкции Angular — директивы, интерполяцию строк и т.п.

Обратите внимание на несколько вещей.

Во-первых, шаблон содержит компонент

Вот как выглядит PopupService.open :

Способ 2: Директива с transclude

Здесь искомая директива —

transclude

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

Можно создавать сколько угодно клонов, переопределять им scope, добавлять в любое место документа, и так далее. Здорово.

Неплохо, всего 36 строк.

Angular 2

Новая версия Angular, отличающаяся от первого настолько, что, фактически, это новый продукт.
Мои впечатления от него двоякие.

С другой стороны, не оставляет ощущение монструозности. 5 min quickstart выглядит издевательством. Множество дополнительных библиотек, многие из которых обязательны к использованию (как rxjs ). То, что я успеваю увидеть надпись Loading. при открытии документа с файловой системы, вселяет сомнения в его скорости. Размер бандла в 4.3MB против 1.3MB у Angular 1 и 700KB React (правда, это без оптимизаций, дефолтный бандлинг webpack-а). (Напоминаю, что webpack собирает (бандлит) весь код приложения и его зависимостей (из npm) в один большой javascript файл).

Минифицированный размер: Angular 1 — 156KB, Angular 2 — около 630KB, в зависимости от варианта, React — 150KB.

Angular 2 на момент написания еще RC. Код практически готов, багов вроде бы нет, основые вещи сделаны (ну кроме разве что переделки форм). Однако документация неполная, многие вещи приходится искать в комментариях к github issue
(как, например, динамическая загрузка компонентов, что, собственно, и подтолкнуло меня к написанию этой статьи).

Disclaimer

Динамическая загрузка

К чести Angular 2, код динамической загрузки вызывает трудности только при поиске. Для динамической загрузки используется класс ComponentResolver в сочетании с ViewContainerRef.

Поэтому, наш механизм для показа поп-апов будет составным.

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

Хост-компонент

Я приведу класс целиком, он не очень большой, и потом пройдусь по тонким местам:

Честно говоря, я это нагуглил, и как по мне, это вообще неинтуитивно. Это одна из особенностей второго Angular-а, которая мне очень сильно бросилась в глаза, — в документации очень сложно, или же вообще невозможно, найти решения для типовых задач низкоуровневой разработки директив. Документация для создания именно бизнес-компонентов нормальная, да и ничего там особо сложного нет. Однако для сценариев написания контролов, низкоуровневых компонентов, невозможно найти документации. Динамическое создание компонентов, взаимодействие с шаблоном из класса — эти области просто не документированы. Даже в описании @ViewChild ничего не сказано о втором параметре.

Что ж, надеюсь, к релизу задокументируют.

Посмотрим теперь, как этим пользоваться:

OverlayService указан в providers Root компонента, в нашем компоненте его регистрировать не нужно.

Потом начинается страшная императивщина: устанавливаем свойства компонента, подписываемся на события, все это руками. Ни о какой декларативности или реактивности речи не идет. Особенно весело, если нужно обеспечить двухстороннее связывание. Несколько вариантов с бесконечными циклами и флагами isRunning вам обеспечены.

Вывод

Честно говоря, это выглядит ужасно. Я искренне надеюсь, что я искал недостаточно хорошо, и где-то есть красивый способ, позволяющий разместить компонент в произвольном месте DOM дерева, и нормально связать свойства динамически созданного компонента с родителем.

Отсутствие способа помещать компоненты в произвольное место DOM это не очень хорошо, и может вносить ограничения, особенно если страница это несколько микро-приложений. Однако отсутствие динамического связывания компонентов это, на мой взгляд, гораздо более серьезная проблема.

ReactJS

Все просто и понятно. Видно, что такой сценарий создателями Реакта продумывался.

Ладно, теперь посмотрим, как это использовать. Привожу, для краткости, только метод render :

Ifc это костылик, который рендерит содержимое, только если condition истинно. Это позволяет избавиться от монструозных IIFE, если нужно отрендерить кусок компонента по условию.

В остальном все просто: если компонент

Как видим, очень похоже на второй способ с Angular 1.5, с директивой.

Итоги

Недостатки приведенного способа — не будет работать в серверном рендеринге.

Заключение

Подходы, изначально заложенные в Реакте — однонаправленные потоки данных, компоненты, четкий input/output контракт компонента — нашли свое отражение и в Angular: by design в Angular 2, и в обновлениях Angular 1.5. Это изменение без сомнения пошло на пользу первому Angular.

Что касается показа всплывающих элементов — это пример костылей, которые возникли из-за несовершенства CSS, но повлияли на всю экосистему веб-разработки. Это яркий пример текущей абстракции, а также баланса между «чистой архитектурой» и «реальной жизнью» веб разработки. Как видим, разработчики Angular 2 либо не задумывались об этом сценарии, либо реализовали его, но никому не сказали. В то же время, первый Angular и React достаточно гибкие (а разработчики Реакта видимо еще и продуманные), чтобы можно было реализовать рендеринг элемента в отличное от его расположения в дереве компонентов.

Источник

Build a full-featured Modal dialog Form with React

How to create a form in a modal that pops on click.

1*VECLk THNznrBWtRROUv8Q

In this tutorial, you’ll create a form in a modal with React.

The Modal pops up on a button click. A form is a separate component from the Modal and can be modified without affecting the modal itself. Modal freezes the background and prevents a user from scrolling.

There’s a close button to exit the modal. But it can also be closed by clicking outside the Form area or pressing the Escape key. The end result of the tutorial will meet these criteria.

The form is probably the most important part of any site. You can use it to get leads, login or have people contact you. Popup forms are where you get the most number of leads, so they’re very useful.

Let’s create a classic pop up form, one that appears on click of a button. Yes, everything will be done using React. You’ll discover the important factors to consider in a popup as you follow.

Here’s what it looks like when done.

1*o 43mPNfvZA6HJmwZaapBg

Tip: Use tools like Bit to make components reusable. Your team can share your components, install them in their projects, suggest updates and build faster.

1*IurWjNcql WEh2G9WzLTRA

Refer to the source code as you follow along:

The Parent App component

An app is the default container for everything.

I also passed onSubmit function for the form submit action from App component.

Since it doesn’t have states to keep track of, I’ll make it a stateless component. Stateless component is a JavaScript-like function. It returns JSX instead of a JavaScript data type.

The submit method just logs the name and email from the form in the console. You can send them to your autoresponder, store in a database or whatever you wish.

Filler Text

Filler component returns a generic lorem ipsum text. Just for the sake on content we need on the page. It is also a stateless component.

The Container. But why?

What’s the need for the container? We shall just have the Modal, right? Wrong!

Also, the modal should close on clicking outside the Modal area. How do we detect that? Using container and the Modal.

You can’t escape the Container.

And Container holds two components:

TriggerButton is the button surrounded by Filler text that launches the Modal, and Modal is, well, the Modal.

The Container needs a state to change the visibility of the Modal. It’ll be a stateful component.

Delcare the isShown state.

Conditional Render

We need the Modal when isShown is true, otherwise we only need the trigger button from the Container. In the above code, I used a ternary operator :? to check if isShown state is true. We return null if is shown is false.

Time for Modal

Here are the features of a generic modal:

Focus: We need to get focus to close button upon opening the Modal and to the trigger button on closing it. We need to reference Modal and Button. Use refs to refer anything in react. They can also be passed to children and components in children can be referred.

1*ayCfqerat9wamsS4Gvawvw

Here’s the Container with all methods.

TriggerButton gets a reference, we’ll use that is a while. It receives triggerText to display and showModal to run on click.

Since we need a lot of methods, lets declare them in Container component.

showModal sets isShown to true. The setState can take a callback function, we can use that to focus on closeButton (in the modal) as model becomes visible and toggle the scroll lock.

closeButton is the buttonRef passed in the Modal component.

Select html and hide the overflow to block scrolling, that overflow:hidden is in the index.css file.

closeModal sets isShown to false and Modal no longer renders in the DOM. It also gives focus to the trigger button and toggles scroll lock. We removed the hidden overflow by toggling scroll lock.

onKeyDown and onClickOutside

onKeyDown closes the Modal of the if the pressed key is Escape.

onClickOutside checks if the modal contains the current click target and returns in that case. This means click is within the modal. Otherwise, closeModal is called.

Container component

Trigger Button

FocusTrap

We need the focus trapped within the fields in the Modal, for this we can wrap the JSX within FocusTrap and focus will remain locked within.

npm install focus-trap-react

import from focus-trap-react

React Portal to inject any component anywhere in DOM

React portals is latest API in to the ReactDOM. It allows to go outside the application into the DOM and place anything.

That’s a form with onSubmit action defined on App.js.

Conclusion

You can fork the code, download, make changes, practice, or whatever. The full code is available here. Please feel free to comment and ask anything or share the components you made (with Bit or GitHub). Thanks for reading!

Источник

React выплывающее окно

Есть две компоненты родительская и дочерняя (header). Как сделать так чтоб при клике на элемент в хедере окошко всплывало, на на клик в любой области за этим окошком окно скрывалось

QNDvQ

2 ответа 2

Это называется модальное окно (modal window) Чтобы не изобретать велосипед, необходимо воспользоваться библиотеками, к примеру: 1) компонент Modal из semantic-ui-react 2) react-modal

photo

1) Если клик на элемент в компоненте «А», должен влиять на компонент «Б», то вам нужен глобальный стор. Например: Redux.

Алгоритм простой: по клику меняем значение переменной в сторе, а в компоненте2 вешаем\снимаем класс в зависимости от значения этой переменной, или вообще рендерим\не рендерим блок.

2) Для того, чтобы обработать событие клика «вне» элемента, можно воспользоваться HOC.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками javascript reactjs или задайте свой вопрос.

Похожие

Подписаться на ленту

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

дизайн сайта / логотип © 2021 Stack Exchange Inc; материалы пользователей предоставляются на условиях лицензии cc by-sa. rev 2021.11.11.40719

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Источник

Building a modal module for React with React-Router

October 21, 2019 8 min read 2405

react router modals no cdn

Modals are very useful for displaying one view on top of another.

However, they are more than an absolutely positioned

In this article, we’ll discuss the various aspects of modals and identify solutions to satisfy the requirements that come with creating dynamic URLs, page refreshes, and other features.

Before starting to shape the modal component, let’s start with some basics of the react-router package.

We’ll use four components from this package: BrowserRouter, Route, Link, and Switch.

Since this is not a react-router tutorial, I won’t be explaining what each of these components do.

However, if you’d like some info about react-router, you can check out this page.

Basic routing

First, go ahead and install react-router-dom through npm.

At the very top level of your application, use the
component to wrap your app.

Functionality-wise, you can use either one.

Below is the basic structure of the navigation menu, which changes the URL accordingly:

The next thing we’ll do is implement the mechanism that matches the URL and renders a specific component.

renders the first matching location specified by its children. When nothing is matched, the last is returned — usually as a 404 page.

Creating a modal component

So far, we’ve implemented the basic routing structure. Now we can create a modal component and work on displaying it as an overlay.

Although there are a variety of different methods for creating modal components, we’ll only be covering one.

A modal component has a wrapper element which spans the whole screen — width and height.

This area also acts as a clickedOutside detector. Then the actual modal element is positioned relative to that wrapper element.

Modal router element nocdn

Opening the modal view

The modal component we created should render on top of the existing view when a specific URL is matched, meaning that somehow we have to change the URL so the routing mechanism can decide what to render.

We know that renders the first matching location, but a modal overlay needs two components rendering at the same time.

This can be achieved by putting the modal out of and rendering it conditionally.

In this case, we should be able to detect if a modal is active or not.

The usage shown below lets us define a state variable, which is then made available in the location prop, which we can access within any component using withRouter HOC.

In this case, you’re not expected to define each intended to match the individual modal locations. In order to handle all of them under the /modal route, use the following syntax:

This gives you the flexibility of getting the value of the hardcoded :id parameter within the modal component through the match.params prop.

It also lets you do dynamic content renderings, depending on which modal is open.

Matching the modal location

This section is particularly important because it identifies the mechanism for displaying a modal on top of an existing view even though the location parameter changes when a modal is opened.

So we have to define the following somewhere.

We want to display the component as an overlay.

However, putting it inside would match it and only render the component. As a result, there would be no overlay.

To resolve this problem, we need to define it both inside and outside of with extra conditions.

Below, you’ll see the modified version of the same snippet. There are several changes. Let’s list them quickly:

There is an isModal variable defined, which depends on some other values.

is using a location prop.

When a modal is opened, we need to store the previous location object and pass this to instead of letting it use the current location object by default.

This basically tricks into thinking it’s still on the previous location — for example / — even though the location changes to /modal/1 after the modal is opened.

The following snippet replaces the previousLocation with the current location object when there is no open modal.

As a result, we can pass it to to make it think we’re still on the same location, even though we changed the location by opening a modal.

However, these two checks alone do not suffice in the case of refreshing the page.

While the modal has to be closed on its own, location.state && location.state.modal still holds.

Given that component has the necessary stylings, this results in two different views rendering on top of each other.

Rendering different modal views

So far we have implemented our modal in a way that ensures we don’t render an overlay when refreshing a page with an open modal, or when directly visiting a modal route.

In this case, the styling you want to apply is likely to be different, or you might want to show a different content.

This is pretty easy to achieve by passing the isModal variable as a prop on the component, as shown below.

Then, depending on the value of the prop, you can apply different stylings or return a completely different markup.

Preventing the scroll underneath the modal

When you open the modal on some browsers it may have the content below scrolling underneath the modal, which is not a desirable interaction.

Using overflow: hidden on body is the first attempt to block scrolling on the entire page.

There are several different npm packages attempting to remedy this scroll locking issue virtually across all platforms.

I found the body-scroll-lock package quite useful.

From this package, you can import disableBodyScroll and enableBodyScroll functions, which accept a reference to the element for which you want scrolling to persist as an input.

When the modal is open we want to disable scrolling for the entire page, except for the modal itself.

Therefore, we need to call disableBodyScroll and enableBodyScroll functions when the modal component is mounted and unmounted, respectively.

To get a reference to the parent

The code snippet below disables scrolling when the modal is open and enables it again when the modal component is about to be unmounted.

Using this.modalRef as the input for these imported functions prevents the content of the modal component from being scroll-locked.

Before using the disableBodyScroll function, we need a simple check.

This is because a modal component might get mounted if the page is refreshed when a modal is open, or when the modal route is visited directly.

In both cases, scrolling should not be disabled.

We have already passed the isModal variable as a prop to the component to render different views, so we can just use this prop to check if there is actually a modal.

Below is the modified version of the modal component:

Conclusion

You now have an understanding of how a modal view works, as well as a sense of some of the problems you may encounter while implementing your own integration.

For the fully functional example, visit this code sandbox project.

Full visibility into production React apps

LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — start monitoring for free.

Источник

Понравилась статья? Поделить с друзьями:
Добавить комментарий
  • Как сделать успешный бизнес на ритуальных услугах
  • Выездной кейтеринг в России
  • Риски бизнеса: без чего не обойтись на пути к успеху
  • react клиент серверное приложение
  • react для мобильных приложений