hw.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. 'use strict';
  2. function Password(parent, open, onChange, onOpenChange) {
  3. const signInForm = document.createElement('form');
  4. signInForm.classList.add('signInForm');
  5. const loginInput = document.createElement('input');
  6. loginInput.classList.add('loginInput');
  7. loginInput.setAttribute('type', 'text');
  8. loginInput.setAttribute('placeholder', 'Write down yor login');
  9. const handelLoginAndPassword = function () {
  10. this.setValue({
  11. login: loginInput.value,
  12. password: passwordInput.value,
  13. confirmPassword: confirmPasswordInput.value,
  14. });
  15. const { login, password, confirmPassword } = this.getValue();
  16. this.onChange({ login, password, confirmPassword });
  17. if (login && password && password === confirmPassword) {
  18. btnSubmit.classList.replace('btnSubmit__disable', 'btnSubmit');
  19. } else if (
  20. login &&
  21. password &&
  22. confirmPasswordInput.classList.contains('hiddenInput')
  23. ) {
  24. btnSubmit.classList.replace('btnSubmit__disable', 'btnSubmit');
  25. } else {
  26. btnSubmit.classList.replace('btnSubmit', 'btnSubmit__disable');
  27. }
  28. };
  29. loginInput.addEventListener('input', handelLoginAndPassword.bind(this));
  30. const passwordInput = document.createElement('input');
  31. passwordInput.classList.add('passwordInput');
  32. passwordInput.setAttribute('placeholder', 'Write down yor password *');
  33. passwordInput.setAttribute('type', open ? 'password' : 'text');
  34. passwordInput.addEventListener('input', handelLoginAndPassword.bind(this));
  35. const confirmPasswordInput = document.createElement('input');
  36. confirmPasswordInput.classList.add('confirmPasswordInput');
  37. !open && confirmPasswordInput.classList.add('hiddenInput');
  38. confirmPasswordInput.setAttribute('placeholder', 'Confirm password');
  39. confirmPasswordInput.setAttribute('type', 'password');
  40. confirmPasswordInput.addEventListener(
  41. 'input',
  42. handelLoginAndPassword.bind(this)
  43. );
  44. const labelCheckBox = document.createElement('label');
  45. labelCheckBox.classList.add('labelCheckBox');
  46. labelCheckBox.textContent = 'Hide password';
  47. const checkBox = document.createElement('input');
  48. checkBox.textContent = 'Show password';
  49. checkBox.classList.add('checkBox');
  50. checkBox.setAttribute('type', 'checkbox');
  51. const handelTogglePassword = function () {
  52. this.setOpen(!this.getOpen());
  53. this.onChange(this.getOpen());
  54. if (passwordInput.type === 'password') {
  55. return confirmPasswordInput.classList.remove('hiddenInput');
  56. }
  57. confirmPasswordInput.value = '';
  58. confirmPasswordInput.classList.add('hiddenInput');
  59. };
  60. checkBox.addEventListener('click', handelTogglePassword.bind(this));
  61. labelCheckBox.append(checkBox);
  62. const btnSubmit = document.createElement('button');
  63. btnSubmit.textContent = 'Submit';
  64. btnSubmit.classList.add('btnSubmit__disable');
  65. btnSubmit.setAttribute('type', 'button');
  66. const handelSubmit = function () {
  67. btnSubmit.classList.replace('btnSubmit', 'btnSubmit__disable');
  68. loginInput.value = '';
  69. passwordInput.value = '';
  70. confirmPasswordInput.value = '';
  71. };
  72. btnSubmit.addEventListener('click', handelSubmit.bind(this));
  73. signInForm.append(
  74. loginInput,
  75. passwordInput,
  76. confirmPasswordInput,
  77. labelCheckBox,
  78. btnSubmit
  79. );
  80. this.parent = parent.append(signInForm);
  81. this.open = open;
  82. this.value = { login: '', password: '', confirmPassword: '' };
  83. this.onChange = onChange;
  84. this.onOpenChange = onOpenChange;
  85. this.setValue = function (value) {
  86. this.value = { ...this.value, ...value };
  87. };
  88. this.getValue = function () {
  89. return this.value;
  90. };
  91. this.setOpen = function (flag) {
  92. passwordInput.setAttribute('type', flag ? 'password' : 'text');
  93. this.open = flag;
  94. };
  95. this.getOpen = function () {
  96. return this.open;
  97. };
  98. }
  99. //Password // LoginForm // Password Verify // are done in code above!!!
  100. const passwordFistInstance = new Password(
  101. document.body,
  102. true,
  103. () => {},
  104. () => {}
  105. );
  106. passwordFistInstance.onChange = (value) => console.log(value, 'onChange');
  107. passwordFistInstance.onOpenChange = (open) => console.log(open, 'onOpenChange');
  108. passwordFistInstance.setValue({ login: 'qwerty' });
  109. passwordFistInstance.setValue({ password: 'qwerty1231' });
  110. console.log(passwordFistInstance.getValue());
  111. passwordFistInstance.setOpen(true);
  112. console.log(passwordFistInstance.getOpen());
  113. // class Password {
  114. // constructor(parent, open) {
  115. // this.parent = parent;
  116. // this.open = open;
  117. // this.value;
  118. // }
  119. // setValue(value) {
  120. // this.value = value;
  121. // }
  122. // get getValue() {
  123. // return this.value;
  124. // }
  125. // setOpen(flag) {
  126. // this.open = flag;
  127. // }
  128. // get getOpen() {
  129. // return this.open;
  130. // }
  131. // onChange(cb) {
  132. // cb(this.value);
  133. // }
  134. // tonOpenChange(cb) {
  135. // cb(this.open);
  136. // }
  137. // }
  138. // const passwordInClass = new Password(document.body, true);
  139. // passwordInClass.setValue('Hello Black Belt');
  140. // console.log(passwordInClass.getValue);
  141. // LoginForm Constructor // are done in code above!!! just for understanding how works classes
  142. //Form
  143. function Form(el, data, okCallback, cancelCallback) {
  144. this.okCallback = okCallback;
  145. this.cancelCallback = cancelCallback;
  146. this.defaultData;
  147. this.data = data;
  148. if (!this.defaultData) this.defaultData = { ...this.data };
  149. this.validators = {
  150. validate(adjust, value, key, input, placeholder, err) {
  151. const title = placeholder.children[0];
  152. const span = placeholder.children[2];
  153. if (!input.required) {
  154. title.classList.add('title');
  155. input.setAttribute('required', '');
  156. }
  157. if (adjust(value)) {
  158. span.classList.remove('warningSpan--hidden');
  159. span.textContent = err;
  160. placeholder.classList.add('placeholderWrong');
  161. placeholder.classList.remove('placeholderRight');
  162. input.classList.add('wrongField');
  163. input.classList.remove('rightInput');
  164. data[key] = value;
  165. return false;
  166. } else {
  167. span.classList.add('warningSpan--hidden');
  168. placeholder.classList.add('placeholderRight');
  169. placeholder.classList.remove('placeholderWrong');
  170. input.classList.add('rightInput');
  171. input.classList.remove('wrongField');
  172. data[key] = value;
  173. return true;
  174. }
  175. },
  176. married(value, key, input, placeholder) {
  177. return this.validate(
  178. (isTrue) => (isTrue === true || isTrue === false ? true : false),
  179. value,
  180. key,
  181. input,
  182. placeholder,
  183. 'Married has to checked!'
  184. );
  185. },
  186. birthday(value, key, input, placeholder) {
  187. return this.validate(
  188. () => (value.length === 16 ? false : true),
  189. value,
  190. key,
  191. input,
  192. placeholder,
  193. 'Birthday is required!'
  194. );
  195. },
  196. password(value, key, input, placeholder) {
  197. return this.validate(
  198. () => (value.length >= 8 ? false : true),
  199. value,
  200. key,
  201. input,
  202. placeholder,
  203. 'Password length min 8!'
  204. );
  205. },
  206. confirmPassword(value, key, input, placeholder) {
  207. return this.validate(
  208. () => (value === data['password'] ? false : true),
  209. value,
  210. key,
  211. input,
  212. placeholder,
  213. 'Password have to be the same *PASSWORD field'
  214. );
  215. },
  216. };
  217. const inputCreators = {
  218. placeholder(key, value, handelInput, type, event, validators) {
  219. const placeholder = document.createElement('placeholder');
  220. placeholder.classList.add('placeholderForm');
  221. const input = document.createElement('input');
  222. const title = document.createElement('span');
  223. title.textContent = key;
  224. if (validators[key]) {
  225. title.classList.add('title');
  226. input.setAttribute('required', '');
  227. }
  228. input.classList.add('formInput');
  229. input.type = type;
  230. input.name = key;
  231. if (type === 'checkbox') {
  232. input['checked'] = value;
  233. } else if (type === 'datetime-local') {
  234. value = new Date(value).toISOString().slice(0, -8);
  235. }
  236. input.value = value;
  237. input.addEventListener(event, handelInput.bind(this));
  238. const warningSpan = document.createElement('span');
  239. warningSpan.classList.add('warningSpan', 'warningSpan--hidden');
  240. placeholder.append(title, input, warningSpan);
  241. return placeholder;
  242. },
  243. string(key, value, handelInput, validators) {
  244. const dataTime = new Date(value);
  245. if (dataTime.getDate())
  246. return inputCreators.object(key, value, handelInput, validators);
  247. if (value === '*') {
  248. return inputCreators.placeholder(
  249. key,
  250. '',
  251. handelInput,
  252. 'password',
  253. 'input',
  254. validators
  255. );
  256. } else {
  257. return inputCreators.placeholder(
  258. key,
  259. value,
  260. handelInput,
  261. 'text',
  262. 'input',
  263. validators
  264. );
  265. }
  266. },
  267. boolean(key, value, handelInput, validators) {
  268. return inputCreators.placeholder(
  269. key,
  270. value,
  271. handelInput,
  272. 'checkbox',
  273. 'input',
  274. validators
  275. );
  276. },
  277. object(key, value, handelInput, validators) {
  278. return inputCreators.placeholder(
  279. key,
  280. value,
  281. handelInput,
  282. 'datetime-local',
  283. 'input',
  284. validators
  285. );
  286. },
  287. };
  288. const form = document.createElement('form');
  289. form.classList.add('formWrapper');
  290. let isChecked = [];
  291. Object.entries(this.data).forEach(([key, value], i) => {
  292. const handelInput = function () {
  293. const input = placeholder.children[1];
  294. if (this.validators[key]) {
  295. isChecked[i] = this.validators[key](
  296. input.value,
  297. key,
  298. input,
  299. placeholder
  300. );
  301. } else {
  302. data[key] = input.value;
  303. }
  304. };
  305. const placeholder = inputCreators[typeof value](
  306. key,
  307. value,
  308. handelInput.bind(this),
  309. this.validators
  310. );
  311. form.append(placeholder);
  312. });
  313. const btnWrapper = document.createElement('div');
  314. btnWrapper.classList.add('btnWrapper');
  315. const okButton = document.createElement('button');
  316. okButton.classList.add('okButton');
  317. okButton.innerHTML = 'OK';
  318. const cancelButton = document.createElement('button');
  319. cancelButton.classList.add('cancelButton');
  320. cancelButton.innerHTML = 'Cancel';
  321. btnWrapper.append(okButton, cancelButton);
  322. el.append(form, btnWrapper);
  323. okButton.onclick = () => {
  324. const isCheckedLength = Object.keys(this.data).reduce((acc, key, i) => {
  325. if (this.validators[key]) return acc + 1;
  326. return acc;
  327. }, 0);
  328. if (isChecked.includes(false) || isCheckedLength !== isChecked.length) {
  329. console.log('Not filed some inputs or do not passed validation');
  330. } else {
  331. this.okCallback(this.data);
  332. }
  333. };
  334. cancelButton.onclick = () => {
  335. isChecked = Object.keys(this.data).map(() => false);
  336. data = { ...this.defaultData };
  337. this.data = { ...data };
  338. for (let i = 0; i < form.children.length; i++) {
  339. const placeholder = form.children[i];
  340. placeholder.classList.remove('placeholderWrong');
  341. placeholder.classList.remove('placeholderRight');
  342. const [, input, warn] = placeholder.children;
  343. warn.classList.add('warningSpan--hidden');
  344. input.classList.remove('wrongField');
  345. input.classList.remove('rightInput');
  346. if (this.data[input.name] === '*') {
  347. input.value = '';
  348. } else if (input.type === 'datetime-local') {
  349. input.value = new Date(this.data[input.name])
  350. .toISOString()
  351. .slice(0, -8);
  352. } else {
  353. input.value = this.data[input.name];
  354. }
  355. }
  356. this.cancelCallback(this.data);
  357. };
  358. }
  359. const cachedFetchStarWars = async () => {
  360. const lc = await localStorage.getItem('data');
  361. if (lc) return JSON.parse(lc);
  362. const data = await fetch('https://swapi.py4e.com/api/people/1/')
  363. .then((res) => res.json())
  364. .then((data) => {
  365. const newData = {};
  366. for (const key in data) {
  367. if (typeof data[key] === 'string') newData[key] = data[key];
  368. }
  369. return newData;
  370. })
  371. .catch((e) => console.log(e));
  372. return data;
  373. };
  374. const data = await cachedFetchStarWars();
  375. const formOne = new Form(
  376. document.body,
  377. {
  378. name: 'Anakin',
  379. surname: 'Skywalker',
  380. married: true,
  381. birthday: new Date(new Date().getTime() - 86400000 * 30 * 365),
  382. password: '*',
  383. confirmPassword: '*',
  384. },
  385. (data) => console.log(data, 'ok , it is updated object after fielding form'),
  386. (data) =>
  387. console.log(
  388. data,
  389. 'ok , it is base object and form is reset for base settings'
  390. )
  391. );
  392. formOne.okCallback = function (data) {
  393. localStorage.setItem('data', JSON.stringify(data));
  394. };
  395. formOne.cancelCallback = function (data) {
  396. localStorage.setItem('data', JSON.stringify(data));
  397. };
  398. formOne.validators.name = function (value, key, input, placeholder) {
  399. return this.validate(
  400. (isTrue) => isTrue.length < 6,
  401. value,
  402. key,
  403. input,
  404. placeholder,
  405. 'Name has to be at least 6 characters!'
  406. );
  407. };
  408. formOne.validators.surname = function (value, key, input, placeholder) {
  409. return this.validate(
  410. (isTrue) => isTrue.length < 8,
  411. value,
  412. key,
  413. input,
  414. placeholder,
  415. 'Name has to be at least 8 characters!'
  416. );
  417. };
  418. const formTwo = new Form(
  419. document.body,
  420. {
  421. ...data,
  422. },
  423. (data) => console.log(data, 'ok , it is updated object after fielding form'),
  424. (data) =>
  425. console.log(
  426. data,
  427. 'ok , it is base object and form is reset for base settings'
  428. ),
  429. 'formTwo'
  430. );
  431. formTwo.okCallback = function (data) {
  432. localStorage.setItem('data', JSON.stringify(data));
  433. };
  434. formTwo.cancelCallback = function (data) {
  435. localStorage.setItem('data', JSON.stringify(data));
  436. };
  437. formTwo.validators.name = function (value, key, input, placeholder) {
  438. return this.validate(
  439. (isTrue) => isTrue.length < 8,
  440. value,
  441. key,
  442. input,
  443. placeholder,
  444. 'Name has to be at least 8 characters!'
  445. );
  446. };
  447. formTwo.validators.height = function (value, key, input, placeholder) {
  448. return this.validate(
  449. (isTrue) => isTrue.length < 10,
  450. value,
  451. key,
  452. input,
  453. placeholder,
  454. 'Name has to be at least 10 characters!'
  455. );
  456. };
  457. // localStorage.userName
  458. // ? alert(`Your name is ${localStorage.userName}`)
  459. // : (localStorage.userName = prompt('What is your name?'));