Skip to content

Commit e64e9a4

Browse files
committed
add yup validation logic
1 parent e954b54 commit e64e9a4

File tree

7 files changed

+157
-4
lines changed

7 files changed

+157
-4
lines changed

.prettierrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"singleQuote": true,
3+
"arrowParens": "avoid",
4+
"semi": false
5+
}

eslint.config.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,13 @@ export default defineConfig([
1010
plugins: { js },
1111
extends: ['js/recommended'],
1212
},
13-
{ files: ['**/*.{js,mjs,cjs}'], languageOptions: { globals: globals.node } },
13+
{
14+
files: ['**/*.{js,mjs,cjs}'],
15+
languageOptions: {
16+
globals: {
17+
...globals.browser,
18+
...globals.node,
19+
},
20+
},
21+
},
1422
])

package-lock.json

Lines changed: 57 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@hexlet/code",
3-
"version": "0.0.0",
3+
"version": "1.0.0",
44
"private": true,
55
"description": "RSS reader",
66
"homepage": "https://github.com/olgarozmetova/frontend-project-11#readme",
@@ -31,6 +31,8 @@
3131
},
3232
"dependencies": {
3333
"@popperjs/core": "^2.11.8",
34-
"bootstrap": "^5.3.8"
34+
"bootstrap": "^5.3.8",
35+
"on-change": "^6.0.1",
36+
"yup": "^1.7.1"
3537
}
3638
}

src/main.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,46 @@
11
import './style.css'
2+
import { buildSchema } from './validation.js'
3+
import { initView } from './view.js'
4+
5+
const state = {
6+
feeds: [],
7+
form: {
8+
status: 'filling',
9+
error: null,
10+
},
11+
}
12+
13+
const elements = {
14+
form: document.querySelector('.rss-form'),
15+
input: document.querySelector('#url-input'),
16+
feedback: document.querySelector('.feedback'),
17+
}
18+
19+
const watched = initView(state, elements)
20+
21+
elements.form.addEventListener('submit', (e) => {
22+
e.preventDefault()
23+
24+
const formData = new FormData(e.target)
25+
const url = formData.get('url').trim()
26+
27+
const data = { url }
28+
const schema = buildSchema(watched.feeds)
29+
30+
watched.form.status = 'filling'
31+
watched.form.error = null
32+
33+
schema
34+
.validate(data)
35+
.then(({ url }) => {
36+
// successful
37+
watched.feeds.push(url)
38+
watched.form.status = 'success'
39+
watched.form.error = null
40+
})
41+
.catch((err) => {
42+
// errors
43+
watched.form.status = 'invalid'
44+
watched.form.error = err.message
45+
})
46+
})

src/validation.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import * as yup from 'yup'
2+
3+
export const buildSchema = urls =>
4+
yup.object().shape({
5+
url: yup.string().trim().required().url().notOneOf(urls),
6+
})

src/view.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import onChange from 'on-change'
2+
3+
export const initView = (state, elements) => {
4+
const watched = onChange(state, (path, value) => {
5+
const { input, feedback, form } = elements
6+
7+
if (path === 'form.error') {
8+
if (value) {
9+
input.classList.add('is-invalid')
10+
feedback.classList.remove('text-success')
11+
feedback.classList.add('text-danger')
12+
feedback.textContent = 'Ссылка должна быть валидным URL'
13+
}
14+
else {
15+
input.classList.remove('is-invalid')
16+
feedback.textContent = ''
17+
}
18+
}
19+
20+
if (path === 'form.status' && value === 'success') {
21+
feedback.classList.remove('text-danger')
22+
feedback.classList.add('text-success')
23+
feedback.textContent = 'RSS успешно загружен'
24+
25+
form.reset()
26+
input.focus()
27+
}
28+
})
29+
30+
return watched
31+
}

0 commit comments

Comments
 (0)