JavaScript можно использовать для создания настраиваемых рабочих процессов PDF на основе электронной почты. Создание электронного письма с прикрепленной формой PDF для дальнейшего рассмотрения и утверждения — простая задача, которую можно выполнить с помощью одной команды. Хотя отправить электронное письмо легко, сделать этот процесс простым и удобным для пользователя требует небольшой работы. В этой статье мы рассмотрим основные шаги, необходимые для добавления этой функции в форму PDF.
Чтобы продемонстрировать это, мы готовим простую форму разрешения на работу (PTW). В сложном проекте создание системы PTW помогает обеспечить прозрачность и подотчетность. В системе PTW перед началом любой работы назначается ответственное лицо, которое подготавливает разрешение в установленном формате и получает одобрение от уполномоченного лица. Эта система особенно полезна, когда несколько подрядчиков работают в одном месте, поскольку потенциальные опасности, связанные с недопониманием, могут быть выявлены до начала работ и могут быть предприняты шаги для снижения этих опасностей.
Минимальная информация, необходимая для формы PTW: описание деятельности, которая должна быть выполнена, время, в течение которого она будет завершена, контрольный список для обеспечения соблюдения минимальных требований безопасности, а также имена и данные ответственного лица. и лицо, санкционирующее деятельность.
Когда в цикле утверждения есть несколько шагов, нам нужен способ, чтобы форма знала, на каком этапе она находится в данный момент, и соответствующим образом модифицировала свое поведение. Для этой цели мы определяем шесть состояний, в которых форма может находиться в любой момент времени. Эти состояния описаны на рисунке ниже.
Для обновления состояния формы используется функция setFormStatus(). Функция принимает целое число, указывающее новое состояние, в качестве аргумента, и в зависимости от этого значения различные поля формы либо активируются, либо деактивируются. Затем новое значение состояния сохраняется в скрытом текстовом поле формы. Таким образом, всякий раз, когда форма закрывается и снова открывается, она инициализируется в правильном состоянии.
//The setFormStatus set the status of the form. The various fields of the form are //enabled or disabled based on the status of the form. function setFormStatus(formStatus){ this.getField('txt_form_status').value = formStatus; if (formStatus == 0){ //Status 0 indicates the form is not approved. enableFields(); this.getField('sig_incharge_1').readonly = false; this.getField('sig_authorize_1').readonly = true; this.getField('sig_incharge_2').readonly = true; this.getField('sig_authorize_2').readonly = true; enableButton('btn_submit_1'); disableButton('btn_approve_1'); disableButton('btn_reject_1'); disableButton('btn_submit_2'); disableButton('btn_approve_2'); disableButton('btn_reject_2'); }else if (formStatus == 1){ //Status 1 indicates that form is sent for approval/rejection. disableFields(); this.getField('sig_incharge_1').readonly = true; this.getField('sig_authorize_1').readonly = false; this.getField('sig_incharge_2').readonly = true; this.getField('sig_authorize_2').readonly = true; disableButton('btn_submit_1'); enableButton('btn_approve_1'); enableButton('btn_reject_1'); disableButton('btn_submit_2'); disableButton('btn_approve_2'); disableButton('btn_reject_2'); }else if (formStatus == 2){ //Status 2 indicates that the form is approved. this.getField('sig_incharge_1').readonly = true; this.getField('sig_authorize_1').readonly = true; this.getField('sig_incharge_2').readonly = false; this.getField('sig_authorize_2').readonly = true; disableButton('btn_submit_1'); disableButton('btn_approve_1'); disableButton('btn_reject_1'); enableButton('btn_submit_2'); disableButton('btn_approve_2'); disableButton('btn_reject_2'); }else if (formStatus ==3){ //Status 3 indicates that the form is sent for closure. this.getField('sig_incharge_1').readonly = true; this.getField('sig_authorize_1').readonly = true; this.getField('sig_incharge_2').readonly = true; this.getField('sig_authorize_2').readonly = false; disableButton('btn_submit_1'); disableButton('btn_approve_1'); disableButton('btn_reject_1'); disableButton('btn_submit_2'); enableButton('btn_approve_2'); enableButton('btn_reject_2'); }else if (formStatus == 4){ //Status 4 indicates that the form is closed. this.getField('sig_incharge_1').readonly = true; this.getField('sig_authorize_1').readonly = true; this.getField('sig_incharge_2').readonly = true; this.getField('sig_authorize_2').readonly = true; disableButton('btn_submit_1'); disableButton('btn_approve_1'); disableButton('btn_reject_1'); disableButton('btn_submit_2'); disableButton('btn_approve_2'); disableButton('btn_reject_2'); } this.getField('txt_form_status').value = formStatus; }
Затем мы создаем функцию getFormData(), которая считывает данные формы и выполняет элементарную проверку. Он возвращает объект, содержащий эту информацию.
//The getFormData function retrieves the data in the form fields and save them in //an object. Basic validation is performed on the values before returning the object. function getFormData(){ var ptw = {}; //Read form data. ptw.number = this.getField('txt_permit_no').value; ptw.project = this.getField('txt_project').value; ptw.description = this.getField('txt_job_description').value; ptw.location = this.getField('txt_location').value; ptw.startDate = this.getField('txt_start_dd').value + '/' + this.getField('txt_start_mm').value + '/' + this.getField('txt_start_yyyy').value; ptw.startTime = this.getField('txt_start_hh').value + ':' + this.getField('txt_start_min').value; ptw.endDate = this.getField('txt_end_dd').value + '/' + this.getField('txt_end_mm').value + '/' + this.getField('txt_end_yyyy').value; ptw.endTime = this.getField('txt_end_hh').value + ':' + this.getField('txt_end_min').value; ptw.inchargeName = this.getField('txt_incharge_name').value; ptw.inchargeEmail = this.getField('txt_incharge_mail').value; ptw.inchargeCompany = this.getField('txt_incharge_company').value; ptw.authName = this.getField('txt_authorize_name').value; ptw.authEmail = this.getField('txt_authorize_mail').value; ptw.authCompany = this.getField('txt_authorize_company').value; ptw.ccList = this.getField('txt_cc_list').value; ptw.inchargeSign1 = (this.getField('sig_incharge_1').signatureValidate() == 4); ptw.authSign1 = (this.getField('sig_authorize_1').signatureValidate() == 4); ptw.inchargeSign2 = (this.getField('sig_incharge_2').signatureValidate() == 4); ptw.authSign2 = (this.getField('sig_authorize_2').signatureValidate() == 4); //Validate the data. if (!ptw.number) throw 'Permit number is a required field.'; if (!ptw.project) throw 'Project is a required field.'; if (!ptw.description) throw 'Job description is a requried field.'; if (!ptw.location) throw 'Location is a required field.'; if (!ptw.inchargeName) throw 'Name of person in charge is a required field.'; if (!ptw.inchargeEmail) throw 'Email of person in charge is a required field.'; if (!ptw.inchargeCompany) throw 'Company of person in charge is a required field.'; if (!ptw.authName) throw 'Name of authorizing person is a required field.'; if (!ptw.authEmail) throw 'Email of authorizing person is a required field.'; if (!ptw.authCompany) throw 'Company name of authorizing person is a required field.'; return ptw; }
Чтобы создать электронное письмо с прикрепленной формой, мы используем метод mailDoc. Этот метод принимает в качестве аргумента объект, содержащий сведения об электронном письме. Некоторые из свойств этого объекта описаны ниже:
1. bUI: логическое значение, определяющее, будет ли электронное письмо появляться на экране или нет. Если установлено значение false, электронное письмо будет отправлено незаметно в фоновом режиме (однако, чтобы это работало, нам потребуются адекватные административные права, в противном случае электронное письмо будет всплывать независимо от значения, которое мы здесь указываем).
2. cTo: Адреса, на которые отправляется электронная почта.
3. cCC: Адреса, которые копируются в почте.
4. cSubject: тема электронного письма.
5.cMsg: тело письма.
//The generateEmail function creates a standardized email from the details provided in the object ptw. function generateEmail(ptw){ var msg = ''; msg = 'Hello ' + ptw.toName + ','; msg = msg + '\n\n' + ptw.message; msg = msg + '\n\n\tPermit No.\t: ' + ptw.number; msg = msg + '\n\tDescription\t: ' + ptw.description; msg = msg + '\n\tLocation\t: ' + ptw.location; msg = msg + '\n\tFrom Time\t: ' + ptw.startDate + ' ' + ptw.startTime; msg = msg + '\n\tTo Time \t: ' + ptw.endDate + ' ' + ptw.endTime; msg = msg + '\n\nPlease open the attached form for the next step in the workflow.' var subject = 'Permit to work # ' + ptw.number; this.mailDoc({ bUI:false, cTo:ptw.toEmail, cCC:ptw.ccList, cSubject:subject, cMsg:msg }); }
Теперь мы готовы настроить рабочий процесс. Мы готовим шесть функций , которые используются для отправки, утверждения или отклонения формы. Все эти функции следуют типичному шаблону. Форма сначала проверяется, а затем после подтверждения состояние формы обновляется и генерируется электронное письмо.
//The submitForApproval function updates the status of the form and sends an email for approval. function submitForApproval(){ //Get data in the form fields and if the validation fails display an error message. var ptw = {}; try{ ptw = getFormData(); }catch (e){ app.alert (e); return 0; } //Check if the form is signed by the preparer before sending. if (this.getField('sig_incharge_1').signatureValidate() != 4){ app.alert ('Please sign the form first.'); return 0; } //Confirm submission of form. app.alert ({ cMsg:'Are you sure you want to submit the form?', nIcon:2, nType:2, cTitle:'Permit to work form' }); //Change form status. setFormStatus(1); //Generate an email with the form attached. ptw.message = 'A new Permit-to-Work form has been submitted for your review and approval.'; ptw.toEmail = ptw.authEmail; ptw.toName = ptw.authName; generateEmail(ptw); this.closeDoc(); } //Set the mouse up of the 'btn_submit_1' button to call the submitForApproval function. this.getField('btn_submit_1').setAction('MouseUp', 'submitForApproval();');
Мы предоставляем возможность сбросить форму в исходное состояние на любом этапе рабочего процесса с помощью кнопки «Сбросить форму».
//The resetPTW function clears all signature and returns the form to the initial state. function resetPTW(){ this.resetForm(['sig_incharge_1']); this.resetForm(['sig_authorize_1']); this.resetForm(['sig_incharge_2']); this.resetForm(['sig_authorize_2']); enableFields(); setFormStatus(0); }
Весь код
//Setting up an Email Based Approval Workflow for PDF Forms //(c) 2023 Roshn Noronha //On opening the form set the form state to what it was before it was last. setFormStatus(this.getField('txt_form_status').value); //The setFormStatus set the status of the form. The various fields of the form are //enabled or disabled based on the status of the form. function setFormStatus(formStatus){ this.getField('txt_form_status').value = formStatus; if (formStatus == 0){ //Status 0 indicates the form is not approved. enableFields(); this.getField('sig_incharge_1').readonly = false; this.getField('sig_authorize_1').readonly = true; this.getField('sig_incharge_2').readonly = true; this.getField('sig_authorize_2').readonly = true; enableButton('btn_submit_1'); disableButton('btn_approve_1'); disableButton('btn_reject_1'); disableButton('btn_submit_2'); disableButton('btn_approve_2'); disableButton('btn_reject_2'); }else if (formStatus == 1){ //Status 1 indicates that form is sent for approval/rejection. disableFields(); this.getField('sig_incharge_1').readonly = true; this.getField('sig_authorize_1').readonly = false; this.getField('sig_incharge_2').readonly = true; this.getField('sig_authorize_2').readonly = true; disableButton('btn_submit_1'); enableButton('btn_approve_1'); enableButton('btn_reject_1'); disableButton('btn_submit_2'); disableButton('btn_approve_2'); disableButton('btn_reject_2'); }else if (formStatus == 2){ //Status 2 indicates that the form is approved. this.getField('sig_incharge_1').readonly = true; this.getField('sig_authorize_1').readonly = true; this.getField('sig_incharge_2').readonly = false; this.getField('sig_authorize_2').readonly = true; disableButton('btn_submit_1'); disableButton('btn_approve_1'); disableButton('btn_reject_1'); enableButton('btn_submit_2'); disableButton('btn_approve_2'); disableButton('btn_reject_2'); }else if (formStatus ==3){ //Status 3 indicates that the form is sent for closure. this.getField('sig_incharge_1').readonly = true; this.getField('sig_authorize_1').readonly = true; this.getField('sig_incharge_2').readonly = true; this.getField('sig_authorize_2').readonly = false; disableButton('btn_submit_1'); disableButton('btn_approve_1'); disableButton('btn_reject_1'); disableButton('btn_submit_2'); enableButton('btn_approve_2'); enableButton('btn_reject_2'); }else if (formStatus == 4){ //Status 4 indicates that the form is closed. this.getField('sig_incharge_1').readonly = true; this.getField('sig_authorize_1').readonly = true; this.getField('sig_incharge_2').readonly = true; this.getField('sig_authorize_2').readonly = true; disableButton('btn_submit_1'); disableButton('btn_approve_1'); disableButton('btn_reject_1'); disableButton('btn_submit_2'); disableButton('btn_approve_2'); disableButton('btn_reject_2'); } this.getField('txt_form_status').value = formStatus; } //The disableFields function is used to make all the form fields readonly. function disableFields(){ this.getField('txt_permit_no').readonly = true; this.getField('txt_project').readonly = true; this.getField('txt_job_description').readonly = true; this.getField('txt_location').readonly = true; this.getField('txt_start_dd').readonly = true; this.getField('txt_start_mm').readonly = true; this.getField('txt_start_yyyy').readonly = true; this.getField('txt_start_hh').readonly = true; this.getField('txt_start_min').readonly = true; this.getField('txt_end_dd').readonly = true; this.getField('txt_end_mm').readonly = true; this.getField('txt_end_yyyy').readonly = true; this.getField('txt_end_hh').readonly = true; this.getField('txt_end_min').readonly = true; this.getField('chk_1').readonly = true; this.getField('chk_2').readonly = true; this.getField('chk_3').readonly = true; this.getField('chk_4').readonly = true; this.getField('txt_incharge_name').readonly = true; this.getField('txt_incharge_mail').readonly = true; this.getField('txt_incharge_company').readonly = true; this.getField('txt_authorize_name').readonly = true; this.getField('txt_authorize_mail').readonly = true; this.getField('txt_authorize_company').readonly = true; } //The enableFields function is used to make all the form fields editable. function enableFields(){ this.getField('txt_permit_no').readonly = false; this.getField('txt_project').readonly = false; this.getField('txt_job_description').readonly = false; this.getField('txt_location').readonly = false; this.getField('txt_start_dd').readonly = false; this.getField('txt_start_mm').readonly = false; this.getField('txt_start_yyyy').readonly = false; this.getField('txt_start_hh').readonly = false; this.getField('txt_start_min').readonly = false; this.getField('txt_end_dd').readonly = false; this.getField('txt_end_mm').readonly = false; this.getField('txt_end_yyyy').readonly = false; this.getField('txt_end_hh').readonly = false; this.getField('txt_end_min').readonly = false; this.getField('chk_1').readonly = false; this.getField('chk_2').readonly = false; this.getField('chk_3').readonly = false; this.getField('chk_4').readonly = false; this.getField('txt_incharge_name').readonly = false; this.getField('txt_incharge_mail').readonly = false; this.getField('txt_incharge_company').readonly = false; this.getField('txt_authorize_name').readonly = false; this.getField('txt_authorize_mail').readonly = false; this.getField('txt_authorize_company').readonly = false; } //The enableButton function makes a button clickable. function enableButton(buttonName){ var f = this.getField(buttonName); f.readonly = false; f.textColor = color.black; } //The disableButton function disables a button. function disableButton(buttonName){ var f = this.getField(buttonName); f.readonly = true; f.textColor = color.gray; } //The getFormData function retrieves the data in the form fields and save them in //an object. Basic validation is performed on the values before returning the object. function getFormData(){ var ptw = {}; //Read form data. ptw.number = this.getField('txt_permit_no').value; ptw.project = this.getField('txt_project').value; ptw.description = this.getField('txt_job_description').value; ptw.location = this.getField('txt_location').value; ptw.startDate = this.getField('txt_start_dd').value + '/' + this.getField('txt_start_mm').value + '/' + this.getField('txt_start_yyyy').value; ptw.startTime = this.getField('txt_start_hh').value + ':' + this.getField('txt_start_min').value; ptw.endDate = this.getField('txt_end_dd').value + '/' + this.getField('txt_end_mm').value + '/' + this.getField('txt_end_yyyy').value; ptw.endTime = this.getField('txt_end_hh').value + ':' + this.getField('txt_end_min').value; ptw.inchargeName = this.getField('txt_incharge_name').value; ptw.inchargeEmail = this.getField('txt_incharge_mail').value; ptw.inchargeCompany = this.getField('txt_incharge_company').value; ptw.authName = this.getField('txt_authorize_name').value; ptw.authEmail = this.getField('txt_authorize_mail').value; ptw.authCompany = this.getField('txt_authorize_company').value; ptw.ccList = this.getField('txt_cc_list').value; ptw.inchargeSign1 = (this.getField('sig_incharge_1').signatureValidate() == 4); ptw.authSign1 = (this.getField('sig_authorize_1').signatureValidate() == 4); ptw.inchargeSign2 = (this.getField('sig_incharge_2').signatureValidate() == 4); ptw.authSign2 = (this.getField('sig_authorize_2').signatureValidate() == 4); //Validate the data. if (!ptw.number) throw 'Permit number is a required field.'; if (!ptw.project) throw 'Project is a required field.'; if (!ptw.description) throw 'Job description is a requried field.'; if (!ptw.location) throw 'Location is a required field.'; if (!ptw.inchargeName) throw 'Name of person in charge is a required field.'; if (!ptw.inchargeEmail) throw 'Email of person in charge is a required field.'; if (!ptw.inchargeCompany) throw 'Company of person in charge is a required field.'; if (!ptw.authName) throw 'Name of authorizing person is a required field.'; if (!ptw.authEmail) throw 'Email of authorizing person is a required field.'; if (!ptw.authCompany) throw 'Company name of authorizing person is a required field.'; return ptw; } //The generateEmail function creates a standardized email from the details provided in the object ptw. function generateEmail(ptw){ var msg = ''; msg = 'Hello ' + ptw.toName + ','; msg = msg + '\n\n' + ptw.message; msg = msg + '\n\n\tPermit No.\t: ' + ptw.number; msg = msg + '\n\tDescription\t: ' + ptw.description; msg = msg + '\n\tLocation\t: ' + ptw.location; msg = msg + '\n\tFrom Time\t: ' + ptw.startDate + ' ' + ptw.startTime; msg = msg + '\n\tTo Time \t: ' + ptw.endDate + ' ' + ptw.endTime; msg = msg + '\n\nPlease open the attached form for the next step in the workflow.' var subject = 'Permit to work # ' + ptw.number; this.mailDoc({ bUI:false, cTo:ptw.toEmail, cCC:ptw.ccList, cSubject:subject, cMsg:msg }); } //The submitForApproval function updates the status of the form and sends an email for approval. function submitForApproval(){ //Get data in the form fields and if the validation fails display an error message. var ptw = {}; try{ ptw = getFormData(); }catch (e){ app.alert (e); return 0; } //Check if the form is signed by the preparer before sending. if (this.getField('sig_incharge_1').signatureValidate() != 4){ app.alert ('Please sign the form first.'); return 0; } //Confirm submission of form. app.alert ({ cMsg:'Are you sure you want to submit the form?', nIcon:2, nType:2, cTitle:'Permit to work form' }); //Change form status. setFormStatus(1); //Generate an email with the form attached. ptw.message = 'A new Permit-to-Work form has been submitted for your review and approval.'; ptw.toEmail = ptw.authEmail; ptw.toName = ptw.authName; generateEmail(ptw); this.closeDoc(); } //Set the mouse up of the 'btn_submit_1' button to call the submitForApproval function. this.getField('btn_submit_1').setAction('MouseUp', 'submitForApproval();'); //The approve function updates the status of the form to approved and returns an approval email. function approve(){ //Get data in the form fields and if the validation fails display an error message. var ptw = {}; try{ ptw = getFormData(); }catch (e){ app.alert (e); return 0; } //Check if the form is signed by the approver before sending. if (this.getField('sig_authorize_1').signatureValidate() != 4){ app.alert ('Please sign the form first.'); return 0; } //Confirm approval of form. app.alert ({ cMsg:'By clicking yes you agree that you have read and approve the contents of the form. Are you sure you want to proceed?', nIcon:2, nType:2, cTitle:'Permit to work form' }); //Change form status. setFormStatus(2); //Generate an email with the form attached. ptw.message = 'The subject Permit-to-Work has been approved.'; ptw.toEmail = ptw.inchargeEmail; ptw.toName = ptw.inchargeName; generateEmail(ptw); this.closeDoc(); } //Set the mouse up of the 'btn_approve_1' button to call the approve function. this.getField('btn_approve_1').setAction('MouseUp', 'approve();'); //the reject function resets the status of the form and sends a rejection email. function reject(){ //Get data in the form fields and if the validation fails display an error message. var ptw = {}; try{ ptw = getFormData(); }catch (e){ app.alert (e); return 0; } //Confirm rejection of form. app.alert ({ cMsg:'Are you sure you want to reject this permit?', nIcon:2, nType:2, cTitle:'Permit to work form' }); //Reset form status setFormStatus(0); //Generate an email with the form attached. ptw.message = 'The subject Permit-to-Work has been rejected.'; ptw.toEmail = ptw.inchargeEmail; ptw.toName = ptw.inchargeName; generateEmail(ptw); this.closeDoc(); } //Set the mouse up of the 'btn_reject_1' button to call the reject function. this.getField('btn_reject_1').setAction('MouseUp', 'reject();'); //The submitForClosure function updates the status of the form and sends an email for closure approval. function submitForClosure(){ //Get data in the form fields and if the validation fails display an error message. var ptw = {}; try{ ptw = getFormData(); }catch (e){ app.alert (e); return 0; } //Check if the form is signed by the preparer before sending. if (this.getField('sig_incharge_2').signatureValidate() != 4){ app.alert ('Please sign the form first.'); return 0; } //Confirm submit of form. app.alert ({ cMsg:'Are you sure you want to submit this permit for closure?', nIcon:2, nType:2, cTitle:'Permit to work form' }); //Change form status. setFormStatus(3); //Generate an email with the form attached. ptw.message = 'The subject Permit-to-Work closure has been requested for your approval.'; ptw.toEmail = ptw.authEmail; ptw.toName = ptw.authName; generateEmail(ptw); this.closeDoc(); } //Set the mouse up of the 'btn_submit_2' button to call the submitForClosure function. this.getField('btn_submit_2').setAction('MouseUp', 'submitForClosure();'); //The approveClosure function updates the status of the form to closed and returns an approval email. function approveClosure(){ //Get data in the form fields and if the validation fails display an error message. var ptw = {}; try{ ptw = getFormData(); }catch (e){ app.alert (e); return 0; } //Check if the form is signed by the approver before sending. if (this.getField('sig_authorize_2').signatureValidate() != 4){ app.alert ('Please sign the form first.'); return 0; } //Confirm approval. app.alert ({ cMsg:'By clicking yes you agree that you have read and approve the contents of the form. Are you sure you want to proceed?', nIcon:2, nType:2, cTitle:'Permit to work form' }); //Change form status. setFormStatus(4); //Generate an email with the form attached. ptw.message = 'The subject Permit-to-Work closure has been approved.'; ptw.toEmail = ptw.inchargeEmail; ptw.toName = ptw.inchargeName; generateEmail(ptw); this.closeDoc(); } //Set the mouse up of the 'btn_approve_2' button to call the approveClosure function. this.getField('btn_approve_2').setAction('MouseUp', 'approveClosure();'); //the rejectClosure function resets the status of the form and sends a rejection email. function rejectClosure(){ //Get data in the form fields and if the validation fails display an error message. var ptw = {}; try{ ptw = getFormData(); }catch (e){ app.alert (e); return 0; } //Confirm rejection. app.alert ({ cMsg:'Are you sure you want to reject this permit closure?', nIcon:2, nType:2, cTitle:'Permit to work form' }); //Change form status. setFormStatus(2); //Generate an email with the form attached. ptw.message = 'The subject Permit-to-Work closure has been rejected.'; ptw.toEmail = ptw.inchargeEmail; ptw.toName = ptw.inchargeName; generateEmail(ptw); this.closeDoc(); } //Set the mouse up of the 'btn_reject_2' button to call the rejectClosure function. this.getField('btn_reject_2').setAction('MouseUp', 'rejectClosure();'); //The resetPTW function clears all signature and returns the form to the initial state. function resetPTW(){ this.resetForm(['sig_incharge_1']); this.resetForm(['sig_authorize_1']); this.resetForm(['sig_incharge_2']); this.resetForm(['sig_authorize_2']); enableFields(); setFormStatus(0); }