hw.js 12 KB

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