# th-inputs

> reusable component developed to have inputs with it's validation

Latest version **3.0.1** (published 2019-11-07) · Frontend Team license · 0 weekly downloads

## Install

```sh
npm install th-inputs
pnpm add th-inputs
yarn add th-inputs
bun add th-inputs
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 3.0.1 |
| Published | 2019-11-07 |
| First published | 2019-11-07 |
| Weekly downloads | 0 |
| License | Frontend Team |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 344.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Thiqah Frontend Team |
| Maintainers | aamahmoud |

## Links

- npm: https://www.npmjs.com/package/th-inputs
- Repository: https://tf.thiqah.sa/tfs/DefaultCollection/Thiqah_ReusableComponents/_git/thiqah_front_validations
- npm.io page: https://npm.io/package/th-inputs

## Recent versions

- 3.0.1 (latest) — 2019-11-07

## README

## Thiqah Inputs validation Components

Thiqah Inputs Validation Component is a web component developed by Thiqah Frontend Development Team

#### Installation
- 1- configure .npmrc create **.npmrc** file inside your project and add thiqah npm registry on thiqah TFS to allow your machine from installing our npm package
```bash
registry=https://tf.thiqah.sa/tfs/DefaultCollection/_packaging/Thiqah.ReusableComponent.FrontEnd/npm/registry/
always-auth=true
```
- 2- install package
to install thiqah inputs validation package run the following command line in your bash or command prompt
```bash
npm install th-inputs
```

#### Usage in regular web project 
static pages, .NET or any none JS framework inside your html file,
- Add vendor and app JS Files at the end of **BODY** tag:

```html
<script type="text/javascript" src="node_modules/th-input/vendors.js"></script>
<script type="text/javascript" src="node_modules/th-input/app.js"></script>
```

- in case you need to add any global style files such as bootstrap, be sure that you are injecting it inside **BODY** tag and allow shady dom

```html
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">

<!-- allow shady dom -->
<script>window.ShadyDOM = { force: true };</script>
```

* inside your HTML, be sure from passing all needed properties 
```html
<th-input 
  validatorType='email' 
  lang="en" 
  type="textarea" 
  class_name="form_control" 
  name="email"
  label="email" 
  id="email" 
  placeholder="email" 
  value="" 
  submitted="0"
  default_error="1">
</th-input>
```

* to integrate with the implemented component, listen to its events and update its data
```javascript
var ThiqahInputs = function ThiqahInputs() {
  this.email = document.querySelector("th-input[id=email]");
  this.events();
};

// add event listeners to listen to component  
ThiqahInputs.prototype.events = function () {
  this.email.addEventListener("validityChangeHandler", this.validityChangeHandler.bind(this));
};

// the call back that will recive component data
ThiqahInputs.prototype.validityChangeHandler = function (event) {
  console.log(event.detail);
  console.log(event.detail.val);
  event.detail.formData ? console.log(event.detail.formData.get(this[event.detail.id].ctrl)) : null;
};

// to pass the submit event to the component to allow validation with submission
ThiqahInputs.prototype.submitHandler = function (event) {
  event.preventDefault();
  this.email.submitted++;
};

// to init ThiqahInputs once page loaded
window.addEventListener("load", function (event) {
  new ThiqahInputs();
});
```

#### Usage in Angular web project 

- First, add vendors.js and app.js files into **angular.json** file.
```typescript
"scripts": [
  "node_modules/th-input/vendors.js",
  "node_modules/th-input/app.js"
]
```

- Now, import **CUSTOM_ELEMENTS_SCHEMA** and **NO_ERRORS_SCHEMA** inside app.nodule.ts and add schemas to @NgModule

```typescript
import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
@NgModule({
  imports: [
    BrowserModule,
  ],
  declarations: [],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [
    CUSTOM_ELEMENTS_SCHEMA,
    NO_ERRORS_SCHEMA
  ]
})
```

- inside component.ts add 

```typescript
import { Component, ElementRef, NgZone } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  @ViewChild("email", { static: false }) email: ElementRef;
  public data;
  
  constructor(
    private _ngZone: NgZone
    ) { }
    
  inputDetector() {
    const email = this.email.nativeElement;
    email.addEventListener('validityChangeHandler', (event) => {
      this._ngZone.run(() => {
        console.log(event['detail']);
        ele.value = event['detail'].val;
      });
    });
   }
   
   ngAfterViewInit() {
    this.inputDetector();
   }
 }
