Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
I
Interstate supplies
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Evgeny Talagaev
Interstate supplies
Commits
fa2dd835
Commit
fa2dd835
authored
Aug 25, 2022
by
Evgeny Talagaev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
some changes, 25.08.2022
parent
9069feaf
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
279 additions
and
95 deletions
+279
-95
config.js
config.js
+1
-0
field-text.scss
src/blocks/field-text/field-text.scss
+7
-4
form-validation.js
src/blocks/form-validation/form-validation.js
+181
-49
modal.js
src/blocks/modal/modal.js
+32
-32
page.scss
src/blocks/page/page.scss
+49
-5
index.pug
src/pages/index.pug
+7
-4
form-mixins.scss
src/scss/mixins/form-mixins.scss
+2
-1
No files found.
config.js
View file @
fa2dd835
...
...
@@ -8,6 +8,7 @@ let config = {
'no-js'
,
],
'alwaysAddBlocks'
:
[
'form-validation'
,
// 'sprite-svg',
// 'sprite-png',
],
...
...
src/blocks/field-text/field-text.scss
View file @
fa2dd835
...
...
@@ -6,7 +6,7 @@
$block-name
:
&
;
// #{$block-name}__element
display
:
block
;
margin-bottom
:
$typo-margin-vertical
;
margin-bottom
:
20px
;
&
__name
{
@include
field-name
;
...
...
@@ -14,6 +14,7 @@
&
__input-wrap
{
display
:
block
;
position
:
relative
;
}
&
__input
{
...
...
@@ -37,12 +38,14 @@
#{
$block-name
}
__name
,
#{
$block-name
}
__input
,
#{
$block-name
}
__help-text
{
color
:
$color-danger
;
}
#{
$block-name
}
__input
{
border-color
:
$color-danger
;
background-color
:
lighten
(
$color-danger
,
35%
);
box-shadow
:
0
0
0
1px
#fff
;
}
#{
$block-name
}
__help-text
{
display
:
block
;
}
}
}
src/blocks/form-validation/form-validation.js
View file @
fa2dd835
...
...
@@ -6,28 +6,138 @@ import ready from 'Utils/documentReady.js';
ready
(
function
(){
// Для всех форм страницы
window
.
validateAllForms
=
function
()
{
const
forms
=
Array
.
from
(
document
.
querySelectorAll
(
'form[data-check-form]'
));
forms
.
forEach
(
function
(
form
){
// Подпишемся на событие отправки
form
.
addEventListener
(
'submit'
,
function
(
e
){
let
valid
=
true
;
// Проверим все текстовые инпуты
const
fieldsText
=
Array
.
from
(
form
.
querySelectorAll
(
'input
[data-check-pattern]'
));
const
fieldsText
=
Array
.
from
(
form
.
querySelectorAll
(
'input[data-check-pattern], textarea
[data-check-pattern]'
));
fieldsText
.
forEach
(
function
(
input
){
if
(
!
checkFieldText
(
input
))
valid
=
false
;
});
// Проверим все чекбоксы
const
fieldsCheckbox
=
Array
.
from
(
form
.
querySelectorAll
(
'input[data-check-state]'
));
fieldsCheckbox
.
forEach
(
function
(
input
){
if
(
!
checkFieldCheckbox
(
input
))
valid
=
false
;
});
let
inputEqual_2
=
form
.
querySelector
(
'input[data-equal_2]'
)
if
(
inputEqual_2
){
let
inputEqual_1
=
form
.
querySelector
(
'input[data-equal_1]'
)
if
(
inputEqual_1
){
valid
=
checkEqual
(
inputEqual_1
,
inputEqual_2
)
inputEqual_2
.
addEventListener
(
'blur'
,
()
=>
{
valid
=
checkEqual
(
inputEqual_1
,
inputEqual_2
)
})
}
}
// Если были ошибки, не отправляем форму
if
(
!
valid
)
e
.
preventDefault
();
});
if
(
!
valid
)
{
e
.
preventDefault
();
}
else
{
// Если есть атрибут data-ajax, отправляем форму ajax
if
(
form
.
hasAttribute
(
'data-ajax'
))
{
e
.
preventDefault
();
let
formAction
=
form
.
getAttribute
(
'action'
),
formMethod
=
(
form
.
getAttribute
(
'method'
)
||
'post'
).
toLowerCase
(),
formErrorMsg
=
form
.
getAttribute
(
'data-error-msg'
)
||
'При отправке формы возникла ошибка, попробуйте перезагрузить страницу и отправить форму ещё раз'
,
formOkMsg
=
form
.
getAttribute
(
'data-ok-msg'
)
||
'Форма успешно отправлена'
,
xhr
=
new
XMLHttpRequest
();
// Формируем запрос xhr
xhr
.
open
(
formMethod
,
formAction
,
true
)
// Проверяем метод формы, отправяем xhr
switch
(
formMethod
)
{
case
'post'
:
// Если post, отправляем данные формы
let
formData
=
new
FormData
(
form
);
xhr
.
send
(
formData
)
break
case
'get'
:
// Если get, получаем даннные
xhr
.
send
()
break
default
:
console
.
error
(
`Ошибка в значении data-method =
${
formMethod
}
`
)
}
// Обработка ответа xhr
xhr
.
onload
=
function
()
{
if
(
xhr
.
status
!=
200
)
{
console
.
error
(
`Ошибка
${
xhr
.
status
}
:
${
xhr
.
statusText
}
`
);
if
(
form
.
hasAttribute
(
'data-form-modal'
))
window
.
closeAllModals
();
showMessage
(
formErrorMsg
,
'error'
);
}
else
{
let
response
=
JSON
.
parse
(
xhr
.
response
)
if
(
response
.
status
==
'error'
){
if
(
form
.
hasAttribute
(
'data-form-modal'
))
window
.
closeAllModals
();
showMessage
(
response
.
msg
,
'error'
);
}
else
{
if
(
form
.
hasAttribute
(
'data-form-modal'
))
window
.
closeAllModals
();
showMessage
(
formOkMsg
,
'ok'
);
}
}
}
// Обработка ошибки xhr
xhr
.
onerror
=
function
()
{
console
.
error
(
"Запрос не удался"
)
if
(
form
.
hasAttribute
(
'data-form-modal'
))
window
.
closeAllModals
();
showMessage
(
formErrorMsg
,
'error'
)
}
// Функция создания сообщения на ответ xhr
function
showMessage
(
textMessage
,
cssClassMessage
){
let
responseWrapper
=
document
.
createElement
(
'div'
),
responseBlock
=
document
.
createElement
(
'div'
),
body
=
document
.
querySelector
(
'body'
);
responseWrapper
.
setAttribute
(
'class'
,
'response-wrapper'
)
responseBlock
.
setAttribute
(
'class'
,
'response-block '
+
cssClassMessage
)
responseBlock
.
textContent
=
textMessage
body
.
insertAdjacentElement
(
'beforeend'
,
responseWrapper
)
body
.
insertAdjacentElement
(
'beforeend'
,
responseBlock
)
body
.
classList
.
add
(
'of-h'
)
responseWrapper
.
classList
.
add
(
'active'
)
responseBlock
.
classList
.
add
(
'active'
)
setTimeout
(
function
(){
body
.
classList
.
remove
(
'of-h'
)
responseWrapper
.
classList
.
remove
(
'active'
)
responseBlock
.
classList
.
remove
(
'active'
)
setTimeout
(
function
(){
responseWrapper
.
remove
()
responseBlock
.
remove
()
},
500
)
},
3500
)
}
}
}
});
// Для всех проверяемых текстовых полей
const
fieldsText
=
Array
.
from
(
document
.
querySelectorAll
(
'input
[data-check-pattern]'
));
const
fieldsText
=
Array
.
from
(
document
.
querySelectorAll
(
'input[data-check-pattern], textarea
[data-check-pattern]'
));
fieldsText
.
forEach
(
function
(
input
){
let
hasBeenAlreadyBlured
=
false
;
input
.
addEventListener
(
'blur'
,
function
(){
...
...
@@ -49,6 +159,7 @@ ready(function(){
const
errorClass
=
'field-text--error'
;
const
parent
=
closest
(
input
,
'.field-text'
);
result
?
parent
.
classList
.
remove
(
errorClass
)
:
parent
.
classList
.
add
(
errorClass
);
return
result
;
}
...
...
@@ -60,4 +171,25 @@ ready(function(){
result
?
parent
.
classList
.
remove
(
errorClass
)
:
parent
.
classList
.
add
(
errorClass
);
return
result
;
}
function
checkEqual
(
input1
,
input2
)
{
let
errorClass
=
'field-text--error'
;
let
parent
=
closest
(
input2
,
'.field-text'
);
if
(
input1
.
value
!=
""
&&
input2
.
value
!=
""
&&
input1
.
value
==
input2
.
value
){
console
.
info
(
'Passwords equal'
)
parent
.
classList
.
remove
(
errorClass
)
return
true
}
else
{
console
.
error
(
'Passwords not equal'
)
parent
.
classList
.
add
(
errorClass
)
return
false
}
}
});
};
window
.
validateAllForms
();
});
src/blocks/modal/modal.js
View file @
fa2dd835
...
...
@@ -7,18 +7,7 @@ ready(function () {
const
bodyPaddingRightOriginal
=
parseInt
(
window
.
getComputedStyle
(
document
.
body
,
null
).
getPropertyValue
(
'padding-right'
));
const
backdrop
=
document
.
createElement
(
'div'
);
document
.
addEventListener
(
'click'
,
function
(
event
)
{
const
target
=
event
.
target
.
closest
(
'a[data-modal], button[data-modal]'
);
if
(
target
&&
target
.
dataset
.
modal
===
'open'
)
{
showModal
(
document
.
getElementById
((
target
.
hash
||
target
.
dataset
.
modalTarget
).
slice
(
1
))
);
}
if
(
target
&&
target
.
dataset
.
modal
===
'close'
||
event
.
target
.
matches
(
'[aria-modal]'
))
{
closeAllModals
();
}
function
showModal
(
targetModalNode
)
{
window
.
showModal
=
function
(
targetModalNode
)
{
if
((
document
.
body
.
clientHeight
-
document
.
documentElement
.
clientHeight
)
>
0
)
{
document
.
body
.
style
.
paddingRight
=
bodyPaddingRightOriginal
+
getScrollSize
()
+
'px'
;
}
...
...
@@ -34,7 +23,7 @@ ready(function () {
document
.
body
.
append
(
backdrop
);
}
function
closeAllModals
()
{
window
.
closeAllModals
=
function
()
{
document
.
body
.
classList
.
remove
(
'modal-open'
);
document
.
body
.
style
.
paddingRight
=
''
;
...
...
@@ -48,6 +37,17 @@ ready(function () {
backdrop
.
remove
();
}
document
.
addEventListener
(
'click'
,
function
(
event
)
{
const
target
=
event
.
target
.
closest
(
'a[data-modal], button[data-modal]'
);
if
(
target
&&
target
.
dataset
.
modal
===
'open'
)
{
window
.
showModal
(
document
.
getElementById
((
target
.
hash
||
target
.
dataset
.
modalTarget
).
slice
(
1
))
);
}
if
(
target
&&
target
.
dataset
.
modal
===
'close'
||
event
.
target
.
matches
(
'[aria-modal]'
))
{
window
.
closeAllModals
();
}
});
});
src/blocks/page/page.scss
View file @
fa2dd835
...
...
@@ -759,7 +759,7 @@ pre {
&
__b-item
{
padding-top
:
40px
;
border-top
:
1px
solid
#efefef
;
counter-increment
:
li
1
;
counter-increment
:
li
;
@media
(
min-width
:
$screen-xl
)
{
padding-top
:
70px
;
...
...
@@ -774,12 +774,11 @@ pre {
margin-top
:
40px
;
@media
(
min-width
:
$screen-xl
)
{
padding
-top
:
70px
;
margin
-top
:
70px
;
}
@media
(
min-width
:
$screen-md
)
{
display
:
flex
;
padding-top
:
50px
;
margin-top
:
50px
;
}
}
}
...
...
@@ -833,6 +832,7 @@ pre {
border
:
1px
solid
$color-1
;
border-radius
:
8px
;
font-size
:
12px
;
white-space
:
nowrap
;
@media
(
min-width
:
$screen-xl
)
{
font-size
:
20px
;
...
...
@@ -843,7 +843,7 @@ pre {
}
&
:
:
before
{
content
:
"0"
counter
(
li
);
content
:
counter
(
li
,
decimal-leading-zero
);
}
}
...
...
@@ -1039,3 +1039,47 @@ pre {
.of-h
{
overflow
:
hidden
;
}
.response-wrapper
,
.response-block
{
position
:
fixed
;
opacity
:
0
;
visibility
:
hidden
;
transition
:
opacity
$transition-time
,
visibility
$transition-time
;
&
.active
{
opacity
:
1
;
visibility
:
visible
;
}
}
.response-wrapper
{
z-index
:
10
;
left
:
0
;
top
:
0
;
width
:
100%
;
height
:
100%
;
background-color
:
rgba
(
0
,
0
,
0
,
0
.6
);
}
.response-block
{
z-index
:
11
;
left
:
50%
;
top
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
padding
:
15px
;
border-right
:
5px
solid
transparent
;
width
:
450px
;
max-width
:
calc
(
100%
-
30px
);
background-color
:
#fff
;
font
:
16px
/
160%
var
(
--
ff
);
color
:
#333
;
&
.error
{
border-color
:
red
;
}
&
.ok
{
border-color
:
limegreen
;
}
}
src/pages/index.pug
View file @
fa2dd835
...
...
@@ -98,29 +98,32 @@ block content
h2.def-title Any questions? <br> Contact us!
.form-block__second
form(action="
", method="post
")
form(action="
test-form.php", method="post", data-check-form, data-ajax, data-ok-msg="Форма успешно отправлена", data-error-msg="При отправке формы возникла ошибка, попробуйте перезагрузить страницу и отправить форму ещё раз
")
+field-text({
helpText: '
Подсказка
',
helpText: '
Only text
',
mods: '',
attrs: {
name: 'name',
placeholder: 'Name',
'data-check-pattern': '^[а-яА-Яa-zA-Z]{3,30}$',
}
})
+field-text({
helpText: '
Подсказка
',
helpText: '
Enter e-mail
',
mods: '',
attrs: {
name: 'email',
placeholder: 'E-mail',
'data-check-pattern': '^[a-zA-Z0-9.!#$%&\'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$',
}
})
+field-text({
helpText: '
Подсказка
',
helpText: '
Enter phone
',
mods: '',
attrs: {
name: 'phone',
placeholder: 'Phone',
'data-check-pattern': '^((8|\\+7|\\+3)[\\- ]?)?(\\(?\\d{3}\\)?[\\- ]?)?[\\d\\- ]{7,15}$',
}
})
+btn('contact us', 'ico')(type="button")
...
...
src/scss/mixins/form-mixins.scss
View file @
fa2dd835
...
...
@@ -48,11 +48,12 @@
}
@mixin
field-help-text
{
position
:
absolute
;
display
:
block
;
padding-top
:
0
.4em
;
font-size
:
$font-size-sm
;
line-height
:
1
.2em
;
color
:
$text-color-muted
;
color
:
#fff
;
&
:empty
{
// stylelint-disable-line
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment