hw.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  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(false);
  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. const inputCreators = {
  150. placeholder(key, value, handelInput, type, event) {
  151. const placeholder = document.createElement('placeholder');
  152. placeholder.classList.add('placeholderForm');
  153. const input = document.createElement('input');
  154. const title = document.createElement('span');
  155. title.textContent = key;
  156. if (validators[key]) {
  157. title.classList.add('title');
  158. input.setAttribute('required', '');
  159. }
  160. input.classList.add('formInput');
  161. input.type = type;
  162. input.name = key;
  163. if (type === 'checkbox') {
  164. input['checked'] = value;
  165. } else if (type === 'datetime-local') {
  166. value = new Date(value).toISOString().slice(0, -8);
  167. }
  168. input.value = value;
  169. input.addEventListener(event, handelInput.bind(this));
  170. const warningSpan = document.createElement('span');
  171. warningSpan.classList.add('warningSpan', 'warningSpan--hidden');
  172. placeholder.append(title, input, warningSpan);
  173. return placeholder;
  174. },
  175. string(key, value, handelInput) {
  176. if (value === '*') {
  177. return inputCreators.placeholder(
  178. key,
  179. '',
  180. handelInput,
  181. 'password',
  182. 'input'
  183. );
  184. } else {
  185. return inputCreators.placeholder(
  186. key,
  187. value,
  188. handelInput,
  189. 'text',
  190. 'input'
  191. );
  192. }
  193. },
  194. boolean(key, value, handelInput) {
  195. return inputCreators.placeholder(
  196. key,
  197. value,
  198. handelInput,
  199. 'checkbox',
  200. 'input'
  201. );
  202. },
  203. object(key, value, handelInput) {
  204. return inputCreators.placeholder(
  205. key,
  206. value,
  207. handelInput,
  208. 'datetime-local',
  209. 'input'
  210. );
  211. },
  212. };
  213. const validators = {
  214. validate(adjust, value, key, input, placeholder, err) {
  215. const span = placeholder.children[2];
  216. if (adjust(value)) {
  217. span.classList.remove('warningSpan--hidden');
  218. span.textContent = err;
  219. placeholder.classList.add('placeholderWrong');
  220. placeholder.classList.remove('placeholderRight');
  221. input.classList.add('wrongField');
  222. input.classList.remove('rightInput');
  223. data[key] = value;
  224. return false;
  225. } else {
  226. span.classList.add('warningSpan--hidden');
  227. placeholder.classList.add('placeholderRight');
  228. placeholder.classList.remove('placeholderWrong');
  229. input.classList.add('rightInput');
  230. input.classList.remove('wrongField');
  231. data[key] = value;
  232. return true;
  233. }
  234. },
  235. name(value, key, input, placeholder) {
  236. return validators.validate(
  237. (isTrue) => isTrue.length < 6,
  238. value,
  239. key,
  240. input,
  241. placeholder,
  242. 'Name has to be at least 6 characters!'
  243. );
  244. },
  245. surname(value, key, input, placeholder) {
  246. return validators.validate(
  247. () => false,
  248. value,
  249. key,
  250. input,
  251. placeholder,
  252. 'Name has to be at least 6 characters!'
  253. );
  254. },
  255. married(value, key, input, placeholder) {
  256. return validators.validate(
  257. (isTrue) => (isTrue === true || isTrue === false ? true : false),
  258. value,
  259. key,
  260. input,
  261. placeholder,
  262. 'Married has to checked!'
  263. );
  264. },
  265. birthday(value, key, input, placeholder) {
  266. return validators.validate(
  267. () => (value.length === 16 ? false : true),
  268. value,
  269. key,
  270. input,
  271. placeholder,
  272. 'Birthday is required!'
  273. );
  274. },
  275. password(value, key, input, placeholder) {
  276. return validators.validate(
  277. () => (value.length >= 8 ? false : true),
  278. value,
  279. key,
  280. input,
  281. placeholder,
  282. 'Password length min 8!'
  283. );
  284. },
  285. confirmPassword(value, key, input, placeholder) {
  286. return validators.validate(
  287. () => (value === data['password'] ? false : true),
  288. value,
  289. key,
  290. input,
  291. placeholder,
  292. 'Password have to be the same *PASSWORD field'
  293. );
  294. },
  295. };
  296. const form = document.createElement('form');
  297. form.classList.add('formWrapper');
  298. const isCheckedLength = Object.keys(this.data).reduce((acc, key, i) => {
  299. if (validators[key]) return acc + 1;
  300. return acc;
  301. }, 0);
  302. let isChecked = [];
  303. Object.entries(this.data).forEach(([key, value], i) => {
  304. const handelInput = function () {
  305. const input = placeholder.children[1];
  306. if (validators[key]) {
  307. isChecked[i] = validators[key](input.value, key, input, placeholder);
  308. } else {
  309. data[key] = input.value;
  310. }
  311. };
  312. const placeholder = inputCreators[typeof value](
  313. key,
  314. value,
  315. handelInput.bind(this)
  316. );
  317. form.append(placeholder);
  318. });
  319. const btnWrapper = document.createElement('div');
  320. btnWrapper.classList.add('btnWrapper');
  321. const okButton = document.createElement('button');
  322. okButton.classList.add('okButton');
  323. okButton.innerHTML = 'OK';
  324. const cancelButton = document.createElement('button');
  325. cancelButton.classList.add('cancelButton');
  326. cancelButton.innerHTML = 'Cancel';
  327. btnWrapper.append(okButton, cancelButton);
  328. el.append(form, btnWrapper);
  329. okButton.onclick = () => {
  330. if (isChecked.includes(false) || isCheckedLength !== isChecked.length) {
  331. console.log('Not filed some inputs or do not passed validation');
  332. } else {
  333. localStorage.setItem('data', JSON.stringify(this.data));
  334. okCallback(this.data);
  335. }
  336. };
  337. cancelButton.onclick = () => {
  338. isChecked = Object.keys(this.data).map(() => false);
  339. data = { ...this.defaultData };
  340. this.data = { ...data };
  341. for (let i = 0; i < form.children.length; i++) {
  342. const placeholder = form.children[i];
  343. placeholder.classList.remove('placeholderWrong');
  344. placeholder.classList.remove('placeholderRight');
  345. const [, input, warn] = placeholder.children;
  346. warn.classList.add('warningSpan--hidden');
  347. input.classList.remove('wrongField');
  348. input.classList.remove('rightInput');
  349. if (this.data[input.name] === '*') {
  350. input.value = '';
  351. } else if (input.type === 'datetime-local') {
  352. input.value = new Date(this.data[input.name])
  353. .toISOString()
  354. .slice(0, -8);
  355. } else {
  356. input.value = this.data[input.name];
  357. }
  358. }
  359. cancelCallback(this.data);
  360. };
  361. }
  362. const cachedFetchStarWars = async () => {
  363. const lc = await localStorage.getItem('data');
  364. if (lc) return JSON.parse(lc);
  365. const data = await fetch('https://swapi.dev/api/people/1/')
  366. .then((res) => res.json())
  367. .then((data) => {
  368. const newData = {};
  369. for (const key in data) {
  370. if (typeof data[key] === 'string') newData[key] = data[key];
  371. }
  372. return newData;
  373. })
  374. .catch((e) => console.log(e));
  375. return data;
  376. };
  377. const data = await cachedFetchStarWars();
  378. const formOne = new Form(
  379. document.body,
  380. {
  381. name: 'Anakin',
  382. surname: 'Skywalker',
  383. married: true,
  384. birthday: new Date(new Date().getTime() - 86400000 * 30 * 365),
  385. password: '*',
  386. confirmPassword: '*',
  387. },
  388. (data) => console.log(data, 'ok , it is updated object after fielding form'),
  389. (data) =>
  390. console.log(
  391. data,
  392. 'ok , it is base object and form is reset for base settings'
  393. )
  394. );
  395. const formTwo = new Form(
  396. document.body,
  397. {
  398. ...data,
  399. },
  400. (data) => console.log(data, 'ok , it is updated object after fielding form'),
  401. (data) =>
  402. console.log(
  403. data,
  404. 'ok , it is base object and form is reset for base settings'
  405. ),
  406. 'formTwo'
  407. );
  408. // localStorage.userName
  409. // ? alert(`Your name is ${localStorage.userName}`)
  410. // : (localStorage.userName = prompt('What is your name?'));