```

- inside component.ts add: 

```html
<th-input 
  validatorType='email' 
  lang="en" 
  type="textarea" 
  class_name="form_control" 
  name="email"
  label="email" 
  id="email" 
  placeholder="email" 
  value="" 
  submitted="0"
  default_error="1">
</th-input>
```

-- Now, You can import bootstrap or any other CSS libraries into your angular application.

#### Avialable Inputs
1) Email
2) Full name
3) Resident id
4) Saudi id
5) Saudi mobile number
6) Saudi phone number
7) Saudi postal code
8) Upload image
9) Address
10) Age
11) International Mailbox
12) Mailbox
13) Name 
14) Notes
15) Description

#### Properties

| Property Name | Description | value |
| ------------- |:-------------: | -----: |
| lang | input language | ar/en |
| validatortype | preconfigured validation roles | description/notes/saphone/email/samobile/sapostalcode/address/full_name/mailbox/itMailbox/fax/name/age/resident_id/saudi_id |
| id | input ID attribute | string |
| label | text ro be rendered in the input label | string |
| placeholder | placeholder ro be rendered inside the input |string |
| name | input name attribute | string |
| class_name | input class attribute | string |
| value | input value attribute | string or empty |
| submitted | count of form submit | number |
| defaulterror | use default error of bootstrap or not | number 0/1 |
| type | input type | text/number/textarea |
| validatortype | custom validation (just in case no validatortype needed) | {"empty":{"value":"","errors":{"ar":"","en":""}},"minLength":{"value":2,"errors":{"ar":"","en":""}},"maxLength":{"value":10,"errors":{"ar":"","en":""}},"min":{"value":500,"errors":{"ar":"","en":""}},"max":{"value":1000,"errors":{"ar":"","en":""}},"regex":[{"pattern":"regex","errors":{"ar":"","en":""}}]} |

#### Denied Records Component
Denied Records Component has it's own validator signature

```html
<th-denied-records 
  validator='{"keywords":["ali", "it", "lorem"], "maxLength":1000, "required": true}' 
  lang="en" 
  class_name="form_control" 
  value="" 
  name="denied-records" 
  id="denied-records" 
  placeholder="denied records" 
  label="denied records" 
  default_error="1">
</th-denied-records>
```

#### Select Menu Component
Select Menu Component has it's own attrs

```html
<th-select 
  dataoptions='{
    "ar": ["متزوج"," مطلق", "ارمل", "أعزب"], 
    "en":["Married", "Single", "Divorced", "Widowed"]}' 
  id="socialStatus" 
  name="socialStatus" 
  value="" 
  class_name="form_control" 
  lang="en">
</th-select>

<th-select 
  dataoptions='{
    "ar": ["ميت", "على قيد الحياة"],
    "en":["alive", "dead"]}' 
  id="alive" 
  name="alive" 
  value="" 
  class_name="form_control" 
  lang="en">
</th-select>
```

Multi Select Menu Component has it's own attrs
```html
<th-multi-select 
  id="select"
  name="select" 
  list='["ahmed", "ali", "lili"]' 
  lang="en"
  validator='{"required": true}' 
  placeholder="select names" 
  default_error="1" 
  label="select names"
></th-multi-select>
```

#### adding custom validations
```html
<th-input 
  validator='{}' 
  lang="en" 
  type="text" 
  class_name="form_control" 
  name="email"
  label="email" 
  id="email" 
  placeholder="email" 
  value="" 
  submitted="0"
  default_error="1">
</th-input>
```
```javascript
var ThiqahInputs = function ThiqahInputs() {
      this.x = document.querySelector("th-input[name=xx]");
      this.init();
      this.events();
  };

  ThiqahInputs.prototype.init = function () {
      this.x.validator = {
          empty: {
              value: "",
              errors: {
                  "ar": "الرجاء إدخال قيمة الاسم الكامل",
                  "en": "please add your full name"
              }
          },
          minLength: {
              value: 8,
              errors: {
                  "ar": "الاسم الكامل يجب الا يقل عن 8 احرف ولا يزيد عن 120 حرف",
                  "en": "full name lengh should't be less than 8 characters and should't be more than 120 characters"
              }
          },
          maxLength: {
              value: 120
          },
          regex: [{
              pattern: /[0-9~!@#$%^&*()-_+=\/:'"<>|]/g,
              errors: {
                  "ar": "الاسم الكامل يجب ان يكون حروف فقط",
                  "en": "full name should contain characters only"
              }
          }]
      };
  };

  // add event listeners to listen to component  
  ThiqahInputs.prototype.events = function () {
      this.x.addEventListener("validityChangeHandler", this.validityChangeHandler.bind(this));
  };

  // the call back that will recive component data
  ThiqahInputs.prototype.validityChangeHandler = function (event) {
      console.log(event.detail);
      console.log(event.detail.val);
      event.detail.formData ? console.log(event.detail.formData.get(this[event.detail.id].ctrl)) :
          null;
  };

  // to pass the submit event to the component to allow validation with submission
  ThiqahInputs.prototype.submitHandler = function (event) {
      event.preventDefault();
  };

  // to init ThiqahInputs once page loaded
  window.addEventListener("load", function (event) {
      new ThiqahInputs();
  });
```

#### Upload Files component
```html
  <th-upload 
    lang="en" 
    class_name="form-control" 
    name="upload" 
    label="upload" 
    upload_text="upload" 
    id="upload"
    default_error="1"
    file_extension='["JPEG", "JPG", "BMP", "GIF", "PNG", "TIFF", "TIF", "PDF", "MP4", "MP3", "ZIP", "RAR", "TGZ", "JSON", "XML", "CSV"]'
    max_size='2000000' 
    isMultiple="1">
  </th-upload>
```

```javascript
  window.addEventListener('load', (e) => {.
    var upload = document.querySelector("th-upload[name=upload]");
    upload.addEventListener('validityChangeHandler', fetchDate);
    function fetchDate(event) {
      console.log(event.detail);
    }
  });
```

#### Upload Files Properties

| Property Name | Description | value |
| ------------- |:-------------: | -----: |
| lang | language | ar/en |
| id | input ID attribute | string |
| label | text ro be rendered in the input label | string |
| name | input name attribute | string |
| class_name | input class attribute | string |
| default_error | use default error of bootstrap or not | 0/1 |
| upload_text | text of upload button | string |
| file_extension | allowed files | an array of extensions (all extensions must be capital letters) |
| max_size | max size for each file | value must be in byets |
| isMultiple | allow uploading single or multiable files | 0/1 |

#### Events
Events can be used to align columns.

| Events Name            | Description                            | return      |
| -------------          |:-------------:                         | -----:      |
| validityChangeHandler  | to listen to input validation changes  | { validity: boolean, error: string, ref: string, id: string, val: string } |

#### js selectors
```javascript
let multiSelect = document.querySelector("th-multi-select");
let email = document.querySelector("th-input[name=email]");
let age = document.querySelector("th-input[name=age]");
let saphone = document.querySelector("th-input[name=saphone]");
let samobile = document.querySelector("th-input[name=samobile]");
let sapostalcode = document.querySelector("th-input[name=sapostalcode]");
let address = document.querySelector("th-input[name=address]");
let denied_records = document.querySelector("th-denied-records");
let full_name = document.querySelector("th-input[name=full_name]");
let mailbox = document.querySelector("th-input[name=mailbox]");
let fax = document.querySelector("th-input[name=fax]");
let itMailbox = document.querySelector("th-input[name=itMailbox]");
let name = document.querySelector("th-input[name=name]");
let description = document.querySelector("th-input[name=description]");
let socialStatus = document.querySelector("th-select[name=socialStatus]");
let alive = document.querySelector("th-select[name=alive]");
let notes = document.querySelector("th-input[name=notes]");
let resident_id = document.querySelector("th-resident-id");
let x = document.querySelector("th-input[name=xx]");
let checkbox = document.querySelector("th-input[type=checkbox]");
let radio = document.querySelector("th-input[type=radio]");
let upload = document.querySelector("th-upload[name=upload]");
let saudi_id = document.querySelector("th-input[name=saudi_id]");
let resident_id = document.querySelector("th-input[name=resident_id]");
```

#### Events
Events can be used to align columns.

| Events Name            | Description                            | return      |
| -------------          |:-------------:                         | -----:      |
| validityChangeHandler  | to listen to input validation changes  | { validity: boolean, error: string, ref: string, id: string, val: string } |

#### Full exmaple
```javascript
var ThiqahInputs = function () {
    this.multiSelect = document.querySelector("th-multi-select");
    this.email = document.querySelector("th-input[name=email]");
    this.age = document.querySelector("th-input[name=age]");
    this.saphone = document.querySelector("th-input[name=saphone]");
    this.samobile = document.querySelector("th-input[name=samobile]");
    this.sapostalcode = document.querySelector("th-input[name=sapostalcode]");
    this.address = document.querySelector("th-input[name=address]");
    this.denied_records = document.querySelector("th-denied-records");
    this.full_name = document.querySelector("th-input[name=full_name]");
    this.mailbox = document.querySelector("th-input[name=mailbox]");
    this.fax = document.querySelector("th-input[name=fax]");
    this.itMailbox = document.querySelector("th-input[name=itMailbox]");
    this.name = document.querySelector("th-input[name=name]");
    this.description = document.querySelector("th-input[name=description]");
    this.socialStatus = document.querySelector("th-select[name=socialStatus]");
    this.alive = document.querySelector("th-select[name=alive]");
    this.notes = document.querySelector("th-input[name=notes]");
    this.resident_id = document.querySelector("th-resident-id");
    this.x = document.querySelector("th-input[name=xx]");
    this.checkbox = document.querySelector("th-input[type=checkbox]");
    this.radio = document.querySelector("th-input[type=radio]");
    this.upload = document.querySelector("th-upload[name=upload]");
    this.saudi_id = document.querySelector("th-input[name=saudi_id]");
    this.resident_id = document.querySelector("th-input[name=resident_id]");
    this.init();
    this.events();
};

ThiqahInputs.prototype.init = function () {
    this.x.validator = {
        required: {
            value: "",
            errors: {
                "ar": "الرجاء إدخال قيمة الاسم الكامل",
                "en": "please add your full name"
            }
        },
        minLength: {
            value: 8,
            errors: {
                "ar": "الاسم الكامل يجب الا يقل عن 8 احرف ولا يزيد عن120 حرف",
                "en": "full name lengh should't be less than 8 characters and should't be more than120 characters"
            }
        },
        maxLength: {
            value: 120
        },
        regex: [{
            pattern: /[0-9~!@#$%^&*()-_+=\/:'"<>|]/g,
            errors: {
                "ar": "الاسم الكامل يجب ان يكون حروف فقط",
                "en": "full name should contain characters only"
            }
        }]
    };
};

// add event listeners to listen to component  
ThiqahInputs.prototype.events = function () {
    this.multiSelect.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.email.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.saphone.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.sapostalcode.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.samobile.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.address.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.denied_records.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.full_name.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.mailbox.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.fax.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.itMailbox.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.name.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.description.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.socialStatus.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.alive.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.notes.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.x.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.upload.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.checkbox.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.radio.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.age.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.resident_id.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    this.saudi_id.addEventListener('validityChangeHandler', this.fetchDate.bind(this));
    document.forms['test'].addEventListener('submit', this.submitHandler.bind(this));
};

// the call back that will recive component data
ThiqahInputs.prototype.fetchDate = function (event) {
    console.log(event.detail);
    console.log(event.detail.val);
};

// to pass the submit event to the component to allow validation with submission
ThiqahInputs.prototype.submitHandler = function (event) {
    event.preventDefault();
    this.email.submit();
    this.saphone.submit();
    this.sapostalcode.submit();
    this.samobile.submit();
    this.address.submit();
    this.full_name.submit();
    this.mailbox.submit();
    this.fax.submit();
    this.itMailbox.submit();
    this.name.submit();
    this.description.submit();            
    this.notes.submit();
    this.x.submit();
    this.age.submit();
    this.checkbox.submit();
    this.radio.submit();
    this.resident_id.submit();
    this.saudi_id.submit();
    this.denied_records.submit();

    // this.upload.submit();
    this.multiSelect.submit();
};

// to init ThiqahInputs once page loaded
window.addEventListener("load", function (event) {
    new ThiqahInputs();
});
```

### Contributing
### License
THIQAH Frontend Team KSA

---
_Source: https://npm.io/package/th-inputs · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
