script.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // console.log(new Date())
  2. // function dateToDateTimeLocal(data){
  3. // // получить timeStamp
  4. // // offset
  5. // // new Date Математика с этим timestamp
  6. // // toISOString без последней буквы
  7. // // return "2021-12-07"
  8. // let timestamp = data.getTime();
  9. // let offsetInMS = data.getTimezoneOffset() * 60 * 1000;
  10. // let offsetDate = new Date (timestamp - offsetInMS);
  11. // return offsetDate.toISOString().slice(0,-1);
  12. // // return (new Date(data.getTime()- data.getTimezoneOffset()*60000)).toISOString().slice(0, -1)
  13. // }
  14. // console.log(dateToDateTimeLocal(new Date()))
  15. function Form(el, data, okCallback, cancelCallback, url){
  16. let formBody = document.createElement('div')
  17. formBody.classList.add("wrapper");
  18. let okButton = document.createElement('button')
  19. okButton.className = "ok";
  20. okButton.innerHTML = 'OK'
  21. okButton.disabled = true;
  22. let cancelButton = document.createElement('button')
  23. cancelButton.innerHTML = 'Cancel'
  24. let inputCreators = {
  25. String(key, value, oninput){
  26. let stringWrapper = document.createElement("div")
  27. stringWrapper.className = "stringWrapper";
  28. let err = document.createElement("p");
  29. err.className = 'error';
  30. let input = document.createElement('input')
  31. input.type = 'text'
  32. input.placeholder = key[0] === "*" ? key.slice(1) : key;
  33. input.value = value.split("").some((item)=>item !== "*") ? value : "" ;
  34. input.className = value.split("").every((item)=>item === "*") ? "password" : "";
  35. input.oninput = () => oninput(input, input.value)
  36. stringWrapper.appendChild(input);
  37. stringWrapper.appendChild(err)
  38. if (key[0] === "*"){
  39. const mandatory = document.createElement('p');
  40. mandatory.className = "mandatory";
  41. mandatory.innerText = '*';
  42. stringWrapper.prepend(mandatory)
  43. }
  44. return stringWrapper
  45. },
  46. Array(key, value, oninput){
  47. let stringWrapper = document.createElement("div")
  48. stringWrapper.className = "stringWrapper";
  49. let err = document.createElement("p");
  50. err.className = 'error';
  51. let input = document.createElement('input')
  52. input.type = 'text'
  53. input.placeholder = key[0] === "*" ? key.slice(1) : key;
  54. input.value = value;
  55. input.oninput = () => oninput(input, input.value)
  56. stringWrapper.appendChild(input);
  57. stringWrapper.appendChild(err)
  58. return stringWrapper
  59. },
  60. Boolean(key, value, oninput){
  61. let wrap = document.createElement('div');
  62. wrap.className = 'checkBoxWrapper';
  63. let p = document.createElement('p');
  64. p.innerText = key;
  65. let input = document.createElement('input');
  66. input.type = 'checkbox';
  67. input.placeholder = key;
  68. input.checked = value;
  69. input.onchange = () => oninput(input, input.checked);
  70. //label for с input type='checkbox' внутри
  71. wrap.appendChild(p)
  72. wrap.appendChild(input)
  73. return wrap
  74. },
  75. Date(key, value, oninput){
  76. let input = document.createElement('input')
  77. input.type = 'date';
  78. input.placeholder = key;
  79. input.value = value;
  80. input.onchange = () => oninput(input, input.value);
  81. return input
  82. //используйте datetime-local
  83. },
  84. //и др. по вкусу, например textarea для длинных строк
  85. }
  86. for(const [key,value]of Object.entries(data)){
  87. let input = inputCreators[value.constructor.name](key, value, (currentInput, newValue) => {
  88. const isValid = this.validators[key] && this.validators[key](newValue, key, data, currentInput);
  89. if (isValid === undefined){
  90. data[key] = newValue;
  91. }
  92. if (currentInput.type === "checkbox"){
  93. data[key] = newValue;
  94. }
  95. if (key[0] === "*" && newValue.length || isValid=== true){
  96. data[key] = newValue;
  97. markInputAsValid(currentInput)
  98. }
  99. if(isValid && isValid.length > 0 && newValue.length){
  100. markInputAsInValid(currentInput, isValid)
  101. }
  102. if (!newValue.length && key[0] === "*"){
  103. currentInput.nextSibling.innerText = "Necessary field";
  104. currentInput.style.backgroundColor = "pink";
  105. }
  106. if (data['*password'] && (!data['*password'].length || data['*password'].split("").every((item)=>item === "*"))){
  107. }
  108. if((key === "*password" || key === "*repeatePassword") && data["*password"].length && isValid===true){
  109. const passwordsArray = Array.from(document.querySelectorAll('.password'));
  110. passwordsArray.forEach((item)=>{
  111. markInputAsValid(item);
  112. })
  113. } else {
  114. if ((key === "*password" || key === "*repeatePassword") && data["*password"].length && isValid !== true){
  115. const passwordsArray = Array.from(document.querySelectorAll('.password'));
  116. markInputAsValid(passwordsArray[0])
  117. markInputAsInValid(passwordsArray[1], isValid)
  118. }
  119. }
  120. checkAllFormValidation(formBody);
  121. });
  122. formBody.appendChild(input);
  123. }
  124. if (typeof okCallback === 'function'){
  125. formBody.appendChild(okButton);
  126. okButton.onclick = (e) => {
  127. console.log(data);
  128. this.savedData = this.data;
  129. // console.log(this)
  130. url ? localStorage.setItem(url, JSON.stringify(this.savedData)) : localStorage.setItem('defaultForm', this.savedData);
  131. console.log(JSON.parse(localStorage.getItem(url)));
  132. this.okCallback(this.data)
  133. }
  134. }
  135. if (typeof cancelCallback === 'function'){
  136. formBody.appendChild(cancelButton);
  137. cancelButton.onclick = () => {
  138. this.data = {...this.savedData};
  139. Array.from(formBody.querySelectorAll('input')).forEach(input => {
  140. input.value = this.savedData[input.placeholder] ? this.savedData[input.placeholder] : this.savedData[`*${input.placeholder}`];
  141. input.value = input.value.split('').every(char => char === "*") ? "" : input.value;
  142. if(input.type === 'checkbox'){
  143. input.checked = input.value;
  144. }
  145. })
  146. cancelCallback(this.savedData);
  147. okButton.disabled = true;
  148. }
  149. }
  150. el.appendChild(formBody)
  151. this.okCallback = okCallback
  152. this.cancelCallback = cancelCallback
  153. this.data = data
  154. this.validators = {}
  155. this.savedData = {...data}
  156. this.url = url
  157. }
  158. let form = new Form(formContainer, {
  159. '*name': 'Anakin',
  160. surname: 'Skywalker',
  161. '*password': '******',
  162. '*repeatePassword': '******',
  163. married: true,
  164. birthday: new Date((new Date).getTime() - 86400000 * 30*365)
  165. }, (data) => console.log(data),(data) => console.log(data) )
  166. form.validators.surname = validateName;
  167. form.validators['*name'] = validateName;
  168. form.validators['*password'] = validatePassword;
  169. form.validators['*repeatePassword'] = validatePassword;
  170. function validateName(value, key, data, input){
  171. return value.length > 2 &&
  172. value[0].toUpperCase() == value[0] &&
  173. !value.includes(' ') ? true : 'Wrong name';
  174. }
  175. function validatePassword(value, key, data, input){
  176. const passwordsArray = Array.from(document.querySelectorAll('.password'));
  177. return (passwordsArray[0].value === passwordsArray[1].value && passwordsArray[0].value.length > 4 ) ? true : "Password should be similar and 5 or more characters"
  178. }
  179. function markInputAsValid(currentInput){
  180. currentInput.style.backgroundColor = "";
  181. currentInput.nextSibling.innerText = '';
  182. }
  183. function markInputAsInValid(currentInput, isValid){
  184. currentInput.style.backgroundColor = "red";
  185. currentInput.nextSibling.innerText = isValid;
  186. }
  187. function checkAllFormValidation(wrapper){
  188. const errors = Array.from(wrapper.querySelectorAll('.error'));
  189. const okButton = wrapper.querySelector('.ok');
  190. const isFormValidated = errors.every(error => {
  191. return error.innerText === '';
  192. })
  193. const mandatory = Array.from(wrapper.querySelectorAll('.mandatory'));
  194. const isFormFilled = mandatory.every(mandatoryItem => {
  195. return mandatoryItem.nextSibling.value.length;
  196. })
  197. okButton.disabled = !isFormValidated || !isFormFilled;
  198. }
  199. function createFormFromApi(url){
  200. if (localStorage[url]){
  201. new Form(formContainer, JSON.parse(localStorage[url]), (data) => console.log(data),(data) => console.log(data), url)
  202. } else {
  203. fetch(url)
  204. .then(res => res.json())
  205. .then(character => {
  206. new Form(formContainer, character, (data) => console.log(data),(data) => console.log(data), url)
  207. })
  208. }
  209. }
  210. createFormFromApi('https://swapi.dev/api/people/1/');
  211. createFormFromApi('https://swapi.dev/api/people/2/');